forked from Lea/UntisBot
applied formatting and started refactoring
This commit is contained in:
parent
c4a9495efd
commit
f6099f0fe2
70
src/index.ts
70
src/index.ts
|
@ -1,53 +1,55 @@
|
||||||
import * as dotenv from 'dotenv';
|
import { codeBlock } from "@discordjs/builders";
|
||||||
|
import { Client, DMChannel, MessageEmbed } from "discord.js";
|
||||||
|
import * as dotenv from "dotenv";
|
||||||
|
import Enmap from "enmap";
|
||||||
|
import fs from "fs";
|
||||||
|
import WebUntis, { Lesson } from "webuntis";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
import Discord from 'discord.js';
|
|
||||||
import Enmap from 'enmap';
|
|
||||||
import fs from 'fs';
|
|
||||||
import * as WebUntis from 'webuntis';
|
|
||||||
|
|
||||||
const untis = new WebUntis.default(
|
const untis = new WebUntis(
|
||||||
process.env.SCHOOLNAME,
|
process.env.SCHOOLNAME,
|
||||||
process.env.USERNAME,
|
process.env.USERNAME,
|
||||||
process.env.PASSWORD,
|
process.env.PASSWORD,
|
||||||
process.env.BASEURL
|
process.env.BASEURL,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('Discord Bot: Logging in');
|
console.log("Discord Bot: Logging in");
|
||||||
const client = new Discord.Client();
|
const client = new Client({ intents: [] });
|
||||||
client.login(process.env.BOT_TOKEN);
|
client.login(process.env.BOT_TOKEN);
|
||||||
client.on('ready', () => console.log(`Discord Bot: Logged in as ${client.user.tag}`));
|
client.on("ready", () => console.log(`Discord Bot: Logged in as ${client.user.tag}`));
|
||||||
|
|
||||||
const seenMessages = new Enmap({ name: "seenMessages" });
|
const seenMessages = new Enmap({ name: "seenMessages" });
|
||||||
const knownLessons = new Enmap({ name: "knownLessons" });
|
const knownLessons: Enmap<string, Lesson> = new Enmap({ name: "knownLessons" });
|
||||||
|
|
||||||
const defaultEmbedColor = 0xFF9A00;
|
const defaultEmbedColor = 0xFF9A00;
|
||||||
|
|
||||||
|
|
||||||
// Periodically attempt to connect to untis and fetch timetable updates
|
// Periodically attempt to connect to untis and fetch timetable updates
|
||||||
let fetchUpdates = () => {
|
async function fetchUpdates() {
|
||||||
console.log('Untis: Logging in');
|
console.log("Untis: Logging in");
|
||||||
try {
|
try {
|
||||||
untis.login()
|
await untis.login();
|
||||||
.then(() => {
|
console.log("Untis: Logged in");
|
||||||
console.log(`Untis: Logged in`)
|
|
||||||
|
|
||||||
fs.readdirSync(`${__dirname}/modules`).filter(file => file.endsWith('.js')).forEach(file => {
|
fs.readdirSync(`${__dirname}/modules`).filter(file => file.endsWith(".js")).forEach(file => {
|
||||||
require(`${__dirname}/modules/${file}`).run();
|
require(`${__dirname}/modules/${file}`).run();
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => untis.logout().then(() => console.log('Untis: Logged out')), 10000);
|
setTimeout(async () => {
|
||||||
});
|
await untis.logout();
|
||||||
|
console.log("Untis: Logged out");
|
||||||
|
}, 10000);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
try {
|
try {
|
||||||
let embed = new Discord.MessageEmbed()
|
const embed = new MessageEmbed()
|
||||||
.setTitle('An error has occurred.')
|
.setTitle("An error has occurred.")
|
||||||
.setDescription(`\`\`\`js\n${e}\`\`\``)
|
.setDescription(codeBlock("js", `${e}`))
|
||||||
.setColor(0xff0000);
|
.setColor(0xff0000);
|
||||||
sendEmbed(embed);
|
sendEmbed(embed);
|
||||||
} catch(e) {
|
} catch (err) {
|
||||||
console.error(e);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,21 +58,21 @@ fetchUpdates();
|
||||||
setInterval(fetchUpdates, 60000);
|
setInterval(fetchUpdates, 60000);
|
||||||
|
|
||||||
|
|
||||||
async function sendEmbed(embed: Discord.MessageEmbed) {
|
async function sendEmbed(embed: MessageEmbed) {
|
||||||
const channel = await client.channels.fetch(process.env.CHANNEL) as Discord.DMChannel;
|
const channel = await client.channels.fetch(process.env.CHANNEL) as DMChannel;
|
||||||
if (!channel) throw `ERROR: Could not find channel`;
|
if (!channel) throw "ERROR: Could not find channel";
|
||||||
|
|
||||||
if (!embed.timestamp) embed.setTimestamp();
|
if (!embed.timestamp) embed.setTimestamp();
|
||||||
channel.send(embed).catch(console.error);
|
channel.send({ embeds: [embed] }).catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
untis: untis,
|
untis,
|
||||||
bot: client,
|
bot: client,
|
||||||
defaultEmbedColor: defaultEmbedColor,
|
defaultEmbedColor,
|
||||||
sendEmbed: sendEmbed,
|
sendEmbed,
|
||||||
db: {
|
db: {
|
||||||
seenMessages: seenMessages,
|
seenMessages,
|
||||||
knownLessons: knownLessons
|
knownLessons,
|
||||||
}
|
},
|
||||||
};
|
};
|
|
@ -1,20 +1,19 @@
|
||||||
import * as WebUntis from 'webuntis';
|
import Discord from "discord.js";
|
||||||
import main from '../index';
|
import main from "../index";
|
||||||
import Discord from 'discord.js';
|
const { defaultEmbedColor, untis, db, sendEmbed } = main;
|
||||||
const { bot, defaultEmbedColor, untis, db, sendEmbed } = main;
|
|
||||||
|
|
||||||
export async function run() {
|
export async function run() {
|
||||||
let news = await untis.getNewsWidget(new Date(), true);
|
const news = await untis.getNewsWidget(new Date(), true);
|
||||||
if (!news) return;
|
if (!news) return;
|
||||||
|
|
||||||
news.messagesOfDay.forEach(message => {
|
news.messagesOfDay.forEach(message => {
|
||||||
if (db.seenMessages.get(`${message.id}`)) return;
|
if (db.seenMessages.get(`${message.id}`)) return;
|
||||||
console.log('New message found: ' + message.text);
|
console.log("New message found: " + message.text);
|
||||||
let embed = new Discord.MessageEmbed()
|
const embed = new Discord.MessageEmbed()
|
||||||
.setAuthor('Notification')
|
.setAuthor("Notification")
|
||||||
.setColor(defaultEmbedColor)
|
.setColor(defaultEmbedColor)
|
||||||
.setTitle(message.subject)
|
.setTitle(message.subject)
|
||||||
.setDescription(message.text.replace(/\<br\>/g, "\n"))
|
.setDescription(message.text.replace(/<br>/g, "\n"))
|
||||||
.setFooter(`Notification ID: ${message.id}`);
|
.setFooter(`Notification ID: ${message.id}`);
|
||||||
|
|
||||||
sendEmbed(embed);
|
sendEmbed(embed);
|
||||||
|
|
|
@ -1,86 +1,88 @@
|
||||||
import * as WebUntis from 'webuntis';
|
import Discord from "discord.js";
|
||||||
import main from '../index';
|
import { Lesson, ShortData } from "webuntis";
|
||||||
import Discord from 'discord.js';
|
import main from "../index";
|
||||||
const { bot, defaultEmbedColor, untis, db, sendEmbed } = main;
|
const { defaultEmbedColor, untis, db, sendEmbed } = main;
|
||||||
|
function addProp(prop: ShortData) {
|
||||||
export async function run() {
|
let str = "";
|
||||||
let timetable = await untis.getOwnTimetableForRange(new Date(Date.now() - 86400000), new Date(Date.now() + (86400000 * 7)), true);
|
if ((!prop.name && !prop.longname) || prop.name == "---") {
|
||||||
|
str += "None";
|
||||||
let sentClasses = {};
|
} else if (prop.longname) {
|
||||||
|
|
||||||
timetable.forEach(lesson => {
|
|
||||||
let kLesson = db.knownLessons.get(`${lesson.id}`);
|
|
||||||
if (kLesson && hasChanged(lesson, kLesson)) {
|
|
||||||
if (sentClasses['' + (lesson.sg || lesson.su?.[0]?.id) + ' -- ' + lesson.date]) return;
|
|
||||||
let dateInfo = {
|
|
||||||
year: Number(`${lesson.date}`.substr(0, 4)),
|
|
||||||
month: Number(`${lesson.date}`.substr(4, 2)),
|
|
||||||
day: Number(`${lesson.date}`.substr(6, 2))
|
|
||||||
}
|
|
||||||
let date = new Date()
|
|
||||||
date.setFullYear(dateInfo.year);
|
|
||||||
date.setMonth(dateInfo.month - 1);
|
|
||||||
date.setDate(dateInfo.day);
|
|
||||||
|
|
||||||
let weekDay = ['Sunday', 'Monday', 'Thursday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][date.getDay()];
|
|
||||||
|
|
||||||
let embed = new Discord.MessageEmbed()
|
|
||||||
.setTitle(`Lesson updated`)
|
|
||||||
.setColor(defaultEmbedColor)
|
|
||||||
.setAuthor(`${weekDay}, ${date.getDate()}. ${date.getMonth() + 1}.: ${lesson.sg || '(Unnamed lesson)'} - ${lesson.te[0].longname || 'No teacher'}`);
|
|
||||||
|
|
||||||
let desc = ``;
|
|
||||||
|
|
||||||
const propFullName = {
|
|
||||||
kl: 'Class',
|
|
||||||
te: 'Teacher',
|
|
||||||
su: 'Subject',
|
|
||||||
ro: 'Room'
|
|
||||||
}
|
|
||||||
for (const prop of ['kl', 'te', 'su', 'ro']) {
|
|
||||||
let lessonStr = JSON.stringify(lesson[prop]);
|
|
||||||
let kLessonStr = JSON.stringify(kLesson[prop]);
|
|
||||||
|
|
||||||
let addProp = (prop) => {
|
|
||||||
let str = ``;
|
|
||||||
if ((!prop.name && !prop.longname) || prop.name == '---') str += `None`;
|
|
||||||
else if (prop.longname) {
|
|
||||||
str += `${prop.longname} `;
|
str += `${prop.longname} `;
|
||||||
if (prop.name && prop.name != prop.longname) str += `(${prop.name}) `;
|
if (prop.name && prop.name != prop.longname) str += `(${prop.name}) `;
|
||||||
} else str += prop.name;
|
} else {
|
||||||
|
str += prop.name;
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function run() {
|
||||||
|
const timetable = await untis.getOwnTimetableForRange(new Date(Date.now() - 86400000), new Date(Date.now() + (86400000 * 7)), true);
|
||||||
|
|
||||||
|
const sentClasses = {};
|
||||||
|
|
||||||
|
timetable.forEach(lesson => {
|
||||||
|
const kLesson = db.knownLessons.get(`${lesson.id}`);
|
||||||
|
if (kLesson && hasChanged(lesson, kLesson)) {
|
||||||
|
if (sentClasses["" + (lesson.sg || lesson.su?.[0]?.id) + " -- " + lesson.date]) return;
|
||||||
|
const dateInfo = {
|
||||||
|
year: Number(`${lesson.date}`.substr(0, 4)),
|
||||||
|
month: Number(`${lesson.date}`.substr(4, 2)),
|
||||||
|
day: Number(`${lesson.date}`.substr(6, 2)),
|
||||||
|
};
|
||||||
|
const date = new Date(dateInfo.year, dateInfo.month - 1, dateInfo.day);
|
||||||
|
|
||||||
|
const weekDay = ["Sunday", "Monday", "Thursday", "Wednesday", "Thursday", "Friday", "Saturday"][date.getDay()];
|
||||||
|
|
||||||
|
const embed = new Discord.MessageEmbed()
|
||||||
|
.setTitle("Lesson updated")
|
||||||
|
.setColor(defaultEmbedColor)
|
||||||
|
.setAuthor(`${weekDay}, ${date.getDate()}. ${date.getMonth() + 1}.: ${lesson.sg || "(Unnamed lesson)"} - ${lesson.te[0].longname || "No teacher"}`);
|
||||||
|
|
||||||
|
let desc = "";
|
||||||
|
|
||||||
|
const propFullName = {
|
||||||
|
kl: "Class",
|
||||||
|
te: "Teacher",
|
||||||
|
su: "Subject",
|
||||||
|
ro: "Room",
|
||||||
|
};
|
||||||
|
for (const prop of ["kl", "te", "su", "ro"]) {
|
||||||
|
const lessonStr = JSON.stringify(lesson[prop]);
|
||||||
|
const kLessonStr = JSON.stringify(kLesson[prop]);
|
||||||
|
|
||||||
|
|
||||||
if (lessonStr != kLessonStr) {
|
if (lessonStr != kLessonStr) {
|
||||||
desc += '**' + propFullName[prop] + '**: ' + (addProp(kLesson[prop][0]) || 'None') + ' → ' + (addProp(lesson[prop][0] || 'None')) + '\n';
|
desc += `**${propFullName[prop]}**: ${(addProp(kLesson[prop][0]) || "None")} → ${(addProp(lesson[prop][0] || "None"))}\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lesson.activityType != kLesson.activityType) {
|
if (lesson.activityType != kLesson.activityType) {
|
||||||
desc += `**Type:** ${kLesson.activityType} \u200b → \u200b ${lesson.activityType} \n`
|
desc += `**Type:** ${kLesson.activityType} \u200b → \u200b ${lesson.activityType} \n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lesson.substText)
|
if (lesson.substText) {
|
||||||
desc += `\nℹ️ ${lesson.substText}`;
|
desc += `\nℹ️ ${lesson.substText}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (lesson.info)
|
if (lesson.info) {
|
||||||
desc += `\nℹ️ ${lesson.info}`;
|
desc += `\nℹ️ ${lesson.info}`;
|
||||||
|
}
|
||||||
|
|
||||||
// if (lesson.code) embed.setColor(lesson.code == 'irregular' ? 'A781B4' : 'B1B3B4');
|
// if (lesson.code) embed.setColor(lesson.code == 'irregular' ? 'A781B4' : 'B1B3B4');
|
||||||
// Change the embed color when teacher ID is 0.
|
// Change the embed color when teacher ID is 0.
|
||||||
// Teacher ID 0 means that the class is canelled (at least on my school),
|
// Teacher ID 0 means that the class is canelled (at least on my school),
|
||||||
// although I don't know if this is always the case.
|
// although I don't know if this is always the case.
|
||||||
if (lesson.code == 'irregular' || lesson.te[0].id == 0) embed.setColor('A781B4');
|
if (lesson.code == "irregular" || lesson.te[0].id == 0) embed.setColor(0xA781B4);
|
||||||
|
|
||||||
embed.setDescription(desc);
|
embed.setDescription(desc);
|
||||||
sentClasses['' + (lesson.sg || lesson.su?.[0]?.id) + ' -- ' + lesson.date] = true;
|
sentClasses[`${lesson.sg || lesson.su?.[ 0 ]?.id} -- ${lesson.date}`] = true;
|
||||||
sendEmbed(embed);
|
sendEmbed(embed);
|
||||||
console.log(`Sent timetable update`);
|
console.log("Sent timetable update");
|
||||||
db.knownLessons.set(`${lesson.id}`, lesson);
|
|
||||||
}
|
}
|
||||||
else db.knownLessons.set(`${lesson.id}`, lesson);
|
db.knownLessons.set(`${lesson.id}`, lesson);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasChanged(lesson1: WebUntis.Lesson, lesson2: WebUntis.Lesson) {
|
function hasChanged(lesson1: Lesson, lesson2: Lesson) {
|
||||||
return (JSON.stringify(lesson1) != JSON.stringify(lesson2));
|
return (JSON.stringify(lesson1) != JSON.stringify(lesson2));
|
||||||
}
|
}
|
Loading…
Reference in a new issue