/** * Disabled to evaluate usefulness 2/11/23 */ /* eslint-disable no-case-declarations */ /* eslint-disable no-continue */ /* eslint-disable no-await-in-loop */ import { promises as fs } from 'fs'; import { randomBytes } from 'crypto'; import { Message, TextableChannel } from 'eris'; import { Client, Command, RichEmbed } from '../class'; export default class Page extends Command { public local: { emergencyNumbers: string[], departmentNumbers: string[], validPagerCodes: string[], codeDict: Map, }; constructor(client: Client) { super(client); this.name = 'page'; this.description = 'Pages the specified emergency number, department number, or individual number with the specified pager code.'; this.usage = `${this.client.config.prefix}page [optional message]\n${this.client.config.prefix}page settings `; this.aliases = ['p']; this.permissions = 1; this.enabled = false; this.guildOnly = true; this.local = { emergencyNumbers: ['#0', '#1', '#2', '#3'], departmentNumbers: ['00', '01', '10', '20', '21', '22'], validPagerCodes: ['911', '811', '210', '265', '411', '419', '555', '556', '557', '558'], codeDict: new Map(), }; this.init(); } public init() { this.local.codeDict.set('911', 'Sender is requesting EMERGENCY assistance.'); this.local.codeDict.set('811', 'Sender is requesting immediate/ASAP assistance.'); this.local.codeDict.set('210', 'Sender is informing you they acknowledged your request, usually sent in response to OK the initial page. (10-4)'); this.local.codeDict.set('265', 'Sender is requesting that you check your email.'); this.local.codeDict.set('411', 'Sender is requesting information/counsel from you.'); this.local.codeDict.set('419', 'Sender didn\'t recognize your request.'); this.local.codeDict.set('555', 'Sender is requesting that you contact them.'); this.local.codeDict.set('556', 'Sender is requesting that you contact them via DMs.'); this.local.codeDict.set('557', 'Sender is requesting that you contact them via PBX/their extension.'); this.local.codeDict.set('558', 'Sender is requesting if they are able to call you via PBX. If so, please send the sender back a 210 page.'); } public async run(message: Message, args: string[]) { if (!args[0]) { this.client.commands.get('help').run(message, [this.name]); const embed = new RichEmbed(); embed.setTitle('Special Emergency/Department Numbers & Pager Codes'); embed.addField('Special Emergency Numbers', '`#0` | Broadcast - all Staff/Associates\n`#1` | Authoritative Broadcast - all Directors, Supervisors, Technicians, and Moderators\n`#2` | Systems Administrators/Technicians Broadcast - Matthew, Bsian, NightRaven, and all Technicians\n`#3` | Community/Moderation Team Broadcast - all Directors, Supervisors, Moderators, and Core Team'); embed.addField('Department Numbers', '`00` | Board of Directors\n`01` | Supervisors\n`10` | Technicians\n`20` | Moderators\n`21` | Core Team\n`22` | Associates'); embed.addField('Pager Codes', '"Pager" term in this field refers to the Staff member that initially paged. This is a list of valid codes you can send via a page.\n\n`911` - Pager is requesting EMERGENCY assistance\n`811` - Pager is requesting immediate/ASAP assistance\n`210` - Pager is informing you they acknowledged your request, usually sent in response to OK the initial page.\n`265` - Pager is requesting that you check your email\n`411` - Pager is requesting information/counsel from you\n`419` - Pager didn\'t recognize your request\n`555` - Pager is requesting that you contact them\n`556` - Pager is requesting that you contact them via DMs\n`557` - Pager is requesting that you contact them via PBX/their extension.\n`558` - Pager is requesting if they are able to call you via PBX. If so, please send the pager back a 210 page.'); embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setTimestamp(); return message.channel.createMessage({ embed }); } if (args[0] === 'settings') { const pager = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: message.author.id }); if (!pager) return this.error(message.channel, 'You do not have a Pager Number.'); switch (args[1]) { case 'email': if (args[2] === 'off') { if (pager.receiveEmail === false) return this.error(message.channel, 'You are already set to not receive email notifications.'); await pager.updateOne({ $set: { receiveEmail: false } }); return this.success(message.channel, 'You will no longer receive notifications by email for pages.'); } if (args[2] === 'on') { if (pager.receiveEmail === true) return this.error(message.channel, 'You are already set to receive email notifications.'); await pager.updateOne({ $set: { receiveEmail: true } }); return this.success(message.channel, 'You will now receive notifications by email for pages.'); } break; case 'phone': if (args[2] === 'off') { if (pager.receivePhone === false) return this.error(message.channel, 'You are already set to not receive PBX calls.'); await pager.updateOne({ $set: { receivePhone: false } }); return this.success(message.channel, 'You will no longer receive PBX calls for pages.'); } if (args[2] === 'on') { if (pager.receivePhone === true) return this.error(message.channel, 'You are already set to receive PBX calls.'); await pager.updateOne({ $set: { receivePhone: true } }); return this.success(message.channel, 'You will now receive PBX calls for pages.'); } break; default: this.error(message.channel, 'Invalid response provided.'); break; } } message.delete(); const loading = await this.loading(message.channel, 'Paging...'); const sender = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: message.author.id }); if (!sender) return this.error(message.channel, 'You do not have a Pager Number.'); const page = await this.page(args[0], sender.num, args[1], message, args[2] ? args.slice(2).join(' ') : undefined); if (page.status === true) { loading.delete(); return this.success(message.channel, page.message); } loading.delete(); return this.error(message.channel, page.message); } public logPage(sender: { number: string, user?: string }, recipient: { number: string, user?: string }, type: 'discord' | 'email' | 'phone', code: string): void { const chan = this.mainGuild.channels.get('722636436716781619'); chan.createMessage(`***[${type.toUpperCase()}] \`${sender.number} (${sender.user ? sender.user : ''})\` sent a page to \`${recipient.number} (${recipient.user ? recipient.user : ''})\` with code \`${code}\`.***`); this.client.util.signale.log(`PAGE (${type.toUpperCase()})| TO: ${recipient.number}, FROM: ${sender.number}, CODE: ${code}`); } public async page(recipientNumber: string, senderNumber: string, code: string, message: Message, txt?: string, options?: { emergencyNumber: string }): Promise<{status: boolean, message: string}> { try { if (txt?.length >= 140) return { status: false, message: 'Your message must be less than 141 characters.' }; const senderEntry = await this.client.db.mongo.PagerNumber.findOne({ num: senderNumber }); if (!senderEntry) { return { status: false, message: 'You do not have a Pager Number.' }; } if (this.local.emergencyNumbers.includes(recipientNumber)) { switch (recipientNumber) { case '#0': this.local.departmentNumbers.forEach(async (num) => { await this.page(num, senderNumber, code, message, txt, { emergencyNumber: '0' }); }); break; case '#1': await this.page('00', senderNumber, code, message, txt, { emergencyNumber: '1' }); await this.page('01', senderNumber, code, message, txt, { emergencyNumber: '1' }); await this.page('10', senderNumber, code, message, txt, { emergencyNumber: '1' }); await this.page('20', senderNumber, code, message, txt, { emergencyNumber: '1' }); break; case '#2': const matthew = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: '278620217221971968' }); const bsian = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: '253600545972027394' }); const nightraven = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: '239261547959025665' }); await this.page(matthew?.num, senderNumber, code, message, txt, { emergencyNumber: '2' }); await this.page(bsian?.num, senderNumber, code, message, txt, { emergencyNumber: '2' }); await this.page(nightraven?.num, senderNumber, code, message, txt, { emergencyNumber: '2' }); await this.page('10', senderNumber, code, message, txt, { emergencyNumber: '2' }); break; case '#3': await this.page('00', senderNumber, code, message, txt, { emergencyNumber: '3' }); await this.page('01', senderNumber, code, message, txt, { emergencyNumber: '3' }); await this.page('20', senderNumber, code, message, txt, { emergencyNumber: '3' }); await this.page('21', senderNumber, code, message, txt, { emergencyNumber: '3' }); break; default: break; } return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; } const recipientEntry = await this.client.db.mongo.PagerNumber.findOne({ num: recipientNumber }); if (!recipientEntry) { return { status: false, message: `Pager Number \`${recipientNumber}\` does not exist.` }; } if (!this.local.validPagerCodes.includes(code)) { return { status: false, message: 'The Pager Code you provided is invalid.' }; } for (const id of recipientEntry.discordIDs) { const recipient = this.mainGuild.members.get(recipientEntry.individualAssignID); const sender = this.mainGuild.members.get(senderEntry.individualAssignID); const chan = await this.client.getDMChannel(id); if (!chan) continue; if (!recipient || !sender) { this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'discord', code); } else { this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'discord', code); } chan.createMessage(`${options?.emergencyNumber ? `[SEN#${options.emergencyNumber}] ` : ''}__**Page**__\n**Recipient PN:** ${recipientNumber}\n**Sender PN:** ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})\n**Initial Command:** https://discordapp.com/channels/${this.mainGuild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)\n\n**Pager Code:** ${code} (${this.local.codeDict.get(code)})${txt ? `\n**Message:** ${txt}` : ''}`); } for (const email of recipientEntry.emailAddresses) { const recipient = this.mainGuild.members.get(recipientEntry.individualAssignID); const sender = this.mainGuild.members.get(senderEntry.individualAssignID); if (recipientEntry.receiveEmail === false) continue; if (!recipient || !sender) { this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'email', code); } else { this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'email', code); } await this.client.util.transporter.sendMail({ from: '"LOC Paging System" ', to: email, subject: `PAGE FROM ${senderNumber}`, html: `

Page

${options?.emergencyNumber ? `

[SEN#${options.emergencyNumber}]` : ''}Recipient PN: ${recipientNumber}
Sender PN: ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})
Initial Command: https://discordapp.com/channels/${this.mainGuild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)

