This repository has been archived by the owner on Feb 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathannouncements.js
182 lines (155 loc) · 6 KB
/
announcements.js
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
/*!
* CoronaBot -- ECS Mailing List Annoucement Channel
*
* This file forwards messages sent to my mailbox via a
* mailing list (see targetAddresses).
*
* FIXME: This module is currently broken and disabled, I may or may not bother
* to fix it.
*
* -- Raresh
*/
/*!
* Announcement channels
*
* This file handles the announcement channels, which pipe email announcements
* sent by ECS staff to students (via my email)
*/
const Discord = require("discord.js");
const ImapClient = require("emailjs-imap-client").default;
const simpleParser = require("mailparser").simpleParser;
/**
* These are the mailing lists for members of a certain class.
* If I receive messages as this email, so does everyone.
*
* Use these to only post relevant messages.
*/
const targetAddresses = [
];
class Announcements {
/**
*
* @param {object} config The configuration object (JSON)
* @param {Discord.Client} client
* @param {object} bot
*/
constructor(config, client, bot) {
// fetch config from main
this.config = config;
this.client = client;
this.bot = bot;
// don't bother in dev mode
if (bot.devMode) return;
// keep the time
this.startTime = new Date();
// get the channel
client.channels.fetch(config.discord.emailChannel).then(c => {
this.channel = c;
// (async () => {
// let messages = this.channel.messages
// let f = await messages.fetch({ limit: 100 })
// for (const message of f) {
// message[1].delete()
// }
// })()
});
// open imap client and connect to it
this.imapClient = new ImapClient(
config.email.host,
config.email.port,
config.email.options
);
this.imapClient.connect()
.then(() => {
this.bot.log.log("EMAIL", "Connected to server");
// select the mail box
this.imapClient.selectMailbox("INBOX").then(mailbox => {
this.bot.log.log("EMAIL", "Got the mailbox");
// set up events
this.imapClient.onupdate = (path, type, value) => {
if (type === "exists") {
console.log(`EMAIL: ${value} exist in ${path}`);
this.checkMailbox();
} else {
/* the library supports more but i cant be fucked */
}
};
// initial mailbox check
this.checkMailbox();
});
})
.catch(e => {
throw e;
});
// make an array to store hashes of known emails
// (and to not dupliate things)
this.pastMailUIDs = [];
}
async checkMailbox() {
this.bot.log.log("EMAIL", "Checking mailbox...");
// convert the target addresses to a query
let queries = targetAddresses.map(addr => { return { header: [ "to", addr ] }; } );
// get the amount of messages in box
let boxDeets = await this.imapClient.selectMailbox("INBOX");
// fetch emails
const blockSize = 10;
let newUids = 0;
for (let i = 1; i <= boxDeets.exists; i += blockSize) {
let scale = `${i}:${ Math.min(i + blockSize, boxDeets.exists) }`;
let messages = await this.imapClient.listMessages(
"INBOX",
scale,
[ "uid", "envelope", "body[]" ]
);
this.bot.log.log("EMAIL", `Downloaded mailbox ${scale}`);
for (const message of messages) {
// skip if it's too old
if (Date.parse(message.envelope.date) < this.startTime) continue;
// skip if the target is not whitelisted
let hasEntry = false;
for (const entry of message.envelope.to || [ ]) {
hasEntry |= targetAddresses.includes(entry.address);
}
if (!hasEntry) continue;
// if we've seen the UID before, same... skip it
if (this.pastMailUIDs.includes(message.uid)) continue;
this.pastMailUIDs.push(message.uid);
newUids++;
// parse the email
let body = await simpleParser(message["body[]"]);
// prep the rich embed
var richEmbed = new Discord.MessageEmbed()
.setColor("#115737")
.setTitle(body.subject || "(No Subject)")
.setAuthor(body.from.text)
.setTimestamp(Date.parse(message.envelope.date))
.addField("To", body.to.text)
.setDescription(body.text)
.setFooter("ECS Mailing List");
// add a warning for shortened ones
if (richEmbed.description.length >= 2048) {
richEmbed
.setColor("#FF0000")
.addField("Notice", "Please check your email for full text.")
.setDescription(richEmbed.description.substring(0, 2040) + "...");
}
this.channel.send(richEmbed).catch(e => console.log("DISCORD: Error " + e));
}
}
this.bot.log.log("EMAIL", `Done. ${newUids} new entries`);
}
/**
* JavaScript doesn't have deconstructors... oh well.
*/
destruct() {
this.imapClient.close().then(() => {
this.bot.log.log("EMAIL", "Connection ended");
});
}
}
module.exports = Announcements;