데브포일 홈
WordPress 자동화
Guest
STAGE 16 · Lv.79

RSS 피드 자동 큐레이션

RSS 피드를 수집하여 콘텐츠를 자동 큐레이션하고, 출처 표기, 자동 요약, 스케줄 발행을 구현합니다.

RSS 기반 콘텐츠 큐레이션의 개념과 가치

큐레이션이 콘텐츠 전략의 핵심인 이유

콘텐츠 큐레이션(Content Curation)은 다양한 소스에서 유용한 콘텐츠를 선별하여 독자에게 부가 가치와 함께 제공하는 전략입니다. 직접 모든 글을 쓸 필요 없이, 업계의 최신 소식을 자동으로 수집하고 AI로 요약하여 블로그에 게시할 수 있습니다. 허브스팟(HubSpot)의 조사에 따르면, 성공적인 콘텐츠 마케터의 60% 이상이 큐레이션을 콘텐츠 전략에 포함하고 있습니다.


RSS(Really Simple Syndication) 피드는 콘텐츠 큐레이션의 핵심 기반 기술입니다. 원하는 블로그, 뉴스 사이트, 업계 매체의 RSS 피드를 구독하면 새 글이 발행될 때마다 자동으로 감지할 수 있습니다. WordPress에는 SimplePie 라이브러리가 내장되어 있어 별도 설치 없이 RSS 피드를 파싱할 수 있습니다.


중요: 큐레이션은 단순 복사가 아닙니다. 원문 링크와 출처를 반드시 표시하고, 자체적인 분석이나 의견을 추가하여 부가 가치를 만들어야 합니다. 저작권을 존중하지 않는 큐레이션은 법적 문제를 초래할 수 있으며, 구글의 중복 콘텐츠 페널티를 받을 수 있습니다.

📡
RSS 수집
자동 소스 감지 및 수집
🤖
AI 요약
핵심 내용 자동 추출
🔍
스팸 필터
저품질 콘텐츠 자동 차단
자동 발행
스케줄 기반 큐레이션 발행
📡
RSS 피드
수집
🔍
중복 제거
스팸 필터
🤖
AI 요약
분류
📝
큐레이션 글
자동 생성
📰
검수 후
발행

RSS 피드 수집 엔진 전체 구현

데이터베이스 테이블 설계

RSS 큐레이션 시스템은 두 개의 커스텀 테이블이 필요합니다. 피드 소스 테이블은 구독 중인 RSS 피드의 URL, 이름, 카테고리, 수집 주기를 저장합니다. 아이템 테이블은 수집된 개별 기사의 제목, 링크, 설명, AI 요약, 상태(대기/승인/거절/사용됨) 등을 저장합니다.

