183 lines
6.1 KiB
Markdown
183 lines
6.1 KiB
Markdown
# 뉴스 시스템 통합 계획
|
|
|
|
## 작성일: 2025-09-06
|
|
## 작성자: happybell80
|
|
## 목적: skill-news, rb8001, skill-publish 통합 연동
|
|
|
|
## 1. 현재 구현 상태
|
|
|
|
### 대상 채널
|
|
- **컴퍼니엑스 전체 채널**: C09C98KK2TT
|
|
- **로빙팀 채널**: C09CP4MDX71 (테스트용)
|
|
- **팀 ID**: T09C98KB933
|
|
- **용도**: 컴퍼니엑스 뉴스 선택 후 게시
|
|
|
|
### 구현 완료 (확인됨)
|
|
- **skill-news** (포트 8505): 뉴스 수집, 스크래핑, 요약 API 운영 중
|
|
- **skill-publish** (포트 8511): Squarespace 게시 서비스 준비 완료
|
|
- **APScheduler**: rb8001/main.py:207 평일 09:00 자동 실행
|
|
- **DM 전송**: rb8001/app/skills/dm_skill.py:384 텍스트 메시지 전송
|
|
- **Gemini 요약**: gemini-2.5-flash-lite 모델 사용 중
|
|
- **JSON 상태 관리**: /app/data/news_state.json 파일 기반
|
|
|
|
### 코드 수정 완료 (테스트 대기)
|
|
- **Slack 인터랙티브 버튼**: Block Kit 구현 완료
|
|
- **Button Callback 처리**: /api/slack/interactive 엔드포인트 추가
|
|
- **rb8001↔skill-publish 연동**: HTTP 통신 코드 구현
|
|
- **게시 결과 알림**: response_url 통한 알림 구현
|
|
- **DB 저장**: rb_news 테이블 없음 (Phase 3 대기)
|
|
|
|
## 2. 통합 플로우
|
|
|
|
### 2.1 뉴스 수집 및 채널 전송
|
|
```
|
|
APScheduler → skill-news:8505/api/news/google/companyx-search
|
|
→ rb8001/app/skills/news_posting_skill.py
|
|
→ Slack 채널 전송
|
|
```
|
|
**구현**: companyx_news_collector.py (OR 연산자, 제외 키워드 적용)
|
|
|
|
### 2.2 사용자 인터랙션 (목표)
|
|
```
|
|
사용자 버튼 클릭 → rb8001/slack/interactive
|
|
→ 검증 및 처리
|
|
→ skill-publish 호출
|
|
```
|
|
|
|
### 2.3 게시 프로세스 (목표)
|
|
```
|
|
rb8001 → POST skill-publish:8511/publish
|
|
→ Squarespace 자동 게시
|
|
→ 결과 반환
|
|
→ Slack DM 알림
|
|
```
|
|
|
|
## 3. 필요 구현 사항
|
|
|
|
### 3.0 컴퍼니엑스 전용 검색 (skill-news) ✅
|
|
**파일**: app/services/companyx_news_collector.py (생성됨)
|
|
**엔드포인트**: /api/news/google/companyx-search (news_endpoints.py:64)
|
|
**검색식**: `"컴퍼니 엑스" OR "컴퍼니엑스" -광고 -채용 -구인`
|
|
**환경변수**: COMPANY_X_NEWS_KEYWORDS (기본값 내장)
|
|
|
|
### 3.1 Slack Block Kit 메시지 (rb8001) ✅
|
|
**위치**: app/skills/news_posting_skill.py (생성됨)
|
|
**함수**:
|
|
- `send_news_for_posting()`: 채널에 뉴스 전송
|
|
- `create_news_blocks()`: Block Kit 메시지 생성
|
|
- `process_news_batch()`: APScheduler에서 호출
|
|
```python
|
|
blocks = [
|
|
{
|
|
"type": "section",
|
|
"text": {"type": "mrkdwn", "text": f"*{title}*\n{summary}"},
|
|
"accessory": {
|
|
"type": "button",
|
|
"text": {"type": "plain_text", "text": "게시"},
|
|
"action_id": f"publish_news_{news_id}",
|
|
"value": news_id
|
|
}
|
|
}
|
|
]
|
|
```
|
|
**참고**: naver_startup_news_service.py, dm_skill.py:384 (DM 전송 로직)
|
|
|
|
### 3.2 Interactive Endpoint (rb8001) ✅
|
|
**위치**: main.py:249 (구현됨)
|
|
```python
|
|
@app.post("/api/slack/interactive")
|
|
async def slack_interactive(request: Request):
|
|
return await handle_interactive(request) # slack_handler.py
|
|
```
|
|
**핸들러**: slack_handler.py:274 handle_interactive() 구현됨
|
|
**구현 방식**: 기존 handle() 패턴 따라 payload 파싱, action_id 확인
|
|
**URL 설정**: Slack App에 https://ro-being.com/api/slack/interactive 등록
|
|
|
|
### 3.3 skill-publish 연동 (rb8001) ✅
|
|
**위치**: news_posting_skill.py:186 publish_to_squarespace() 구현됨
|
|
```python
|
|
async def publish_to_squarespace(news_data):
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.post(
|
|
"http://localhost:8511/publish",
|
|
json=news_data
|
|
)
|
|
```
|
|
**호출 위치**: slack_handler.handle_interactive() → publish_to_squarespace()
|
|
**결정**: localhost 사용 (rb8001이 모든 스킬을 localhost로 호출 중)
|
|
|
|
### 3.4 데이터 저장 전략
|
|
**현재**: JSON 파일 (/app/data/news_state.json)
|
|
**향후**: PostgreSQL rb_news 테이블
|
|
**결정**: JSON 유지 (DB 작업 완료 후 마이그레이션)
|
|
|
|
## 4. 환경변수 설정
|
|
|
|
### rb8001 (.env)
|
|
```bash
|
|
COMPANY_X_NEWS_CHANNEL_ID=C09CP4MDX71
|
|
COMPANY_X_NEWS_KEYWORDS=컴퍼니엑스,컴퍼니 엑스,Company X
|
|
COMPANY_X_NEWS_SCHEDULE=0 10 * * 1-5 # cron
|
|
SKILL_PUBLISH_URL=http://localhost:8511
|
|
SKILL_NEWS_URL=http://localhost:8505
|
|
```
|
|
|
|
### skill-publish (.env)
|
|
```bash
|
|
# 이미 설정됨 (포트 8511)
|
|
```
|
|
|
|
## 5. Slack App 설정
|
|
**필요 작업**:
|
|
- Interactivity & Shortcuts 활성화 (HTTP Mode)
|
|
- Request URL 설정: https://ro-being.com/api/slack/interactive
|
|
- OAuth Scopes 확인됨: chat:write, chat:write.public (문서 확인)
|
|
- 확인 필요: im:history 권한
|
|
|
|
## 6. 구현 우선순위
|
|
|
|
### Phase 1 (즉시)
|
|
1. Slack Block Kit 메시지 구현
|
|
2. Interactive endpoint 추가
|
|
3. 테스트 (버튼 클릭 → 로그 확인)
|
|
|
|
### Phase 2 (다음 주)
|
|
1. skill-publish 연동 코드
|
|
2. 게시 결과 Slack 알림
|
|
3. 상태 추적 (JSON 기반)
|
|
|
|
### Phase 3 (DB 준비 후)
|
|
1. rb_news 테이블 생성
|
|
2. JSON → DB 마이그레이션
|
|
3. 이력 조회 API
|
|
|
|
## 7. 테스트 시나리오
|
|
1. 환경변수 설정: COMPANY_X_NEWS_TEST_NOW=true (30초 후 실행)
|
|
2. 버튼 표시 확인
|
|
3. 클릭 이벤트 수신 확인
|
|
4. skill-publish 호출 확인
|
|
5. 게시 완료 확인
|
|
|
|
## 8. 리스크 및 대안
|
|
- **Slack 권한 부족**: App 재설치 필요할 수 있음
|
|
- **통신 실패**: 모든 서비스 localhost 사용으로 해결
|
|
- **DB 지연**: JSON 파일로 충분히 운영 가능
|
|
|
|
## 9. 모니터링
|
|
```bash
|
|
# Interactive 이벤트 확인
|
|
docker logs rb8001 | grep interactive
|
|
|
|
# 게시 요청 확인
|
|
docker logs skill-publish | grep publish
|
|
|
|
# Slack 전송 확인
|
|
docker logs rb8001 | grep postMessage
|
|
```
|
|
|
|
## 10. 완료 기준
|
|
- [x] 코드 구현: 모든 Phase 1, 2 기능 구현 완료
|
|
- [ ] 테스트: 실제 작동 확인 필요
|
|
- [ ] Slack App 설정: Interactive URL 등록 필요
|
|
- [ ] 환경변수 설정: .env 파일 업데이트 필요
|
|
- [ ] 배포: Docker 재시작 후 검증 필요 |