-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
187 lines (158 loc) · 5.53 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import { Client, GatewayIntentBits, TextChannel } from 'discord.js';
import * as dotenv from 'dotenv';
import { MongoClient, Db, Collection } from 'mongodb';
import { readFileSync } from 'fs';
dotenv.config();
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] });
const DISCORD_TOKEN = process.env.DISCORD_TOKEN;
const SPORTSDB_API_KEY = process.env.SPORTSDB_API_KEY;
const MONGODB_URI = process.env.MONGODB_URI; // Your MongoDB connection string
const DB_NAME = process.env.DB_NAME || 'sportsdb';
const COLLECTION_NAME = process.env.COLLECTION_NAME || 'games';
interface Config {
teams?: ConfigTeam[];
leagues?: ConfigLeague[];
notifyRole: string;
}
interface ConfigTeam {
teamId: string;
notifyRoleId: string;
channelId: string;
}
interface ConfigLeague {
leagueId: string;
notifyRoleId: string;
channelId: string;
excludedWords?: string[];
}
type Game = {
eventId: string;
eventName: string;
eventDate: Date;
notified: boolean;
} & ConfigTeam;
const config: Config = JSON.parse(readFileSync('config.json', 'utf8'));
let db: Db;
let gamesCollection: Collection<Game>;
const mongoClient = new MongoClient(MONGODB_URI!);
async function connectToDatabase() {
await mongoClient.connect();
db = mongoClient.db(DB_NAME);
gamesCollection = db.collection(COLLECTION_NAME);
console.log('Connected to MongoDB');
}
client.once('ready', async () => {
console.log(`Logged in as ${client.user?.tag}!`);
await connectToDatabase();
scheduleDailyCheck();
checkUpcomingGames()
setInterval(checkDatabaseForNotifications, 60*1000); // Check every 1 minute
});
function scheduleDailyCheck() {
const now = new Date();
const nextCheck = new Date();
nextCheck.setHours(24, 0, 0, 0); // Next midnight
const timeUntilNextCheck = nextCheck.getTime() - now.getTime();
setTimeout(() => {
checkUpcomingGames();
setInterval(checkUpcomingGames, 86400000); // Every 24 hours after that
}, timeUntilNextCheck);
}
async function checkUpcomingGames() {
const teamPromises = (config?.teams || []).map(async (team) => {
await fetchUpcomingGames(team.teamId, team.notifyRoleId, team.channelId);
});
const leaguePromises = (config?.leagues || []).map(async (league) => {
await fetchUpcomingLeagueEvents(league.leagueId, league.notifyRoleId, league.channelId, league.excludedWords);
});
await Promise.all([...teamPromises, ...leaguePromises]);
}
async function fetchUpcomingLeagueEvents(leagueId: string, notifyRoleId: string, leagueChannelId: string, excludedWords?: string[]) {
try {
const url=`https://www.thesportsdb.com/api/v1/json/${SPORTSDB_API_KEY}/eventsnextleague.php?id=${leagueId}`;
const response = await fetch(url);
const responseJson = await response.json();
const events = responseJson.events;
if (events && events.length > 0) {
for (const event of events) {
if (excludedWords && excludedWords.length > 0) {
const excluded = excludedWords.some(word => event.strEvent.toLowerCase().includes(word.toLowerCase()));
if (excluded) {
continue;
}
}
const gameDate = new Date(event.dateEvent + ' ' + event.strTime);
const game = {
eventId: event.idEvent,
eventName: event.strEvent,
eventDate: gameDate,
leagueId,
notifyRoleId,
channelId: leagueChannelId,
};
await gamesCollection.updateOne(
{ eventId: event.idEvent },
{ $set: game },
{ upsert: true }
);
}
}
} catch (error) {
console.error('Error fetching upcoming games:', error);
}
}
async function fetchUpcomingGames(teamId: string, notifyRoleId: string, leagueChannelId: string) {
try {
const url=`https://www.thesportsdb.com/api/v1/json/${SPORTSDB_API_KEY}/eventsnext.php?id=${teamId}`;
const response = await fetch(url);
const responseJson = await response.json();
const events = responseJson.events;
if (events && events.length > 0) {
for (const event of events) {
const gameDate = new Date(event.dateEvent + ' ' + event.strTime);
const game = {
eventId: event.idEvent,
eventName: event.strEvent,
eventDate: gameDate,
teamId,
notifyRoleId,
channelId: leagueChannelId,
};
await gamesCollection.updateOne(
{ eventId: event.idEvent },
{ $set: game },
{ upsert: true }
);
}
}
} catch (error) {
console.error('Error fetching upcoming games:', error);
}
}
async function checkDatabaseForNotifications() {
const tenMinutesAgo = new Date((new Date()).getTime() - 600000);
const tenMinutesFromNow = new Date((new Date()).getTime() + 600000);
try {
const games = await gamesCollection.find({
eventDate: { $gte: tenMinutesAgo, $lte: tenMinutesFromNow },
$or: [
{ notified: { $exists: false } },
{ notified: false }
]
}).toArray();
for (const game of games) {
const channel = client.channels.cache.get(game.channelId!) as TextChannel;
if (channel) {
const eventDateUnix = Math.floor(game.eventDate.getTime()/1000);
channel.send(`<@&${game.notifyRoleId}> A game is coming up: ${game.eventName} at <t:${eventDateUnix}:R>`);
await gamesCollection.updateOne(
{ eventId: game.eventId },
{ $set: { notified: true } }
);
}
}
} catch (error) {
console.error('Error checking database for notifications:', error);
}
}
client.login(DISCORD_TOKEN);