// RSS 큐레이션 시스템 - 테이블 생성 function map_rss_create_tables() { global $wpdb; $charset = $wpdb->get_charset_collate(); // 피드 소스 테이블 $sql1 = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}map_rss_feeds ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(200) NOT NULL, url VARCHAR(500) NOT NULL, category VARCHAR(100) DEFAULT '', max_items INT DEFAULT 10, fetch_interval VARCHAR(20) DEFAULT 'hourly', is_active TINYINT(1) DEFAULT 1, last_fetched DATETIME DEFAULT NULL, last_error TEXT DEFAULT NULL, total_items_fetched INT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_active (is_active), UNIQUE KEY uk_url (url(255)) ) {$charset};"; // 수집 아이템 테이블 $sql2 = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}map_rss_items ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, feed_id BIGINT UNSIGNED NOT NULL, guid VARCHAR(64) NOT NULL, title VARCHAR(500) NOT NULL, link VARCHAR(1000) NOT NULL, description TEXT, ai_summary TEXT DEFAULT NULL, ai_category VARCHAR(100) DEFAULT NULL, ai_relevance_score DECIMAL(5,2) DEFAULT NULL, source_name VARCHAR(200), author VARCHAR(200) DEFAULT '', pub_date DATETIME, category VARCHAR(100) DEFAULT '', status ENUM('pending','approved','rejected','used','spam') DEFAULT 'pending', post_id BIGINT DEFAULT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_guid (guid), INDEX idx_status (status), INDEX idx_feed_id (feed_id), INDEX idx_pub_date (pub_date) ) {$charset};"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($sql1); dbDelta($sql2); } register_activation_hook(__FILE__, 'map_rss_create_tables');
// RSS 피드 수집 및 큐레이션 핵심 클래스 class MAP_RSS_Curator { private $items_table; private $feeds_table; private $spam_filter; public function __construct() { global $wpdb; $this->items_table = $wpdb->prefix . 'map_rss_items'; $this->feeds_table = $wpdb->prefix . 'map_rss_feeds'; $this->spam_filter = new MAP_RSS_Spam_Filter(); // 매시간 RSS 피드 체크 add_action('map_fetch_rss_feeds', [$this, 'fetch_all_feeds']); if (!wp_next_scheduled('map_fetch_rss_feeds')) { wp_schedule_event(time(), 'hourly', 'map_fetch_rss_feeds'); } } // 피드 소스 추가 public function add_feed($name, $url, $category = '', $max_items = 10) { global $wpdb; // URL 유효성 검증 if (!filter_var($url, FILTER_VALIDATE_URL)) { return new WP_Error('invalid_url', '유효하지 않은 URL입니다.'); } // RSS 피드인지 확인 include_once ABSPATH . WPINC . '/feed.php'; $test = fetch_feed($url); if (is_wp_error($test)) { return new WP_Error('invalid_feed', 'RSS 피드를 파싱할 수 없습니다: ' . $test->get_error_message()); } return $wpdb->insert($this->feeds_table, [ 'name' => sanitize_text_field($name), 'url' => esc_url_raw($url), 'category' => sanitize_text_field($category), 'max_items'=> absint($max_items), ]); } // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // 모든 활성 RSS 피드 수집 // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ public function fetch_all_feeds() { global $wpdb; $feeds = $wpdb->get_results( "SELECT * FROM {$this->feeds_table} WHERE is_active = 1" ); $total_new = 0; foreach ($feeds as $feed) { $count = $this->fetch_feed($feed); $total_new += $count; } error_log(sprintf( '[RSS Curator] %d개 피드에서 %d개 새 아이템 수집', count($feeds), $total_new )); return $total_new; } // 개별 피드 수집 private function fetch_feed($feed) { global $wpdb; include_once ABSPATH . WPINC . '/feed.php'; // SimplePie로 RSS 파싱 $rss = fetch_feed($feed->url); if (is_wp_error($rss)) { // 에러 기록 $wpdb->update($this->feeds_table, [ 'last_error' => $rss->get_error_message(), ], ['id' => $feed->id]); error_log("[RSS] 피드 오류 [{$feed->name}]: " . $rss->get_error_message()); return 0; } $items = $rss->get_items(0, $feed->max_items); $new_count = 0; foreach ($items as $item) { $guid = md5($item->get_permalink()); // 중복 체크 $exists = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$this->items_table} WHERE guid = %s", $guid )); if ($exists) continue; // 설명 텍스트 정리 (HTML 제거, 100단어 제한) $description = wp_trim_words( strip_tags($item->get_description()), 100 ); // 스팸 필터 검사 $status = $this->spam_filter->check($item->get_title(), $description) ? 'spam' : 'pending'; // 새 아이템 저장 $wpdb->insert($this->items_table, [ 'feed_id' => $feed->id, 'guid' => $guid, 'title' => sanitize_text_field($item->get_title()), 'link' => esc_url_raw($item->get_permalink()), 'description' => $description, 'author' => sanitize_text_field($item->get_author() ? $item->get_author()->get_name() : ''), 'source_name' => $feed->name, 'pub_date' => $item->get_date('Y-m-d H:i:s') ?: current_time('mysql'), 'category' => $feed->category, 'status' => $status, ]); $new_count++; } // 피드 메타 업데이트 $wpdb->update($this->feeds_table, [ 'last_fetched' => current_time('mysql'), 'last_error' => null, 'total_items_fetched' => $feed->total_items_fetched + $new_count, ], ['id' => $feed->id]); return $new_count; } }
🔒
여기까지는 미리보기입니다
RSS 피드 자동 큐레이션
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)