From 518a0d14eb91c4df9e5e2aefb06967e6aef6a214 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 26 Mar 2021 11:31:33 +0100 Subject: [PATCH] move discord connection to own file --- src/class/ConnectionModule.ts | 7 ++++ src/class/User.ts | 12 +++--- src/connections/discord.ts | 57 ++++++++++++++++++++++++++ src/index.ts | 49 +++++++--------------- src/modules/scanForNotifications.ts | 2 +- src/modules/scanForTimetableChanges.ts | 2 +- 6 files changed, 88 insertions(+), 41 deletions(-) create mode 100644 src/class/ConnectionModule.ts create mode 100644 src/connections/discord.ts diff --git a/src/class/ConnectionModule.ts b/src/class/ConnectionModule.ts new file mode 100644 index 0000000..7652d51 --- /dev/null +++ b/src/class/ConnectionModule.ts @@ -0,0 +1,7 @@ +import { Connection } from './User'; +import NotificationMessage from './NotificationMessage'; + +export default class ConnectionModule { + run: (message: NotificationMessage, connection: Connection) => void; + init: () => void; +} \ No newline at end of file diff --git a/src/class/User.ts b/src/class/User.ts index 45507af..9c48e8b 100644 --- a/src/class/User.ts +++ b/src/class/User.ts @@ -5,10 +5,12 @@ export default class User { password: string, baseURL: string, }; - public connections: Array<{ - type: string, - userID: string, - channelID: string, - }>; + public connections: Array; public ID: string; +} + +export class Connection { + type: string; + userID: string; + channelID: string; } \ No newline at end of file diff --git a/src/connections/discord.ts b/src/connections/discord.ts new file mode 100644 index 0000000..63482df --- /dev/null +++ b/src/connections/discord.ts @@ -0,0 +1,57 @@ +import Discord from 'discord.js'; +const client = new Discord.Client(); + +import User, { Connection } from '../class/User'; +import NotificationMessage from '../class/NotificationMessage'; + +let run = async (message: NotificationMessage, connection: Connection) => { + if (!process.env.BOT_TOKEN) return; // Only run when client is enabled + if (!client.readyAt) await new Promise(r => client.once('ready', r)) as void; // Wait for client to log in + + try { + const channel = await client.channels.fetch(connection.channelID).catch(()=>{}) as Discord.DMChannel; + if (!channel) return console.log(`Could not find channel: ${channel?.id}`); + + let embed = new Discord.MessageEmbed() + .setAuthor(message.title) + .setDescription(message.body) + .setColor(message.color); + + if (message.footer) embed.setFooter(message.footer); + + // Couldn't figure out how to attach the images in the assets folder, so I use hardcoded URLs instead + if (message.isImportant) { + embed.setAuthor(embed.author.name, 'https://cdn.discordapp.com/attachments/637695358373199879/824676476405940284/info.png'); + } + + if (message.isError) { + embed.color = 0xff0000; + embed.setAuthor(embed.author.name, 'https://cdn.discordapp.com/attachments/637695358373199879/824676465051828334/error.png' ); + } + + if (!embed.timestamp) embed.setTimestamp(); + channel.send(embed) + .catch(console.error); + } catch(e) { + console.warn(e); + + // If error didn't occur while sending an error message, attempt to send an error to the user. + if (!message.isError) { + let msg = new NotificationMessage() + .setTitle('Error during delivery') + .setBody(`\`\`\`js\n${e}\`\`\``); + + run(msg.error(), connection) + .catch(console.warn); + } + } +} + +let init = async () => { + if (!process.env.BOT_TOKEN) return console.log('Discord: No token specified'); + + client.login(process.env.BOT_TOKEN); + client.on('ready', () => console.log(`Discord Bot: Logged in as ${client.user.tag}`)); +} + +export { run, init }; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 8a4486a..97470c5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,12 @@ import * as dotenv from 'dotenv'; dotenv.config(); -import Discord from 'discord.js'; import Enmap from 'enmap'; import fs from 'fs'; import * as WebUntis from 'webuntis'; import User from './class/User'; import NotificationMessage from './class/NotificationMessage'; - -console.log('Discord Bot: Logging in'); -const client = new Discord.Client(); -client.login(process.env.BOT_TOKEN); -client.on('ready', () => console.log(`Discord Bot: Logged in as ${client.user.tag}`)); +import ConnectionModule from './class/ConnectionModule'; const seenMessages = new Enmap({ name: "seenMessages" }); const knownLessons = new Enmap({ name: "knownLessons" }); @@ -66,33 +61,15 @@ setInterval(fetchUpdates, 60000); async function sendMessage(message: NotificationMessage, user: User) { user.connections.forEach(async connection => { - switch(connection.type) { - case 'discord': - const channel = await client.channels.fetch(connection.channelID).catch(()=>{}) as Discord.DMChannel; - if (!channel) return console.log(`Could not find channel: ${channel?.id}`); - - let embed = new Discord.MessageEmbed() - .setAuthor(message.title) - .setDescription(message.body) - .setColor(message.color); - - if (message.footer) embed.setFooter(message.footer); - - // Couldn't figure out how to attach the images in the assets folder, so I use hardcoded URLs instead - if (message.isImportant) { - embed.setAuthor(embed.author.name, 'https://cdn.discordapp.com/attachments/637695358373199879/824676476405940284/info.png'); - } - - if (message.isError) { - embed.color = 0xff0000; - embed.setAuthor(embed.author.name, 'https://cdn.discordapp.com/attachments/637695358373199879/824676465051828334/error.png' ); - } - - if (!embed.timestamp) embed.setTimestamp(); - channel.send(embed) - .catch(console.error); - break; - default: console.log(`Unknown connection type: ${connection.type}`); + let path = require('path').join(__dirname, 'connections', connection.type + '.js') as string; + if (fs.existsSync(path)) { + try { + require(path).run(message, connection); + } catch(e) { + console.warn(e); + } + } else { + console.log(`Unknown connection type: ${connection.type}`); } }); } @@ -100,7 +77,6 @@ async function sendMessage(message: NotificationMessage, user: User) { export default { untisInstances, usersDB, - bot: client, sendEmbed: sendMessage, db: { seenMessages: seenMessages, @@ -109,6 +85,11 @@ export default { }; +// Initialize clients in dist/connections/* +fs.readdirSync(`${__dirname}/connections`).filter(file => file.endsWith('.js')).forEach(file => { + (require(`${__dirname}/connections/${file}`) as ConnectionModule).init(); +}); + // Run tasks in dist/tasks/* fs.readdirSync(`${__dirname}/tasks`).filter(file => file.endsWith('.js')).forEach(file => require(`${__dirname}/tasks/${file}`)); \ No newline at end of file diff --git a/src/modules/scanForNotifications.ts b/src/modules/scanForNotifications.ts index 31501d5..f05bad8 100644 --- a/src/modules/scanForNotifications.ts +++ b/src/modules/scanForNotifications.ts @@ -2,7 +2,7 @@ import * as WebUntis from 'webuntis'; import main from '../index'; import User from '../class/User'; import NotificationMessage from '../class/NotificationMessage'; -const { bot, untisInstances, db, sendEmbed } = main; +const { db, sendEmbed } = main; export async function run(untis: WebUntis.default, user: User) { let news = await untis.getNewsWidget(new Date(), true); diff --git a/src/modules/scanForTimetableChanges.ts b/src/modules/scanForTimetableChanges.ts index 85450cd..18b8a7e 100644 --- a/src/modules/scanForTimetableChanges.ts +++ b/src/modules/scanForTimetableChanges.ts @@ -2,7 +2,7 @@ import * as WebUntis from 'webuntis'; import main from '../index'; import User from '../class/User'; import NotificationMessage from '../class/NotificationMessage'; -const { bot, untisInstances, db, sendEmbed } = main; +const { db, sendEmbed } = main; export async function run(untis: WebUntis.default, user: User) { let timetable = await untis.getOwnTimetableForRange(new Date(Date.now() - 86400000), new Date(Date.now() + (86400000 * 7)), true);