# Featured Image 업로드 기능 추가 - 사용된 프롬프트 및 요청사항 ## 작업 개요 2025-11-25에 AI News 자동 포스팅 시스템에 featured image 업로드 기능을 추가한 작업 ## 사용자 요청사항 기록 ### 1. 초기 요청 ``` 작업디렉토리 20251125-upload-featured-image 를 만들고 작업을 시작하자. 이 작업의 내용은 /var/www/tkim.planitai.co.jp/blog/batch/auto-post-ai-news 의 batch에 첫번째 기사의 featured image를 추출하여 wordpress의 기사에 업로드 하는 것이다. ``` **핵심 요구사항:** - 작업 디렉토리 생성 - 첫 번째 기사의 featured image 추출 - WordPress에 이미지 업로드 ### 2. 원본 디렉토리 적용 요청 ``` 원본 디렉토리에 적용해줘 ``` **작업:** - 백업 생성 - 수정된 파일을 원본 디렉토리로 복사 - 패키지 설치 ### 3. 전체 시스템 실행 요청 ``` 전체 시스템을 한 번 실행해줘 ``` **결과:** - 90건 뉴스 수집 성공 - 3개 기사 선정 성공 - 첫 번째 기사에 이미지 없음 확인 - 중복 포스트로 인한 실패 (정상) ### 4. Fallback 로직 추가 요청 ``` 첫 번째 기사에 이미지가 없으면, 두 번째, 세 번째로 차례로 이미지를 획득하도록 수정하자. ``` **핵심 요구사항:** - 첫 번째 기사에 이미지 없으면 두 번째 시도 - 두 번째도 없으면 세 번째 시도 - 순차적 fallback 로직 구현 **구현:** ```javascript for (let i = 0; i < analyzedArticles.length; i++) { if (article.imageUrl) { featuredMediaId = await wpClient.uploadImage(...); if (featuredMediaId) break; } } ``` ### 5. 파일명 형식 변경 요청 ``` 업로드 할 때의 이미지의 이름은 20251125-featured-image.jpg 등과 같은 이름을 사용하도록 하자. ``` **핵심 요구사항:** - 날짜 기반 파일명 사용 - 형식: `YYYYMMDD-featured-image.확장자` **구현:** ```javascript const dateStr = `${year}${month}${day}`; const filename = `${dateStr}-featured-image.${extension}`; // 예: 20251125-featured-image.jpg ``` ### 6. 작업 마무리 요청 ``` 좋아. 내일 아침의 cronjob 결과를 살펴보자. 오늘은 정리하고 끝낼까? 작업디렉토리의 progress.md 와 prompts.md 기록하고 종료하자. ``` ## 기술적 의사결정 ### 1. RSS Feed에서 이미지 추출 방법 **결정**: 다양한 RSS Feed 형식 지원 - enclosure (Media RSS) - media:content, media:thumbnail - itunes:image - HTML content 내의 img 태그 **이유**: RSS Feed마다 이미지 정보 제공 방식이 다르기 때문 ### 2. 이미지 업로드 방식 **결정**: 임시 파일 다운로드 → FormData 업로드 ```javascript 1. axios로 이미지 다운로드 (stream) 2. 임시 파일로 저장 3. FormData로 WordPress REST API에 POST 4. 임시 파일 삭제 ``` **이유**: - WordPress REST API는 multipart/form-data 요구 - Stream 처리로 메모리 효율적 관리 - 임시 파일로 안전한 업로드 보장 ### 3. Fallback 로직 **결정**: 순차적 시도 (1→2→3) ```javascript for (let i = 0; i < analyzedArticles.length; i++) { if (이미지 있음 && 업로드 성공) break; } ``` **이유**: - 첫 번째 기사가 가장 중요하므로 우선 시도 - 실패 시 자동으로 다음 기사 시도 - 모든 기사에 이미지 없어도 투고는 진행 ### 4. 파일명 형식 **결정**: `YYYYMMDD-featured-image.확장자` **이유**: - 날짜별 식별 용이 - 중복 방지 (하루에 하나의 featured image) - WordPress 미디어 라이브러리에서 정렬 용이 ## Claude AI 프롬프트 변경사항 ### 변경 전 (config/prompts.js:201-222) ```javascript **JSON形式で返してください**: { "articles": [ { "title": "...", "coreContent": [...], "whyImportant": [...], "sourceTitle": "...", "sourceUrl": "...", "sourceName": "..." } ] } ``` ### 변경 후 ```javascript **JSON形式で返してください**: { "articles": [ { "title": "...", "coreContent": [...], "whyImportant": [...], "sourceTitle": "...", "sourceUrl": "...", "sourceName": "...", "imageUrl": "元記事の画像URL(元のニュースリストに含まれている場合はそのまま含める、ない場合はnull)" } ] } ``` **변경 이유**: Claude AI가 분석 결과에 이미지 URL을 포함하도록 지시 ## 에러 처리 전략 ### 1. 이미지 다운로드 실패 ``` 제1の記事の画像アップロードに失敗、次の記事を試します ``` → 다음 기사로 fallback ### 2. 이미지 업로드 실패 ``` 第2の記事の画像アップロードに失敗、次の記事を試します ``` → 다음 기사로 fallback ### 3. 모든 기사에 이미지 없음 ``` 全ての記事に画像がないため、アイキャッチ画像なしで投稿します ``` → 이미지 없이 투고 진행 ### 4. 임시 파일 삭제 실패 ``` 一時ファイル削除エラー: ... ``` → 경고만 출력하고 계속 진행 ## 로깅 전략 ### 상세 로깅 추가 ```javascript await logger.info(`第${articleNumber}の記事の画像URL: ${article.imageUrl}`); await logger.info(`アイキャッチ画像アップロード成功: ID ${featuredMediaId} (第${articleNumber}の記事から)`); await logger.warn(`第${articleNumber}の記事の画像アップロードに失敗、次の記事を試します`); ``` **목적**: - 어떤 기사에서 이미지를 가져왔는지 추적 - 문제 발생 시 디버깅 용이 ## 참고 자료 ### WordPress REST API - Media 엔드포인트: `POST /wp/v2/media` - 문서: https://developer.wordpress.org/rest-api/reference/media/ ### 사용된 라이브러리 - `rss-parser`: RSS Feed 파싱 - `axios`: HTTP 클라이언트 - `form-data`: Multipart form data 생성 - `@anthropic-ai/claude-agent-sdk`: Claude AI 통합 ## 다음 실행 시 확인사항 ### Cronjob 로그에서 확인할 내용 1. **이미지 URL 추출 확인** ``` [NewsCollector] TechCrunch: 20件の記事を取得 ``` 2. **Claude AI 분석 결과에 imageUrl 포함 확인** ``` [NewsAnalyzer] 3件のニュースを選定しました ``` 3. **이미지 업로드 시도 확인** ``` 第1の記事の画像URL: https://... [WordPressClient] アップロード用ファイル名: 20251126-featured-image.jpg ``` 4. **업로드 성공 확인** ``` アイキャッチ画像アップロード成功: ID 123 (第1の記事から) ``` 5. **WordPress 투고 확인** ``` [WordPressClient] アイキャッチ画像ID: 123 投稿成功! ``` ## 추가 개선 가능 사항 (향후) 1. **이미지 크기 제한** - 너무 큰 이미지는 리사이즈 - WordPress에 업로드하기 전에 최적화 2. **이미지 포맷 변환** - WebP로 자동 변환하여 용량 절약 3. **이미지 품질 검증** - 너무 작은 이미지는 제외 - 최소 해상도 설정 (예: 800x600) 4. **캐싱** - 같은 날짜에 이미 업로드된 이미지 재사용 5. **재시도 로직** - 네트워크 오류 시 자동 재시도 6. **이미지 출처 기록** - 이미지가 어떤 기사에서 왔는지 메타데이터에 저장