# X 봇 동적 관리 기능 구현 계획 ## 개요 현재 `config/bots.js`에 하드코딩된 X 봇 설정을 DB 기반으로 변경하여, 관리 페이지에서 X 계정을 추가/수정/삭제할 수 있도록 함. ## 현재 구조 ```javascript // config/bots.js { id: 'x-fromis9', type: 'x', username: 'realfromis_9', nitterUrl: process.env.NITTER_URL || 'http://nitter:8080', cron: '*/1 * * * *', enabled: true, } ``` ## 주요 기능 1. X username 입력 → Nitter를 통해 프로필 정보 조회 (displayName, avatarUrl) 2. 동기화 간격 설정 (분 단위) 3. 봇 활성화/비활성화 4. 봇 삭제 --- ## 1. DB 스키마 ### `bot_x` 테이블 생성 ```sql CREATE TABLE IF NOT EXISTS bot_x ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, display_name VARCHAR(100), avatar_url VARCHAR(500), cron_interval INT DEFAULT 1, enabled TINYINT(1) DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_username (username) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` **파일**: `backend/sql/bot_x.sql` ### 시드 데이터 ```sql INSERT INTO bot_x (username, display_name, cron_interval, enabled) VALUES ('realfromis_9', 'fromis_9', 1, 1) ON DUPLICATE KEY UPDATE display_name = VALUES(display_name); ``` **파일**: `backend/sql/bot_x_seed.sql` --- ## 2. 백엔드 API ### 2.1 프로필 조회 API (신규) **POST /api/admin/x-bots/lookup** Nitter를 통해 X 계정 프로필 정보 조회. ```javascript // 요청 { "username": "realfromis_9" } // 응답 { "username": "realfromis_9", "displayName": "fromis_9", "avatarUrl": "https://pbs.twimg.com/profile_images/..." } ``` **구현**: `services/x/scraper.js`의 `fetchTweets` 함수 활용 ### 2.2 봇 CRUD API (신규) **파일**: `backend/src/routes/admin/x-bots.js` | 메서드 | 경로 | 설명 | |--------|------|------| | GET | /api/admin/x-bots | 봇 목록 조회 | | GET | /api/admin/x-bots/:id | 봇 상세 조회 | | POST | /api/admin/x-bots | 봇 추가 | | PUT | /api/admin/x-bots/:id | 봇 수정 | | DELETE | /api/admin/x-bots/:id | 봇 삭제 | ### 2.3 기존 봇 API 수정 **파일**: `backend/src/routes/admin/bots.js` - `GET /api/admin/bots`: DB에서 X 봇 목록도 조회하도록 수정 - X 봇 상세 정보 추가 (db_id, username, display_name, avatar_url 등) --- ## 3. 스케줄러 수정 **파일**: `backend/src/plugins/scheduler.js` ### 변경 사항 1. `getXBotsFromDB()` 함수 추가 2. `getAllBots()`에서 X 봇도 DB에서 로드 3. `config/bots.js`에서 X 봇 제거 ```javascript async function getXBotsFromDB() { const [rows] = await fastify.db.query( 'SELECT * FROM bot_x WHERE enabled = 1' ); return rows.map(row => ({ id: `x-${row.id}`, dbId: row.id, type: 'x', username: row.username, displayName: row.display_name, avatarUrl: row.avatar_url, nitterUrl: process.env.NITTER_URL || 'http://nitter:8080', cron: `*/${row.cron_interval} * * * *`, enabled: row.enabled === 1, })); } async function getAllBots(forceRefresh = false) { if (cachedBots && !forceRefresh) { return cachedBots; } const xBots = await getXBotsFromDB(); const youtubeBots = await getYouTubeBotsFromDB(); cachedBots = [...staticBots, ...xBots, ...youtubeBots]; return cachedBots; } ``` --- ## 4. 프론트엔드 UI ### 4.1 봇 추가/수정 다이얼로그 **파일**: `frontend/src/components/pc/admin/bot/XBotDialog.jsx` **입력 필드**: - X username 입력 → "조회" 버튼 → Nitter에서 프로필 정보 가져와 표시 - 동기화 간격 (분): 드롭다운 (1, 2, 5, 10, 30, 60) ### 4.2 봇 목록 페이지 수정 **파일**: `frontend/src/pages/pc/admin/schedules/ScheduleBots.jsx` - X 섹션에 "봇 추가" 버튼 추가 (`canAdd: true`) - X 봇도 수정/삭제 버튼 표시 ### 4.3 API 클라이언트 **파일**: `frontend/src/api/admin/bots.js` ```javascript export const lookupXProfile = (username) => fetchAuthApi('/admin/x-bots/lookup', { method: 'POST', body: JSON.stringify({ username }) }); export const getXBot = (id) => fetchAuthApi(`/admin/x-bots/${id}`); export const createXBot = (data) => fetchAuthApi('/admin/x-bots', { method: 'POST', body: JSON.stringify(data) }); export const updateXBot = (id, data) => fetchAuthApi(`/admin/x-bots/${id}`, { method: 'PUT', body: JSON.stringify(data) }); export const deleteXBot = (id) => fetchAuthApi(`/admin/x-bots/${id}`, { method: 'DELETE' }); ``` --- ## 5. 파일 변경 목록 ### 신규 파일 | 파일 | 설명 | |------|------| | `backend/sql/bot_x.sql` | 테이블 생성 SQL | | `backend/sql/bot_x_seed.sql` | 초기 데이터 SQL | | `backend/src/routes/admin/x-bots.js` | X 봇 CRUD API | | `frontend/src/components/pc/admin/bot/XBotDialog.jsx` | 봇 추가/수정 다이얼로그 | ### 수정 파일 | 파일 | 변경 내용 | |------|-----------| | `backend/src/plugins/scheduler.js` | X 봇 DB 로드 추가 | | `backend/src/routes/admin/bots.js` | X 봇 상세 정보 추가 | | `backend/src/routes/index.js` | x-bots 라우트 등록 | | `backend/src/config/bots.js` | X 봇 제거 (meilisearch만 남김) | | `frontend/src/pages/pc/admin/schedules/ScheduleBots.jsx` | X 섹션 canAdd, 다이얼로그 연결 | | `frontend/src/components/pc/admin/bot/index.js` | XBotDialog export | | `frontend/src/api/admin/bots.js` | X 봇 API 함수 추가 | --- ## 6. 구현 순서 ### 단계 1: DB 스키마 생성 1. `backend/sql/bot_x.sql` 파일 생성 2. `backend/sql/bot_x_seed.sql` 파일 생성 3. DB에 테이블 생성 및 시드 데이터 삽입 ### 단계 2: Nitter 프로필 조회 함수 추가 1. `backend/src/services/x/scraper.js`에 `fetchProfile()` 함수 추가 - Nitter에서 username으로 프로필 정보(displayName, avatarUrl) 조회 ### 단계 3: X 봇 CRUD API 생성 1. `backend/src/routes/admin/x-bots.js` 파일 생성 - POST `/lookup`: 프로필 조회 - GET `/`: 봇 목록 조회 - GET `/:id`: 봇 상세 조회 - POST `/`: 봇 추가 - PUT `/:id`: 봇 수정 - DELETE `/:id`: 봇 삭제 2. `backend/src/routes/index.js`에 x-bots 라우트 등록 ### 단계 4: 스케줄러 수정 1. `backend/src/plugins/scheduler.js`에 `getXBotsFromDB()` 함수 추가 2. `getBots()`에서 X 봇도 DB에서 로드하도록 수정 3. `backend/src/config/bots.js`에서 X 봇 제거 ### 단계 5: 기존 봇 API 수정 1. `backend/src/routes/admin/bots.js` 스키마에 X 봇 필드 추가 - `db_id`, `username`, `display_name`, `avatar_url` 등 ### 단계 6: 프론트엔드 API 클라이언트 1. `frontend/src/api/admin/bots.js`에 X 봇 API 함수 추가 - `lookupXProfile`, `getXBot`, `createXBot`, `updateXBot`, `deleteXBot` ### 단계 7: X 봇 다이얼로그 컴포넌트 생성 1. `frontend/src/components/pc/admin/bot/XBotDialog.jsx` 생성 - username 입력 → "조회" 버튼 → 프로필 정보 표시 - 동기화 간격 선택 - 추가/수정 폼 제출 2. `frontend/src/components/pc/admin/bot/index.js`에 export 추가 ### 단계 8: 봇 목록 페이지 수정 1. `frontend/src/pages/pc/admin/schedules/ScheduleBots.jsx` 수정 - X 섹션에 `canAdd: true` 추가 - XBotDialog 연결 - 수정/삭제 핸들러 연결 --- ## 7. 검증 방법 1. **DB 테이블 확인**: `SELECT * FROM bot_x` 2. **프로필 조회 API**: username 입력 → displayName, avatarUrl 반환 확인 3. **봇 추가**: 새 X 계정 추가 후 목록에 표시, 스케줄러 동작 확인 4. **봇 수정**: 동기화 간격 변경 후 cron 재등록 확인 5. **봇 삭제**: 삭제 후 목록에서 제거, 스케줄러 중지 확인