Pager Code: ${code} (${this.local.codeDict.get(code)})${txt ? `
Message: ${txt}` : ''}`, }); } /* for (const id of recipientEntry.discordIDs) { const pager = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: id }); if (!pager || !pager.receivePhone) continue; const member = await this.client.db.mongo.Staff.findOne({ userID: pager.individualAssignID }); if (!member || !member.extension) continue; const fileExtension = `${randomBytes(10).toString('hex')}`; const [response] = await this.client.util.pbx.tts.synthesizeSpeech({ input: { text: `Hello, this call was automatically dialed by the Library of Code Private Branch Exchange. You have received a page from Pager Number, ${senderNumber}. The Pager Code is ${code}. Please check your Direct Messages on Discord for further information.` }, voice: { languageCode: 'en-US', ssmlGender: 'MALE' }, audioConfig: { audioEncoding: 'OGG_OPUS' }, }); await fs.writeFile(`/tmp/${fileExtension}.ogg`, response.audioContent, 'binary'); await this.client.util.exec(`ffmpeg -i /tmp/${fileExtension}.ogg -af "highpass=f=300, lowpass=f=3400" -ar 8000 -ac 1 -ab 64k -f mulaw /tmp/${fileExtension}.ulaw`); try { const chan = await this.client.util.pbx.ari.channels.originate({ endpoint: `PJSIP/${member.extension}`, extension: `${member.extension}`, callerId: `PAGE FRM ${senderNumber} <000>`, context: 'from-internal', priority: 1, app: 'cr-zero', }); chan.on('StasisStart', async (_event, channel) => { const playback = await channel.play({ media: `sound:/tmp/${fileExtension}`, }, undefined); playback.on('PlaybackFinished', () => { channel.hangup(); }); }); const recipient = this.mainGuild.members.get(recipientEntry.individualAssignID); const sender = this.mainGuild.members.get(senderEntry.individualAssignID); if (!recipient || !sender) { this.logPage({ number: senderNumber, user: 'N/A' }, { number: recipientNumber, user: 'N/A' }, 'phone', code); } else { this.logPage({ number: senderNumber, user: `${sender.username}#${sender.discriminator}` }, { number: recipientNumber, user: `${recipient.username}#${recipient.discriminator}` }, 'phone', code); } } catch (err) { this.client.util.signale.log(`Unable to Dial ${member.extension} | ${err}`); } } */ this.client.db.mongo.Stat.updateOne({ name: 'pages' }, { $inc: { value: 1 } }).exec(); return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; } catch (err) { this.client.util.signale.error(err); return { status: false, message: `Error during Processing: ${err}` }; } } }