diff --git a/bots/publisher_bot.py b/bots/publisher_bot.py
index e222334..3daacfa 100644
--- a/bots/publisher_bot.py
+++ b/bots/publisher_bot.py
@@ -206,12 +206,59 @@ def build_json_ld(article: dict, blog_url: str = '') -> str:
return f''
+def fetch_featured_image(article: dict) -> str:
+ """글 키워드 기반 무료 대표 이미지 URL 가져오기 (Pexels → Unsplash fallback)"""
+ # 검색 키워드: 태그 또는 코너 기반
+ tags = article.get('tags', [])
+ if isinstance(tags, str):
+ tags = [t.strip() for t in tags.split(',')]
+ corner = article.get('corner', '')
+ query = tags[0] if tags else corner or 'technology'
+
+ # Pexels API (키가 있을 때)
+ pexels_key = os.getenv('PEXELS_API_KEY', '')
+ if pexels_key:
+ try:
+ resp = requests.get(
+ 'https://api.pexels.com/v1/search',
+ headers={'Authorization': pexels_key},
+ params={'query': query, 'per_page': 1, 'orientation': 'landscape'},
+ timeout=10,
+ )
+ if resp.status_code == 200:
+ photos = resp.json().get('photos', [])
+ if photos:
+ return photos[0]['src']['large']
+ except Exception as e:
+ logger.warning(f"Pexels 이미지 검색 실패: {e}")
+
+ # Unsplash Source (API 키 불필요, 직접 URL)
+ import urllib.parse
+ encoded = urllib.parse.quote(query)
+ return f'https://source.unsplash.com/1200x630/?{encoded}'
+
+
def build_full_html(article: dict, body_html: str, toc_html: str) -> str:
- """최종 HTML 조합: JSON-LD + 목차 + 본문 + 면책 문구"""
+ """최종 HTML 조합: 대표이미지 + JSON-LD + 목차 + 본문 + 면책 문구"""
json_ld = build_json_ld(article)
disclaimer = article.get('disclaimer', '')
- html_parts = [json_ld]
+ # 본문에 이미 태그가 있으면 대표 이미지 삽입 건너뜀
+ has_image = '
'
+ f'
'
+ f''
+ )
+
+ html_parts.append(json_ld)
if toc_html:
html_parts.append(f'