A start
This commit is contained in:
parent
b349149176
commit
e3398549e9
76
commands.json
Normal file
76
commands.json
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "register",
|
||||||
|
"description": "Register for a new account number",
|
||||||
|
"type": 1,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "phone_number",
|
||||||
|
"description": "The 10 digit US phone number to call when the system is triggered",
|
||||||
|
"type": 3,
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "verify",
|
||||||
|
"description": "Verify the phone number on a new account",
|
||||||
|
"type": 1,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "verification_code",
|
||||||
|
"description": "The 6 digit verification code sent to the phone number",
|
||||||
|
"type": 3,
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "update",
|
||||||
|
"description": "Update the phone number on an account",
|
||||||
|
"type": 1,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "account_number",
|
||||||
|
"description": "The account number to update",
|
||||||
|
"type": 3,
|
||||||
|
"required": true,
|
||||||
|
"autocomplete": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phone_number",
|
||||||
|
"description": "The 10 digit US phone number to call when the system is triggered",
|
||||||
|
"type": 3,
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deactivate",
|
||||||
|
"description": "Deactivate an account",
|
||||||
|
"type": 1,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "account_number",
|
||||||
|
"description": "The account number to deactivate",
|
||||||
|
"type": 3,
|
||||||
|
"required": true,
|
||||||
|
"autocomplete": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "resend",
|
||||||
|
"description": "Resend the verification code to a phone number",
|
||||||
|
"type": 1,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "phone_number",
|
||||||
|
"description": "The 10 digit US phone number to call when the system is triggered",
|
||||||
|
"type": 3,
|
||||||
|
"required": true,
|
||||||
|
"autocomplete": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
151
index.js
151
index.js
|
@ -0,0 +1,151 @@
|
||||||
|
const colors = require("colors");
|
||||||
|
require("dotenv").config();
|
||||||
|
const fs = require("fs");
|
||||||
|
const express = require("express");
|
||||||
|
const app = express();
|
||||||
|
const port = process.env.PORT || 3000;
|
||||||
|
const { exec } = require("child_process");
|
||||||
|
const sqlite3 = require("sqlite3").verbose();
|
||||||
|
const db = new sqlite3.Database("./database.db");
|
||||||
|
// Find all migrations .sql files in ./migrations, execute them in order
|
||||||
|
db.on("open", () => {
|
||||||
|
console.log(`${colors.cyan("[DB]")} Connected to the database`);
|
||||||
|
fs.readdirSync("./migrations").forEach((file) => {
|
||||||
|
if (file.endsWith(".sql")) {
|
||||||
|
const migration = fs.readFileSync(`./migrations/${file}`, "utf8");
|
||||||
|
db.run(migration);
|
||||||
|
console.log(`${colors.cyan("[DB]")} ${file} ${colors.green("executed")}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const Discord = require("discord.js");
|
||||||
|
const {
|
||||||
|
REST,
|
||||||
|
Routes
|
||||||
|
} = require('discord.js');
|
||||||
|
const { title } = require("process");
|
||||||
|
const rest = new REST({
|
||||||
|
version: '10'
|
||||||
|
}).setToken(process.env.DISCORD_TOKEN);
|
||||||
|
const client = new Discord.Client({
|
||||||
|
intents: [
|
||||||
|
"Guilds"
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Vars
|
||||||
|
|
||||||
|
var handledTransactions = [];
|
||||||
|
|
||||||
|
// Funcs
|
||||||
|
|
||||||
|
// runCommand(command) // Run a shell command and return the output
|
||||||
|
function runCommand(command) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(command, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(`exec error: ${error}`);
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve(stdout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// generateAccountNumber() // Returns a random 10 digit number, checks if it already exists in the database, and loops until it gets one that doesn't exist
|
||||||
|
function generateAccountNumber() {
|
||||||
|
let accountNumber = Math.floor(Math.random() * 10000000000);
|
||||||
|
db.get("SELECT * FROM accounts WHERE id = ?", accountNumber, (err, row) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else if (row) {
|
||||||
|
accountNumber = generateAccountNumber();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return accountNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateTransactionNumber() // Returns a random 10 digit number
|
||||||
|
function generateTransactionNumber() {
|
||||||
|
return Math.floor(Math.random() * 10000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendAlert(accountNumber, transaction, placeName, systemName, zoneNumber, zoneName, event) {
|
||||||
|
if (handledTransactions.includes(transaction)) {
|
||||||
|
return; // Duplicate transaction
|
||||||
|
}
|
||||||
|
handledTransactions.push(transaction);
|
||||||
|
// Check if the account exists and is verified
|
||||||
|
db.get("SELECT * FROM accounts WHERE id = ? AND verified = 1", accountNumber, (err, row) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else if (row) {
|
||||||
|
// Account exists and is verified
|
||||||
|
// Send the alert
|
||||||
|
runCommand(`flite -t "Hello. This is an automated call from KCA SecuriNet Monitoring. ${systemName} has reported an ${event} at ${placeName} in ${zoneNumber}, ${zoneName}" -o /tmp/${transaction}.wav`).then((output) => {
|
||||||
|
runCommand(`ffmpeg -y -i /tmp/${transaction}.wav -ar 8000 -ac 1 -c:a pcm_s16le /tmp/${transaction}-ast.wav`).then(() => {
|
||||||
|
runCommand(`rm /tmp/${transaction}.wav`)
|
||||||
|
runCommand(`/var/lib/asterisk/bin/originate ${row.phone} roblox.s.1 0 0 /tmp/test-asterisk "Ik5vb24gQ2hpbWUiIDw+"`).then(() => {
|
||||||
|
console.log(`Alert sent to ${row.phone}`);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
// Account does not exist or is not verified
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
sendAlert(1961600249, generateTransactionNumber(), "Test Place", "Test System", 1, "Test Zone", "alarm");
|
||||||
|
client.on("ready", async () => {
|
||||||
|
console.log(`${colors.cyan("[Discord]")} Logged in as ${client.user.tag}`);
|
||||||
|
|
||||||
|
const commands = require("./commands.json");
|
||||||
|
//Register commands
|
||||||
|
await (async () => {
|
||||||
|
try {
|
||||||
|
console.log(`${colors.cyan("[Discord]")} Registering Commands...`)
|
||||||
|
//Global
|
||||||
|
await rest.put(Routes.applicationCommands(client.user.id), { body: commands })
|
||||||
|
console.log(`${colors.cyan("[Discord]")} Successfully registered commands. Took ${colors.green((Date.now() - startTime) / 1000)} seconds.`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`${colors.cyan("[EXPRESS]")} Listening on ${port}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("interactionCreate", async (interaction) => {
|
||||||
|
if (!interaction.isCommand()) return;
|
||||||
|
|
||||||
|
switch (interaction.commandName) {
|
||||||
|
case "register":
|
||||||
|
// check that the user doesnt have any unverified accounts already (check discord_id and verified)
|
||||||
|
db.get("SELECT * FROM accounts WHERE discord_id = ? AND verified = 0", interaction.user.id, (err, row) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else if (row) {
|
||||||
|
interaction.reply("You already have an unverified account. Please verify it before creating a new one.");
|
||||||
|
} else {
|
||||||
|
const accountNumber = generateAccountNumber();
|
||||||
|
db.run("INSERT INTO accounts (id, discord_id) VALUES (?, ?)", accountNumber, interaction.user.id, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
interaction.reply(`Account created with number ${accountNumber}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
startTime = new Date();
|
||||||
|
client.login(process.env.DISCORD_TOKEN);
|
9
migrations/1 - Init.sql
Normal file
9
migrations/1 - Init.sql
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS 'accounts' (
|
||||||
|
'id' INTEGER PRIMARY KEY,
|
||||||
|
'phone' TEXT NOT NULL,
|
||||||
|
--'discord_webhook' TEXT NOT NULL,
|
||||||
|
'verified' INTEGER NOT NULL DEFAULT 0,
|
||||||
|
'verification_code' TEXT,
|
||||||
|
'code_sent_at' TEXT,
|
||||||
|
'discord_id' TEXT
|
||||||
|
)
|
2350
package-lock.json
generated
Normal file
2350
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -7,5 +7,12 @@
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "GPL-3.0-or-later"
|
"license": "GPL-3.0-or-later",
|
||||||
|
"dependencies": {
|
||||||
|
"colors": "^1.4.0",
|
||||||
|
"discord.js": "^14.15.3",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"express": "^4.19.2",
|
||||||
|
"sqlite3": "^5.1.7"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue