feat(bot): studiofromis_9 채널 봇 추가 및 cron 표현식 지원
- .env에 YouTube API 키 추가 - bots 테이블에 channel_id, rss_url, cron_expression 컬럼 추가 - youtube-scheduler.js: cron_expression 파라미터 지원 - youtube-bot.js: bots 테이블에서 직접 조회, Shorts 필터링 제거 - studiofromis_9 봇 등록 (채널: UCW0ORl7mZO8wIWkgtq-yzjQ, cron: 1,2 * * * *)
This commit is contained in:
parent
1b01182028
commit
e216539f34
3 changed files with 28 additions and 35 deletions
3
.env
3
.env
|
|
@ -19,3 +19,6 @@ RUSTFS_BUCKET=fromis-9
|
|||
|
||||
# Kakao API
|
||||
KAKAO_REST_KEY=cf21156ae6cc8f6e95b3a3150926cdf8
|
||||
|
||||
# YouTube API
|
||||
YOUTUBE_API_KEY=AIzaSyC6l3nFlcHgLc0d1Q9WPyYQjVKTv21ZqFs
|
||||
|
|
|
|||
|
|
@ -241,20 +241,19 @@ export async function createScheduleFromVideo(video, categoryId) {
|
|||
*/
|
||||
export async function syncNewVideos(botId) {
|
||||
try {
|
||||
// 봇 정보 조회
|
||||
const [bots] = await pool.query(
|
||||
`SELECT b.*, c.channel_id, c.rss_url, c.include_shorts
|
||||
FROM bots b
|
||||
JOIN bot_youtube_config c ON b.id = c.bot_id
|
||||
WHERE b.id = ?`,
|
||||
[botId]
|
||||
);
|
||||
// 봇 정보 조회 (bots 테이블에서 직접)
|
||||
const [bots] = await pool.query(`SELECT * FROM bots WHERE id = ?`, [botId]);
|
||||
|
||||
if (bots.length === 0) {
|
||||
throw new Error("봇을 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
const bot = bots[0];
|
||||
|
||||
if (!bot.rss_url) {
|
||||
throw new Error("RSS URL이 설정되지 않았습니다.");
|
||||
}
|
||||
|
||||
const categoryId = await getYoutubeCategory();
|
||||
|
||||
// RSS 피드 파싱
|
||||
|
|
@ -262,10 +261,7 @@ export async function syncNewVideos(botId) {
|
|||
let addedCount = 0;
|
||||
|
||||
for (const video of videos) {
|
||||
// Shorts 필터링
|
||||
if (!bot.include_shorts && video.videoType === "shorts") {
|
||||
continue;
|
||||
}
|
||||
// Shorts도 포함하여 일정으로 추가
|
||||
|
||||
const scheduleId = await createScheduleFromVideo(video, categoryId);
|
||||
if (scheduleId) {
|
||||
|
|
@ -303,20 +299,19 @@ export async function syncNewVideos(botId) {
|
|||
*/
|
||||
export async function syncAllVideos(botId) {
|
||||
try {
|
||||
// 봇 정보 조회
|
||||
const [bots] = await pool.query(
|
||||
`SELECT b.*, c.channel_id, c.include_shorts
|
||||
FROM bots b
|
||||
JOIN bot_youtube_config c ON b.id = c.bot_id
|
||||
WHERE b.id = ?`,
|
||||
[botId]
|
||||
);
|
||||
// 봇 정보 조회 (bots 테이블에서 직접)
|
||||
const [bots] = await pool.query(`SELECT * FROM bots WHERE id = ?`, [botId]);
|
||||
|
||||
if (bots.length === 0) {
|
||||
throw new Error("봇을 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
const bot = bots[0];
|
||||
|
||||
if (!bot.channel_id) {
|
||||
throw new Error("Channel ID가 설정되지 않았습니다.");
|
||||
}
|
||||
|
||||
const categoryId = await getYoutubeCategory();
|
||||
|
||||
// API로 전체 영상 수집
|
||||
|
|
@ -324,10 +319,7 @@ export async function syncAllVideos(botId) {
|
|||
let addedCount = 0;
|
||||
|
||||
for (const video of videos) {
|
||||
// Shorts 필터링
|
||||
if (!bot.include_shorts && video.videoType === "shorts") {
|
||||
continue;
|
||||
}
|
||||
// Shorts도 포함하여 일정으로 추가
|
||||
|
||||
const scheduleId = await createScheduleFromVideo(video, categoryId);
|
||||
if (scheduleId) {
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ const schedulers = new Map();
|
|||
/**
|
||||
* 개별 봇 스케줄 등록
|
||||
*/
|
||||
export function registerBot(botId, intervalMinutes = 2) {
|
||||
export function registerBot(botId, intervalMinutes = 2, cronExpression = null) {
|
||||
// 기존 스케줄이 있으면 제거
|
||||
unregisterBot(botId);
|
||||
|
||||
// cron 표현식 생성 (1분 시작, X분 간격: 1,3,5,7...)
|
||||
const cronExpression = `1-59/${intervalMinutes} * * * *`;
|
||||
// cron 표현식: 지정된 표현식 사용, 없으면 기본값 생성
|
||||
const expression = cronExpression || `1-59/${intervalMinutes} * * * *`;
|
||||
|
||||
const task = cron.schedule(cronExpression, async () => {
|
||||
const task = cron.schedule(expression, async () => {
|
||||
console.log(`[Bot ${botId}] 동기화 시작...`);
|
||||
try {
|
||||
const result = await syncNewVideos(botId);
|
||||
|
|
@ -26,9 +26,7 @@ export function registerBot(botId, intervalMinutes = 2) {
|
|||
});
|
||||
|
||||
schedulers.set(botId, task);
|
||||
console.log(
|
||||
`[Bot ${botId}] 스케줄 등록됨 (${intervalMinutes}분 간격, 1분 오프셋)`
|
||||
);
|
||||
console.log(`[Bot ${botId}] 스케줄 등록됨 (cron: ${expression})`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -48,11 +46,11 @@ export function unregisterBot(botId) {
|
|||
export async function initScheduler() {
|
||||
try {
|
||||
const [bots] = await pool.query(
|
||||
"SELECT id, check_interval FROM bots WHERE status = 'running'"
|
||||
"SELECT id, check_interval, cron_expression FROM bots WHERE status = 'running'"
|
||||
);
|
||||
|
||||
for (const bot of bots) {
|
||||
registerBot(bot.id, bot.check_interval);
|
||||
registerBot(bot.id, bot.check_interval, bot.cron_expression);
|
||||
}
|
||||
|
||||
console.log(`[Scheduler] ${bots.length}개 봇 스케줄 등록됨`);
|
||||
|
|
@ -72,8 +70,8 @@ export async function startBot(botId) {
|
|||
|
||||
const bot = bots[0];
|
||||
|
||||
// 스케줄 등록
|
||||
registerBot(botId, bot.check_interval);
|
||||
// 스케줄 등록 (cron_expression 우선 사용)
|
||||
registerBot(botId, bot.check_interval, bot.cron_expression);
|
||||
|
||||
// 상태 업데이트
|
||||
await pool.query(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue