142 lines
3.6 KiB
JavaScript
142 lines
3.6 KiB
JavaScript
|
|
import fp from 'fastify-plugin';
|
||
|
|
import { fetchRecentVideos, fetchAllVideos } from './api.js';
|
||
|
|
import bots from '../../config/bots.js';
|
||
|
|
|
||
|
|
const YOUTUBE_CATEGORY_ID = 2;
|
||
|
|
|
||
|
|
async function youtubeBotPlugin(fastify, opts) {
|
||
|
|
/**
|
||
|
|
* 멤버 이름 맵 조회
|
||
|
|
*/
|
||
|
|
async function getMemberNameMap() {
|
||
|
|
const [rows] = await fastify.db.query('SELECT id, name FROM members');
|
||
|
|
const map = {};
|
||
|
|
for (const r of rows) {
|
||
|
|
map[r.name] = r.id;
|
||
|
|
}
|
||
|
|
return map;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* description에서 멤버 추출
|
||
|
|
*/
|
||
|
|
function extractMemberIds(description, memberNameMap) {
|
||
|
|
if (!description) return [];
|
||
|
|
const ids = [];
|
||
|
|
for (const [name, id] of Object.entries(memberNameMap)) {
|
||
|
|
if (description.includes(name)) {
|
||
|
|
ids.push(id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return ids;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 영상을 DB에 저장
|
||
|
|
*/
|
||
|
|
async function saveVideo(video, bot) {
|
||
|
|
// 중복 체크 (video_id로)
|
||
|
|
const [existing] = await fastify.db.query(
|
||
|
|
'SELECT id FROM schedule_youtube WHERE video_id = ?',
|
||
|
|
[video.videoId]
|
||
|
|
);
|
||
|
|
if (existing.length > 0) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 커스텀 설정 적용
|
||
|
|
if (bot.titleFilter && !video.title.includes(bot.titleFilter)) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// schedules 테이블에 저장
|
||
|
|
const [result] = await fastify.db.query(
|
||
|
|
'INSERT INTO schedules (category_id, title, date, time) VALUES (?, ?, ?, ?)',
|
||
|
|
[YOUTUBE_CATEGORY_ID, video.title, video.date, video.time]
|
||
|
|
);
|
||
|
|
const scheduleId = result.insertId;
|
||
|
|
|
||
|
|
// schedule_youtube 테이블에 저장
|
||
|
|
await fastify.db.query(
|
||
|
|
'INSERT INTO schedule_youtube (schedule_id, video_id, video_type, channel_id, channel_name) VALUES (?, ?, ?, ?, ?)',
|
||
|
|
[scheduleId, video.videoId, video.videoType, video.channelId, bot.channelName]
|
||
|
|
);
|
||
|
|
|
||
|
|
// 멤버 연결 (커스텀 설정)
|
||
|
|
if (bot.defaultMemberId || bot.extractMembersFromDesc) {
|
||
|
|
const memberIds = [];
|
||
|
|
if (bot.defaultMemberId) {
|
||
|
|
memberIds.push(bot.defaultMemberId);
|
||
|
|
}
|
||
|
|
if (bot.extractMembersFromDesc) {
|
||
|
|
const nameMap = await getMemberNameMap();
|
||
|
|
memberIds.push(...extractMemberIds(video.description, nameMap));
|
||
|
|
}
|
||
|
|
if (memberIds.length > 0) {
|
||
|
|
const uniqueIds = [...new Set(memberIds)];
|
||
|
|
const values = uniqueIds.map(id => [scheduleId, id]);
|
||
|
|
await fastify.db.query(
|
||
|
|
'INSERT INTO schedule_members (schedule_id, member_id) VALUES ?',
|
||
|
|
[values]
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return scheduleId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 최근 영상 동기화 (정기 실행)
|
||
|
|
*/
|
||
|
|
async function syncNewVideos(bot) {
|
||
|
|
const videos = await fetchRecentVideos(bot.channelId, 10);
|
||
|
|
let addedCount = 0;
|
||
|
|
|
||
|
|
for (const video of videos) {
|
||
|
|
const scheduleId = await saveVideo(video, bot);
|
||
|
|
if (scheduleId) {
|
||
|
|
addedCount++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return { addedCount, total: videos.length };
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 전체 영상 동기화 (초기화)
|
||
|
|
*/
|
||
|
|
async function syncAllVideos(bot) {
|
||
|
|
const videos = await fetchAllVideos(bot.channelId);
|
||
|
|
let addedCount = 0;
|
||
|
|
|
||
|
|
for (const video of videos) {
|
||
|
|
const scheduleId = await saveVideo(video, bot);
|
||
|
|
if (scheduleId) {
|
||
|
|
addedCount++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return { addedCount, total: videos.length };
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 관리 중인 채널 ID 목록
|
||
|
|
*/
|
||
|
|
function getManagedChannelIds() {
|
||
|
|
return bots
|
||
|
|
.filter(b => b.type === 'youtube')
|
||
|
|
.map(b => b.channelId);
|
||
|
|
}
|
||
|
|
|
||
|
|
fastify.decorate('youtubeBot', {
|
||
|
|
syncNewVideos,
|
||
|
|
syncAllVideos,
|
||
|
|
getManagedChannelIds,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export default fp(youtubeBotPlugin, {
|
||
|
|
name: 'youtubeBot',
|
||
|
|
dependencies: ['db'],
|
||
|
|
});
|