Files
sam-manage/app/Services/Video/TrendingKeywordService.php
김보곤 0be763b05a feat:트렌딩 키워드 수집 + Veo 3.1 프롬프트 강화 파이프라인
- Google Trends RSS 기반 실시간 급상승 키워드 수집 서비스 추가
- 트렌딩 컨텍스트 활용 후킹 제목 생성 (5패턴: 충격/비교/숫자/질문/반전)
- Veo 3.1 공식 가이드 기반 visual_prompt 5요소 프레임워크 적용
- GET /video/veo3/trending 엔드포인트 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:36:36 +09:00

100 lines
2.9 KiB
PHP

<?php
namespace App\Services\Video;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class TrendingKeywordService
{
private const CACHE_KEY = 'google_trends_kr';
private const CACHE_TTL = 1800; // 30분
private const RSS_URL = 'https://trends.google.co.kr/trending/rss?geo=KR';
/**
* Google Trends RSS에서 한국 실시간 급상승 키워드 수집
*/
public function fetchTrendingKeywords(int $limit = 10): array
{
return Cache::remember(self::CACHE_KEY, self::CACHE_TTL, function () use ($limit) {
try {
$response = Http::timeout(10)
->withHeaders(['Accept' => 'application/xml'])
->get(self::RSS_URL);
if (! $response->successful()) {
Log::warning('TrendingKeywordService: RSS 호출 실패', [
'status' => $response->status(),
]);
return [];
}
$keywords = $this->parseGoogleTrendsRss($response->body());
return array_slice($keywords, 0, $limit);
} catch (\Exception $e) {
Log::error('TrendingKeywordService: 예외 발생', [
'error' => $e->getMessage(),
]);
return [];
}
});
}
/**
* RSS XML 파싱
*/
private function parseGoogleTrendsRss(string $xml): array
{
$keywords = [];
try {
// XML namespace 처리를 위해 ht: 접두사 등록
$doc = new \SimpleXMLElement($xml);
$namespaces = $doc->getNamespaces(true);
$items = $doc->channel->item ?? [];
foreach ($items as $item) {
$keyword = (string) $item->title;
if (empty($keyword)) {
continue;
}
$traffic = '';
$newsTitle = '';
if (isset($namespaces['ht'])) {
$htData = $item->children($namespaces['ht']);
$traffic = (string) ($htData->approx_traffic ?? '');
if (isset($htData->news_item)) {
$newsTitle = (string) ($htData->news_item->news_item_title ?? '');
}
}
$pubDate = (string) ($item->pubDate ?? '');
$keywords[] = [
'keyword' => $keyword,
'traffic' => $traffic,
'news_title' => $newsTitle,
'pub_date' => $pubDate ? date('c', strtotime($pubDate)) : null,
];
}
} catch (\Exception $e) {
Log::error('TrendingKeywordService: XML 파싱 실패', [
'error' => $e->getMessage(),
]);
}
return $keywords;
}
}