1
+ const { Client, GatewayIntentBits, Events, EmbedBuilder } = require ( 'discord.js' ) ;
2
+ require ( 'dotenv' ) . config ( ) ;
3
+
4
+ const client = new Client ( {
5
+ intents : [
6
+ GatewayIntentBits . Guilds ,
7
+ GatewayIntentBits . GuildScheduledEvents ,
8
+ GatewayIntentBits . MessageContent ,
9
+ ]
10
+ } ) ;
11
+
12
+ const NOTIFICATION_CHANNEL_ID = process . env . YOUR_DISCORD_CHANNEL_ID ;
13
+ // 예정된 이벤트 알림을 저장할 Map
14
+ const scheduledNotifications = new Map ( ) ;
15
+
16
+ client . once ( 'ready' , ( ) => {
17
+ console . log ( `Logged in as ${ client . user . tag } ` ) ;
18
+ console . log ( 'Notification Channel ID:' , NOTIFICATION_CHANNEL_ID ) ;
19
+ console . log ( 'Watching for events...' ) ;
20
+ checkUpcomingEvents ( ) ;
21
+ } ) ;
22
+
23
+ // 1시간 전 알림을 위한 주기적 체크
24
+ function checkUpcomingEvents ( ) {
25
+ setInterval ( async ( ) => {
26
+ const now = Date . now ( ) ;
27
+ scheduledNotifications . forEach ( async ( notified , eventId ) => {
28
+ const event = await client . guilds . cache . first ( ) ?. scheduledEvents . fetch ( eventId ) . catch ( ( ) => null ) ;
29
+ if ( ! event ) {
30
+ scheduledNotifications . delete ( eventId ) ;
31
+ return ;
32
+ }
33
+
34
+ const timeUntilEvent = event . scheduledStartTimestamp - now ;
35
+ // 1시간 전 (허용 오차 1분)
36
+ if ( timeUntilEvent <= 3600000 && timeUntilEvent > 3540000 && ! notified . oneHourNotified ) {
37
+ sendEventReminder ( event , '1시간' ) ;
38
+ notified . oneHourNotified = true ;
39
+ }
40
+ } ) ;
41
+ } , 60000 ) ; // 1분마다 체크
42
+ }
43
+
44
+ async function sendEventReminder ( event , timeLeft ) {
45
+ try {
46
+ const channel = await client . channels . fetch ( NOTIFICATION_CHANNEL_ID ) ;
47
+ const reminderEmbed = new EmbedBuilder ( )
48
+ . setColor ( '#FF9300' )
49
+ . setTitle ( '⏰ 이벤트 시작 알림' )
50
+ . setDescription ( `**${ event . name } ** 이벤트가 ${ timeLeft } 후에 시작됩니다!` )
51
+ . addFields (
52
+ { name : '시작 시간' , value : `<t:${ Math . floor ( event . scheduledStartTimestamp / 1000 ) } :R>` , inline : true }
53
+ )
54
+ . setFooter ( { text : '이벤트에 참여하시려면 위 제목을 클릭하세요!' } )
55
+ . setTimestamp ( ) ;
56
+
57
+ await channel . send ( {
58
+ content : `@everyone 잊지 마세요!` ,
59
+ embeds : [ reminderEmbed ]
60
+ } ) ;
61
+ } catch ( error ) {
62
+ console . error ( 'Error sending event reminder:' , error ) ;
63
+ }
64
+ }
65
+
66
+ client . on ( Events . GuildScheduledEventCreate , async scheduledEvent => {
67
+ console . log ( 'New event detected:' , scheduledEvent . name ) ;
68
+ try {
69
+ const channel = await client . channels . fetch ( NOTIFICATION_CHANNEL_ID ) ;
70
+
71
+ const eventEmbed = new EmbedBuilder ( )
72
+ . setColor ( '#5865F2' )
73
+ . setTitle ( '🎉 새로운 이벤트가 등록되었습니다!' )
74
+ . setDescription ( `# ${ scheduledEvent . name } \n\n` ) // 이벤트 이름을 더 크게
75
+ . addFields (
76
+ { name : '\u200B' , value : '\u200B' } , // 빈 줄 추가
77
+ {
78
+ name : '📅 시작 시간' ,
79
+ value : `<t:${ Math . floor ( scheduledEvent . scheduledStartTimestamp / 1000 ) } :F>\n(<t:${ Math . floor ( scheduledEvent . scheduledStartTimestamp / 1000 ) } :R>)` ,
80
+ inline : false // inline을 false로 변경
81
+ } ,
82
+ { name : '\u200B' , value : '\u200B' } // 빈 줄 추가
83
+ ) ;
84
+
85
+ if ( scheduledEvent . scheduledEndTimestamp ) {
86
+ eventEmbed . addFields ( {
87
+ name : '⏰ 종료 시간' ,
88
+ value : `<t:${ Math . floor ( scheduledEvent . scheduledEndTimestamp / 1000 ) } :F>` ,
89
+ inline : false
90
+ } ,
91
+ { name : '\u200B' , value : '\u200B' } ) ; // 빈 줄 추가
92
+ }
93
+
94
+ if ( scheduledEvent . description ) {
95
+ eventEmbed . addFields ( {
96
+ name : '📝 설명' ,
97
+ value : scheduledEvent . description ,
98
+ inline : false
99
+ } ,
100
+ { name : '\u200B' , value : '\u200B' } ) ; // 빈 줄 추가
101
+ }
102
+
103
+ if ( scheduledEvent . entityMetadata ?. location ) {
104
+ eventEmbed . addFields ( {
105
+ name : '📍 장소' ,
106
+ value : scheduledEvent . entityMetadata . location ,
107
+ inline : false
108
+ } ,
109
+ { name : '\u200B' , value : '\u200B' } ) ; // 빈 줄 추가
110
+ }
111
+
112
+ eventEmbed
113
+ . setURL ( `https://discord.com/events/${ scheduledEvent . guildId } /${ scheduledEvent . id } ` )
114
+ . setFooter ( { text : '이벤트에 참여하시려면 위 제목을 클릭하세요!' } )
115
+ . setTimestamp ( ) ;
116
+
117
+ await channel . send ( {
118
+ content : '새로운 이벤트가 등록되었습니다! @everyone' ,
119
+ embeds : [ eventEmbed ]
120
+ } ) ;
121
+
122
+ // 1시간 전 알림을 위해 이벤트 저장
123
+ scheduledNotifications . set ( scheduledEvent . id , { oneHourNotified : false } ) ;
124
+
125
+ console . log ( 'Event notification sent successfully!' ) ;
126
+ } catch ( error ) {
127
+ console . error ( 'Error sending event notification:' , error ) ;
128
+ }
129
+ } ) ;
130
+
131
+ client . login ( process . env . DISCORD_BOT_TOKEN ) ;
0 commit comments