From 931ed3c475c887862776a80031678ced7e5fff4a Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Sun, 1 Oct 2023 16:31:12 -0600 Subject: [PATCH] testing more things --- fpbxFuncs.js | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ index.js | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 fpbxFuncs.js diff --git a/fpbxFuncs.js b/fpbxFuncs.js new file mode 100644 index 0000000..1ace440 --- /dev/null +++ b/fpbxFuncs.js @@ -0,0 +1,97 @@ +// Some random functions, as to not clutter the main file +// Generate GraphQL query +const generateQuery = (type, args) => { + switch (type) { + case 'lookup': + return minifyQuery(`query { + fetchExtension(extensionId: "${args.ext}") { + user { + extension + name + extPassword + voicemail + } + } + fetchVoiceMail(extensionId: "${args.ext}") { + password + email + } + }`); + break; + case 'list': + return minifyQuery(`query { + fetchAllExtensions { + extension { + user { + extension + name + } + } + } + }`); + break; + case 'add': + return minifyQuery(`mutation { + addExtension(input: { + extensionId: "${args.ext}" + name: "${args.name}" + email: "${args.uid}" + vmEnable: true + vmPassword: "${args.ext}" + maxContacts: "5" + umEnable: false + }) { + status + } + }`); + break; + + case 'delete': + return minifyQuery(`mutation { + deleteExtension(input: {extensionId: ${args.ext}}) { + status + } + }`); + break; + case 'reload': + return minifyQuery(`mutation { + doreload(input: {clientMutationId: "${args.id}"}) { + status + } + }`); + break; + case 'update_name': + return minifyQuery(`mutation { + updateCoreUser (input: {extension: ${args.ext}, name: "${args.name}", noanswer_cid: "", busy_cid: "", chanunavail_cid: "", busy_dest: "", noanswer_dest: "", chanunavail_dest: ""}) { + coreuser { + name + } + } + }`); + } +} + +// minify query function +const minifyQuery = (query) => { + return query.replace(/\s+/g, ' ').trim(); +} + +module.exports = { + generateQuery, + minifyQuery, + // Input validation + validateInput: function (input, type) { + switch (type) { + case 'extention': + // Check if input is a 3 digit number + if (input.length != 3) { + return false; + } + if (isNaN(input)) { + return false; + } + return true; + break; + } + } +} diff --git a/index.js b/index.js index 0fdd732..e668f8e 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,70 @@ const config = require("./config.json"); const fs = require("fs"); +const fpbxFuncs = require("./fpbxFuncs.js"); + +const lookupExtension = (ident, type) => { // type is either "ext" or "uid" + return new Promise((resolve, reject) => { + switch (type) { + case "ext": + pbxClient.request(fpbxFuncs.generateQuery('lookup', { + ext: ident + })).then((result) => { + res = { + "status": "exists", + "result": result + } + resolve(res); + }).catch((error) => { + res = { + "status": "notfound", + "result": error + } + reject(res); + }); + break; + case "uid": + // Find the extension based on Discord ID in the voicemail email field + pbxClient.request(fpbxFuncs.generateQuery('list', {})).then(async (result) => { + // loop through all extensions, run a lookup on each one, and return the first one that matches + var found = false; + var ext = ""; + var count = 0; + result.fetchAllExtensions.extension.forEach(async (ext) => { + pbxClient.request(fpbxFuncs.generateQuery('lookup', { + ext: ext.user.extension + })).then((result) => { + if (result.fetchVoiceMail.email == ident && !found) { + found = true; + ext = result; + clearInterval(x); + resolve({ + "status": "exists", + "result": ext + }) + } + count++; + }).catch((error) => { + reject(error); + }); + }); + x = setInterval(() => { + if (count == result.fetchAllExtensions.extension.length) { + clearInterval(x); + if (!found) { + reject("Not found"); + } + } + }, 100); + + }).catch((error) => { + reject(error); + }); + break; + default: + reject("Invalid type"); + } + }); +} // Setup GQL Client const { @@ -15,7 +80,7 @@ const pbxClient = new FreepbxGqlClient(config.freepbx.url, { // Setup Discord client const Discord = require("discord.js"); -const client = new Discord.Client({intents: ["Guilds", "GuildMembers"]}); +const client = new Discord.Client({ intents: ["Guilds", "GuildMembers"] }); // Setup filesystem monitoring (for new voicemail) const chokidar = require("chokidar"); @@ -23,7 +88,34 @@ const watcher = chokidar.watch(config.freepbx.voicemaildir, { ignored: /(^|[\/\\])\../, persistent: true }); +watched = []; +watcher.on("add", async (event, path) => { + // if the file is already being watched, ignore it, this stops spam from the watcher at startup + if (watched.includes(path)) return; + watched.push(path); -watcher.on("all", (event, path) => { - console.log(event, path); + // extract file name from path + let filename = path.split("/").pop(); + // extract mailbox from path (path looks like /var/spool/asterisk/voicemail/default/1000/INBOX/file.wav) + let mailbox = path.split("/")[6]; + if(mailbox !== "INBOX") return; // ignore anything that isn't in the inbox + // if its a txt file (voicemail info), open it and get relavent info + // make a json object with the callerid, duration, origdate, and origmailbox from the txt file + if (filename.endsWith(".txt")) { + let file = fs.readFileSync(path, "utf8"); + let lines = file.split("\n"); + let callerid = lines[9].split("=")[1].replace(/"/g, ""); + let duration = lines[17].split("=")[1]; + let origdate = lines[11].split("=")[1]; + let origmailbox = lines[2].split("=")[1]; + let message = { + "callerid": callerid, + "duration": duration, + "origdate": origdate, + "origmailbox": origmailbox + } + // get the extension info from the callerid + let ext = await lookupExtension(callerid, "uid"); + console.log(`New voicemail from ${message.callerid} (${message.duration}s)`); + } }); \ No newline at end of file