Compare commits
No commits in common. "66931ca73502c229bd8e74af325a865d6eca6791" and "fe26d3fe1eaa68c12a4bffb20e02beb2c4b7ce16" have entirely different histories.
66931ca735
...
fe26d3fe1e
159
index.js
159
index.js
|
|
@ -1,25 +1,6 @@
|
||||||
const blocked = [
|
require("dotenv").config({quiet: true});
|
||||||
'0',
|
const exec = require("child_process").exec;
|
||||||
'0000',
|
const Discord = require("discord.js");
|
||||||
'9998',
|
|
||||||
'9999'
|
|
||||||
];
|
|
||||||
|
|
||||||
import dotenv from 'dotenv';
|
|
||||||
dotenv.config({ quiet: true })
|
|
||||||
import AMISocket from 'ami';
|
|
||||||
const sock = new AMISocket({
|
|
||||||
connect: {
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: 5038
|
|
||||||
},
|
|
||||||
credentials: {
|
|
||||||
username: process.env.AMI_USER,
|
|
||||||
secret: process.env.AMI_SECRET
|
|
||||||
},
|
|
||||||
events: true
|
|
||||||
})
|
|
||||||
import Discord from 'discord.js';
|
|
||||||
const hook = new Discord.WebhookClient({ url: process.env.DISCORD_WEBHOOK_URL });
|
const hook = new Discord.WebhookClient({ url: process.env.DISCORD_WEBHOOK_URL });
|
||||||
|
|
||||||
const cfTypes = {
|
const cfTypes = {
|
||||||
|
|
@ -28,92 +9,72 @@ const cfTypes = {
|
||||||
CFU: "Unavailable",
|
CFU: "Unavailable",
|
||||||
}
|
}
|
||||||
|
|
||||||
const main = () => {
|
const main = async () => {
|
||||||
var respData = [];
|
const runAsterisk = (command) =>
|
||||||
console.log('checking')
|
new Promise((resolve) =>
|
||||||
// getList for CF, CFB, CFU
|
exec(command, (error, stdout, stderr) => resolve({ error, stdout, stderr }))
|
||||||
sock.getList({
|
);
|
||||||
action: 'DBGetTree',
|
|
||||||
family: 'CF'
|
try {
|
||||||
}).then(async (response) => {
|
var forwards = {};
|
||||||
// Responses are an array of objects. The first should always have eventlist: 'start', and last should have eventlist: 'complete'. Remove these, make an array of objects {key, val} based on the rest of the response objects.
|
const commands = [
|
||||||
let entries = response.filter(r => r.eventlist !== 'start' && r.eventlist !== 'Complete').map(r => ({ key: r.key, val: r.val }));
|
'asterisk -x "database show CF"',
|
||||||
for (let entry of entries) {
|
'asterisk -x "database show CFB"',
|
||||||
let stuff = entry.key.split('/');
|
'asterisk -x "database show CFU"',
|
||||||
let type = stuff[1];
|
];
|
||||||
let ext = stuff[2];
|
for (const command of commands) {
|
||||||
console
|
const { error, stdout, stderr } = await runAsterisk(command);
|
||||||
respData.push({
|
if (error) {
|
||||||
extension: ext,
|
console.error(`Error executing command "${command}": ${error}`);
|
||||||
type: type,
|
continue;
|
||||||
target: entry.val
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}).then(() => {
|
const lines = stdout.split('\n');
|
||||||
sock.getList({
|
for (const line of lines) {
|
||||||
action: 'DBGetTree',
|
const match = line.match(/^\/(CF|CFB|CFU)\/(\d+)\s+:\s+(.+)$/);
|
||||||
family: 'CFB'
|
if (match) {
|
||||||
}).then(async (response) => {
|
const type = match[1];
|
||||||
let entries = response.filter(r => r.eventlist !== 'start' && r.eventlist !== 'Complete').map(r => ({ key: r.key, val: r.val }));
|
const extension = match[2];
|
||||||
for (let entry of entries) {
|
const target = match[3];
|
||||||
let stuff = entry.key.split('/');
|
|
||||||
let type = stuff[1];
|
forwards[`${type}/${extension}`] = target.replace(/\s+$/, '');
|
||||||
let ext = stuff[2];
|
|
||||||
console
|
|
||||||
respData.push({
|
|
||||||
extension: ext,
|
|
||||||
type: type,
|
|
||||||
target: entry.val
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).then(() => {
|
|
||||||
sock.getList({
|
|
||||||
action: 'DBGetTree',
|
|
||||||
family: 'CFU'
|
|
||||||
}).then(async (response) => {
|
|
||||||
let entries = response.filter(r => r.eventlist !== 'start' && r.eventlist !== 'Complete').map(r => ({ key: r.key, val: r.val }));
|
|
||||||
for (let entry of entries) {
|
|
||||||
let stuff = entry.key.split('/');
|
|
||||||
let type = stuff[1];
|
|
||||||
let ext = stuff[2];
|
|
||||||
console
|
|
||||||
respData.push({
|
|
||||||
extension: ext,
|
|
||||||
type: type,
|
|
||||||
target: entry.val
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).then(() => {
|
|
||||||
console.log(`Found ${respData.length} call forwards.`);
|
|
||||||
for (let cf of respData) {
|
|
||||||
// Check if forward target is anything in the 700-800 range, or is a number in the blocked list
|
|
||||||
if ((cf.target >= 700 && cf.target < 800) || blocked.includes(cf.target)) {
|
|
||||||
// Violation. Remove call forward from db.
|
|
||||||
console.log(`---> Violation found on extension ${cf.extension}. Removing call forward to ${cf.target}`);
|
|
||||||
sock.send({
|
|
||||||
action: 'DBDel',
|
|
||||||
family: cf.type,
|
|
||||||
key: cf.extension
|
|
||||||
}).then((resp) => {
|
|
||||||
console.log(`-----> Call forward removed successfully.`);
|
|
||||||
hook.send(`:no_entry: **Call Forward Removed** :no_entry:\nExtension **${cf.extension}** had a **${cfTypes[cf.type]}** call forward to **${cf.target}** The call forward has been removed.`);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search all forwards for any target that is between 700 and 800. If it exists, log to console and run `asterisk -x "database del CF[U/B] <ext>"` to delete it
|
||||||
|
for (const [key, target] of Object.entries(forwards)) {
|
||||||
|
const targetExt = parseInt(target, 10);
|
||||||
|
if ((targetExt >= 700 && targetExt < 800) || targetExt === 0) { // Also block forwards to 0 (operator line)
|
||||||
|
console.log(`Deleting forward ${key} to target ${target}`);
|
||||||
|
await hook.send(`Fuckass with extension ${key.split('/')[1]} tried to forward to ${target}. ${cfTypes[key.split('/')[0]]} Forward has been deleted.`);
|
||||||
|
const delCommand = `asterisk -x "database del ${key.replace('/', ' ')}"`;
|
||||||
|
const { error, stdout, stderr } = await runAsterisk(delCommand);
|
||||||
|
if (error) {
|
||||||
|
console.error(`Error executing command "${delCommand}": ${error}`);
|
||||||
|
} else {
|
||||||
|
console.log(`Successfully deleted forward ${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Unexpected error: ${err}`);
|
||||||
|
}
|
||||||
|
setTimeout(main, process.env.CHECK_INTERVAL * 1000); // Run every CHECK_INTERVAL seconds
|
||||||
};
|
};
|
||||||
setTimeout(main, 5000); // Repeat every 60 seconds
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const startup = async () => {
|
const startup = async () => {
|
||||||
sock.connect().then(() => {
|
// Run `asterisk -x "core show version"` to get the Asterisk version. If it fails, wait 10 seconds before running main again
|
||||||
console.log(sock.amiVersion)
|
exec('asterisk -x "core show version"', (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(`Error executing command: ${error}`);
|
||||||
|
console.log("Asterisk is not running. Retrying in 10 seconds...");
|
||||||
|
setTimeout(startup, 10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const version = stdout.trim();
|
||||||
|
console.log(`Asterisk version: ${version}`);
|
||||||
main();
|
main();
|
||||||
}).catch((err) => {
|
|
||||||
console.error('Error connecting to AMI:', err);
|
|
||||||
setTimeout(startup, 10000); // Retry after 10 seconds
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
package-lock.json
generated
10
package-lock.json
generated
|
|
@ -9,7 +9,6 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ami": "^1.0.0",
|
|
||||||
"discord.js": "^14.24.0",
|
"discord.js": "^14.24.0",
|
||||||
"dotenv": "^17.2.3"
|
"dotenv": "^17.2.3"
|
||||||
}
|
}
|
||||||
|
|
@ -202,15 +201,6 @@
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ami": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ami/-/ami-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-wkuxJl8ahQ4FYVwXvtJpQ7wuRUAqD30ueVpeJ1t5UyYqjzh+GtmrnaeHrXzzp+KO3ukhHZoMrsZlKB0j91oAlw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/discord-api-types": {
|
"node_modules/discord-api-types": {
|
||||||
"version": "0.38.31",
|
"version": "0.38.31",
|
||||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.31.tgz",
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.31.tgz",
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,8 @@
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"type": "module",
|
"type": "commonjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ami": "^1.0.0",
|
|
||||||
"discord.js": "^14.24.0",
|
"discord.js": "^14.24.0",
|
||||||
"dotenv": "^17.2.3"
|
"dotenv": "^17.2.3"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue