해당 글은, 제가 작성한 Discord.js 보일러플레이트를 기반으로 합니다. 해당 보일러픝레이트는 다음에라도 봇을 빠르게 만들고 싶으실 때 사용하실 수 있습니다. Discord.js TypeScript Boilerplate
안녕하세요! 드디어 우리 Discord.js 봇 개발 튜토리얼의 마지막 시간이 되었습니다. 지난 시간에는 웹 기반 관리자 패널을 만들어봤는데, 이제 정말 완성도 높은 봇의 모습을 갖추게 되었죠.
마지막으로 다룰 주제는 스케줄링입니다. 매일 정해진 시간에 알림을 보내거나, 주기적으로 데이터를 백업하거나, 특정 조건에 따라 자동으로 작업을 수행하는 기능 말이에요.
node-cron이라는 라이브러리를 사용해서 다양한 스케줄링 기능을 구현해보겠습니다. 리눅스의 cron과 비슷한 문법을 사용하지만, JavaScript 환경에서 더 유연하게 활용할 수 있어요.
node-cron이란?
node-cron은 Node.js에서 cron 작업을 수행할 수 있게 해주는 라이브러리입니다. 정해진 시간이나 주기에 따라 함수를 자동으로 실행할 수 있어요.
cron 표현식:
* * * * * *
| | | | | |
| | | | | +-- 요일 (0-7, 0과 7은 일요일)
| | | | +---- 월 (1-12)
| | | +------ 일 (1-31)
| | +-------- 시 (0-23)
| +---------- 분 (0-59)
+------------ 초 (0-59, 선택사항)
자주 사용되는 패턴들:
'0 0 * * *'
- 매일 자정'0 9 * * *'
- 매일 오전 9시'0 0 * * 1'
- 매주 월요일 자정'*/30 * * * *'
- 30분마다'0 */2 * * *'
- 2시간마다
실제 봇에서 어떻게 활용할 수 있는지 차근차근 알아보겠습니다.
패키지 설치 및 기본 설정
먼저 필요한 패키지를 설치해보겠습니다.
npm install node-cron
npm install -D @types/node-cron
간단한 스케줄러 구현
보일러플레이트의 scheduler.ts
파일을 간단하게 수정해보겠습니다:
// src/scheduler.ts
import cron from "node-cron";
import { Client, TextChannel, EmbedBuilder } from "discord.js";
export function startScheduledJobs(client: Client) {
// 매일 오전 9시에 일일 체크인 메시지
cron.schedule("0 9 * * *", async () => {
await sendDailyMessage(client);
});
// 매 시간마다 봇 상태 업데이트
cron.schedule("0 * * * *", async () => {
await updateBotActivity(client);
});
// 매주 월요일 오전 10시에 주간 리포트
cron.schedule("0 10 * * 1", async () => {
await sendWeeklyReport(client);
});
console.log("스케줄러가 시작되었습니다.");
}
// 일일 메시지 발송
async function sendDailyMessage(client: Client) {
try {
const channelId = "1234567890123456789"; // 실제 채널 ID로 변경
const channel = client.channels.cache.get(channelId) as TextChannel;
if (!channel) {
console.log("채널을 찾을 수 없습니다.");
return;
}
const embed = new EmbedBuilder()
.setTitle("🌅 좋은 아침!")
.setDescription("새로운 하루가 시작되었습니다!")
.setColor(0x00ff00)
.setTimestamp();
await channel.send({ embeds: [embed] });
console.log("일일 메시지를 발송했습니다.");
} catch (error) {
console.error("일일 메시지 발송 실패:", error);
}
}
// 봇 상태 업데이트
async function updateBotActivity(client: Client) {
try {
const activities = [
"공부 시간 측정 중",
`${client.guilds.cache.size}개 서버 관리 중`,
`${client.users.cache.size}명의 사용자와 함께`,
"24시간 대기 중",
];
const randomActivity =
activities[Math.floor(Math.random() * activities.length)];
client.user?.setActivity(randomActivity, { type: 3 }); // 3: Watching
console.log(`봇 상태 업데이트: ${randomActivity}`);
} catch (error) {
console.error("봇 상태 업데이트 실패:", error);
}
}
// 주간 리포트 발송
async function sendWeeklyReport(client: Client) {
try {
const channelId = "1234567890123456789"; // 실제 채널 ID로 변경
const channel = client.channels.cache.get(channelId) as TextChannel;
if (!channel) {
console.log("채널을 찾을 수 없습니다.");
return;
}
const embed = new EmbedBuilder()
.setTitle("📊 주간 리포트")
.setDescription("이번 주 활동 요약입니다")
.setColor(0x0099ff)
.addFields(
{
name: "서버 수",
value: client.guilds.cache.size.toString(),
inline: true,
},
{
name: "사용자 수",
value: client.users.cache.size.toString(),
inline: true,
},
{ name: "응답 시간", value: `${client.ws.ping}ms`, inline: true }
)
.setTimestamp();
await channel.send({ embeds: [embed] });
console.log("주간 리포트를 발송했습니다.");
} catch (error) {
console.error("주간 리포트 발송 실패:", error);
}
}
기존 index.ts
에서는 이미 스케줄러를 호출하고 있으니 그대로 두면 됩니다:
// src/index.ts에서 이미 호출 중
startScheduledJobs(client);
더 많은 예시들
특정 시간에 알림 보내기
// 매일 오후 6시에 퇴근 알림
cron.schedule("0 18 * * *", async () => {
const channel = client.channels.cache.get("채널ID") as TextChannel;
if (channel) {
await channel.send("🏠 퇴근 시간입니다! 오늘도 수고하셨어요!");
}
});
// 매주 금요일 오후 5시에 주말 인사
cron.schedule("0 17 * * 5", async () => {
const channel = client.channels.cache.get("채널ID") as TextChannel;
if (channel) {
await channel.send("🎉 즐거운 주말 되세요!");
}
});
정기적인 서버 관리
// 매일 자정에 서버 정리
cron.schedule("0 0 * * *", async () => {
console.log("일일 서버 정리 시작...");
// 캐시 정리
client.users.cache.sweep((user) => user.id !== client.user?.id);
console.log("서버 정리 완료");
});
// 30분마다 상태 확인
cron.schedule("*/30 * * * *", async () => {
console.log(
`서버 상태: ${client.guilds.cache.size}개 서버, 핑: ${client.ws.ping}ms`
);
});
사용할 때 주의사항
1. 채널 ID 설정하기
실제 사용하려면 채널 ID를 올바르게 설정해야 해요:
const channelId = "1234567890123456789"; // 이 부분을 실제 채널 ID로 변경
2. 시간대 설정
한국 시간 기준으로 작업하려면:
# .env 파일에 추가
TZ=Asia/Seoul
3. 에러 처리
각 함수에서 에러가 발생해도 봇이 멈추지 않도록 try-catch를 사용했어요.
4. 개발 중일 때는 짧은 주기로 테스트
// 개발할 때는 1분마다 테스트
if (process.env.NODE_ENV === "development") {
cron.schedule("* * * * *", async () => {
console.log("테스트 메시지");
});
}
마무리
이렇게 간단하게 node-cron을 사용해서 스케줄링 기능을 구현할 수 있어요! 복잡한 관리 기능이 필요하지 않다면 이 방법이 훨씬 간단하고 이해하기 쉽습니다.
중요한 것은 실제 채널 ID를 올바르게 설정하고, 적절한 에러 처리를 해주는 것이에요. 그러면 봇이 자동으로 정해진 시간에 메시지를 보내고 상태를 업데이트해줄 거예요!
'DiscordJS 개발 튜토리얼' 카테고리의 다른 글
[DiscordJS 봇 개발 튜토리얼] 15. 관리자 패널 만들기 (웹 연동 기본): 웹으로 봇을 편리하게 관리하자! (0) | 2025.06.14 |
---|---|
[DiscordJS 봇 개발 튜토리얼] 12. 다국어 지원 시스템 만들기 (i18n): 전 세계와 소통하자! (0) | 2025.06.13 |
[DiscordJS 봇 개발 튜토리얼] 11. 사용자 반응(이모지) 기반 기능 만들기: 손쉬운 상호작용의 시작 (1) | 2025.06.12 |
[DiscordJS 봇 개발 튜토리얼] 10. 대화형 UI: 셀렉트 메뉴와 모달 활용하기 (7) | 2025.06.11 |
[DiscordJS 봇 개발 튜토리얼] 9. 봇 배포 및 호스팅하기: 내 봇을 세상에 내보내자! (2) | 2025.06.11 |