|
|
|
@ -6,7 +6,7 @@ const wfos = require("./data/wfos.json");
|
|
|
|
|
const blacklist = require("./data/blacklist.json");
|
|
|
|
|
const events = require("./data/events.json");
|
|
|
|
|
const outlookURLs = require("./data/outlook.json");
|
|
|
|
|
const sattelites = require("./data/sattelites.json");
|
|
|
|
|
const satellites = require("./data/satellites.json");
|
|
|
|
|
const nwrstreams = {callsigns:{}};
|
|
|
|
|
const Jimp = require("jimp");
|
|
|
|
|
const { client, xml } = require("@xmpp/client");
|
|
|
|
@ -21,6 +21,7 @@ satMessages = {};
|
|
|
|
|
|
|
|
|
|
// Setup Discord
|
|
|
|
|
const discord = new Discord.Client({
|
|
|
|
|
|
|
|
|
|
intents: [
|
|
|
|
|
"Guilds",
|
|
|
|
|
"GuildVoiceStates",
|
|
|
|
@ -35,7 +36,6 @@ const rest = new REST({
|
|
|
|
|
version: '10'
|
|
|
|
|
}).setToken(config.discord.token);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Setup SQlite DB
|
|
|
|
|
const db = new sqlite3.Database("channels.db", (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
@ -360,6 +360,16 @@ xmpp.on("stanza", (stanza) => {
|
|
|
|
|
evt = { name: "Unknown", priority: 3 }
|
|
|
|
|
console.log(`${colors.red("[ERROR]")} Unknown event type: ${product_id.pil.substring(0, 3)}. Fix me`);
|
|
|
|
|
console.log(`${colors.magenta("[DEBUG]")} ${bodyData.string}`)
|
|
|
|
|
const logChannel = discord.guilds.cache.get(config.discord.mainGuild).channels.cache.get(config.discord.logChannel);
|
|
|
|
|
logChannel.send({
|
|
|
|
|
embeds: [
|
|
|
|
|
{
|
|
|
|
|
title: "Unknown Event Type",
|
|
|
|
|
description: `Unknown event type: ${product_id.pil.substring(0, 3)}. Please check the logs for more details.`,
|
|
|
|
|
color: 0xff0000
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
evt.code = product_id.pil.substring(0, 3);
|
|
|
|
@ -367,13 +377,14 @@ xmpp.on("stanza", (stanza) => {
|
|
|
|
|
const now = new Date();
|
|
|
|
|
const diff = (now - product_id.timestamp) / 1000 / 60;
|
|
|
|
|
if (diff > 3) return;
|
|
|
|
|
if (config.debug >= 1) console.log(`${colors.magenta("[DEBUG]")} New message from ${fromChannel}`);
|
|
|
|
|
// if (config.debug >= 1) console.log(`${colors.magenta("[DEBUG]")} New message from ${fromChannel}`);
|
|
|
|
|
console.log(`${colors.cyan("[INFO]")} ${getWFOByRoom(fromChannel).location} - ${evt.text} - ${product_id.timestamp}`);
|
|
|
|
|
messages++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle NTFY
|
|
|
|
|
if (config.ntfy.enabled) {
|
|
|
|
|
if (config.debug >= 1) console.log(`${colors.magenta("[DEBUG]")} Sending NTFY for ${config.ntfy.prefix}${fromChannel}`)
|
|
|
|
|
//if (config.debug >= 1) console.log(`${colors.magenta("[DEBUG]")} Sending NTFY for ${config.ntfy.prefix}${fromChannel}`)
|
|
|
|
|
ntfyBody = {
|
|
|
|
|
"topic": `${config.ntfy.prefix}${fromChannel}`,
|
|
|
|
|
"message": bodyData.string,
|
|
|
|
@ -391,7 +402,7 @@ xmpp.on("stanza", (stanza) => {
|
|
|
|
|
'Authorization': `Bearer ${config.ntfy.token}`
|
|
|
|
|
}
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
if (config.debug >= 1) console.log(`${colors.magenta("[DEBUG]")} NTFY sent for ${config.ntfy.prefix}${fromChannel} with status ${res.status} ${res.statusText}`);
|
|
|
|
|
//if (config.debug >= 1) console.log(`${colors.magenta("[DEBUG]")} NTFY sent for ${config.ntfy.prefix}${fromChannel} with status ${res.status} ${res.statusText}`);
|
|
|
|
|
if (res.status !== 200) console.log(`${colors.red("[ERROR]")} NTFY failed for ${config.ntfy.prefix}${fromChannel} with status ${res.status} ${res.statusText}`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -447,7 +458,7 @@ xmpp.on("stanza", (stanza) => {
|
|
|
|
|
console.log(`${colors.red("[ERROR]")} ${err.message}`);
|
|
|
|
|
}
|
|
|
|
|
if (!rows) return; // No channels to alert
|
|
|
|
|
rows.forEach((row) => {
|
|
|
|
|
rows.forEach(async (row) => {
|
|
|
|
|
// Get Filters as arrays
|
|
|
|
|
if (!row.filterEvt) row.filterEvt = "";
|
|
|
|
|
if (!row.filter) row.filter = "";
|
|
|
|
@ -473,6 +484,54 @@ xmpp.on("stanza", (stanza) => {
|
|
|
|
|
console.error(err);
|
|
|
|
|
}).then((msg) => {
|
|
|
|
|
if (msg.channel.type === Discord.ChannelType.GuildAnnouncement) msg.crosspost();
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
console.log(`${colors.yellow("[WARN]")} Failed to send message to ${channel.guild.name}/${channel.name} (${channel.guild.id}/${channel.id})`);
|
|
|
|
|
const logChannel = discord.guilds.cache.get(config.discord.mainGuild).channels.cache.get(config.discord.logChannel);
|
|
|
|
|
logChannel.send({
|
|
|
|
|
embeds: [
|
|
|
|
|
{
|
|
|
|
|
title: "Failed to send message",
|
|
|
|
|
description: `There is likely an issue with permissions. Please notify the server owner if possible.
|
|
|
|
|
Guild: ${channel.guild.name} (${channel.guild.id})
|
|
|
|
|
Channel: ${channel.name} (${channel.id})
|
|
|
|
|
Guild Owner: <@${channel.guild.ownerId}> (${channel.guild.ownerId})
|
|
|
|
|
Sub Info: \`\`\`json\n${JSON.stringify(row)}\`\`\``,
|
|
|
|
|
color: 0xff0000
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
discord.users.fetch(channel.guild.ownerId).then((user) => {
|
|
|
|
|
user.send({
|
|
|
|
|
embeds: [
|
|
|
|
|
{
|
|
|
|
|
title: "Issue with your subscribed channel.",
|
|
|
|
|
description: `There is likely an issue with permissions. Please check that I can send messages in <#${channel.id}>\nYour subscription has been removed, and you will need to resubscribe to get alerts.`,
|
|
|
|
|
color: 0xff0000,
|
|
|
|
|
fields: [
|
|
|
|
|
{
|
|
|
|
|
name: "Guild",
|
|
|
|
|
value: `${channel.guild.name} (${channel.guild.id})`
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Channel",
|
|
|
|
|
value: `${channel.name} (${channel.id})`
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
console.log(`${colors.red("[ERROR]")} Failed to send message to ${channel.guild.ownerId}`);
|
|
|
|
|
}).then(() => {
|
|
|
|
|
if (channel.guildId == config.discord.mainGuild) return;
|
|
|
|
|
db.run(`DELETE FROM channels WHERE channelid = ? AND iemchannel = ?`, [channel.id, fromChannel], (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err.message);
|
|
|
|
|
}
|
|
|
|
|
console.log(`${colors.cyan("[INFO]")} Deleted channel ${channel.id} from database`);
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}).catch((err) => {
|
|
|
|
@ -518,6 +577,27 @@ xmpp.on("stanza", (stanza) => {
|
|
|
|
|
thisMsg.content = row.custommessage || null;
|
|
|
|
|
user.send(thisMsg).catch((err) => {
|
|
|
|
|
console.error(err);
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
console.log(`${colors.yellow("[WARN]")} Failed to send message to ${user.tag} (${user.id})`);
|
|
|
|
|
const logChannel = discord.guilds.cache.get(config.discord.mainGuild).channels.cache.get(config.discord.logChannel);
|
|
|
|
|
logChannel.send({
|
|
|
|
|
embeds: [
|
|
|
|
|
{
|
|
|
|
|
title: "Failed to send DM",
|
|
|
|
|
description: `User may have DMs disabled, or bot doesnt' share a server anymore!.
|
|
|
|
|
User: ${user.tag} (${user.id})
|
|
|
|
|
Sub Info: \`\`\`json\n${JSON.stringify(row)}\`\`\``,
|
|
|
|
|
color: 0xff0000
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}).then(() => {
|
|
|
|
|
db.run(`DELETE FROM userAlerts WHERE userid = ? AND iemchannel = ?`, [user.id, fromChannel], (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err.message);
|
|
|
|
|
}
|
|
|
|
|
console.log(`${colors.cyan("[INFO]")} Deleted user ${user.id} from database`);
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}).catch((err) => {
|
|
|
|
@ -624,19 +704,19 @@ discord.on('ready', async () => {
|
|
|
|
|
commands = require("./data/commands.json");
|
|
|
|
|
// Add dynamic commands (based on datas files)
|
|
|
|
|
satCommand = {
|
|
|
|
|
"name": "sattelite",
|
|
|
|
|
"description": "Get the latest sattelite images from a given sattelite",
|
|
|
|
|
"name": "satellite",
|
|
|
|
|
"description": "Get the latest satellite images from a given satellite",
|
|
|
|
|
"options": [
|
|
|
|
|
{
|
|
|
|
|
"name": "sattelite",
|
|
|
|
|
"description": "The sattelite to get images from",
|
|
|
|
|
"name": "satellite",
|
|
|
|
|
"description": "The satellite to get images from",
|
|
|
|
|
"type": 3,
|
|
|
|
|
"required": true,
|
|
|
|
|
"choices": []
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
for (const key in sattelites) {
|
|
|
|
|
for (const key in satellites) {
|
|
|
|
|
satCommand.options[0].choices.push({
|
|
|
|
|
"name": key,
|
|
|
|
|
"value": key
|
|
|
|
@ -785,21 +865,26 @@ discord.on("interactionCreate", async (interaction) => {
|
|
|
|
|
filterEvt = interaction.options.getString("filterevt") || null;
|
|
|
|
|
message = interaction.options.getString("message") || null;
|
|
|
|
|
if (interaction.inGuild()) {
|
|
|
|
|
db.get(`SELECT * FROM channels WHERE channelid = ? AND iemchannel = ?`, [interaction.channel.id, room], (err, row) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err.message);
|
|
|
|
|
interaction.reply({ content: "Failed to subscribe to room", ephemeral: true });
|
|
|
|
|
} else if (row) {
|
|
|
|
|
return interaction.reply({ content: `Already subscribed to \`${getWFOByRoom(room).location}\`\nIf you want to update a subscribtion, please unsubscribe and resubscribe. This will be made a command eventually.`, ephemeral: true });
|
|
|
|
|
}
|
|
|
|
|
db.run(`INSERT INTO channels (channelid, iemchannel, custommessage, filter, filterEvt, minPriority) VALUES (?, ?, ?, ? ,? ,?)`, [interaction.channel.id, room, message, filter, filterEvt, minPriority], (err) => {
|
|
|
|
|
interaction.channel.send("Permission check").then((msg) => {
|
|
|
|
|
msg.delete();
|
|
|
|
|
db.get(`SELECT * FROM channels WHERE channelid = ? AND iemchannel = ?`, [interaction.channel.id, room], (err, row) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err.message);
|
|
|
|
|
interaction.reply({ content: "Failed to subscribe to room", ephemeral: true });
|
|
|
|
|
} else {
|
|
|
|
|
interaction.reply({ content: `Subscribed to \`${getWFOByRoom(room).location}\``, ephemeral: true });
|
|
|
|
|
} else if (row) {
|
|
|
|
|
return interaction.reply({ content: `Already subscribed to \`${getWFOByRoom(room).location}\`\nIf you want to update a subscribtion, please unsubscribe and resubscribe. This will be made a command eventually.`, ephemeral: true });
|
|
|
|
|
}
|
|
|
|
|
db.run(`INSERT INTO channels (channelid, iemchannel, custommessage, filter, filterEvt, minPriority) VALUES (?, ?, ?, ? ,? ,?)`, [interaction.channel.id, room, message, filter, filterEvt, minPriority], (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err.message);
|
|
|
|
|
interaction.reply({ content: "Failed to subscribe to room", ephemeral: true });
|
|
|
|
|
} else {
|
|
|
|
|
interaction.reply({ content: `Subscribed to \`${getWFOByRoom(room).location}\``, ephemeral: true });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
interaction.reply({ content: "Failed to subscribe to room. Bot does not have send message permissions here!", ephemeral: true });
|
|
|
|
|
});
|
|
|
|
|
} else { // We're in a DM
|
|
|
|
|
db.get(`SELECT * FROM userAlerts WHERE userid = ? AND iemchannel = ?`, [interaction.user.id, room], (err, row) => {
|
|
|
|
@ -1270,18 +1355,18 @@ discord.on("interactionCreate", async (interaction) => {
|
|
|
|
|
console.error(err);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "sattelite": // Get satellite images
|
|
|
|
|
sat = interaction.options.getString("sattelite");
|
|
|
|
|
if (!sattelites[sat]) return interaction.reply({ content: "Invalid satellite", ephemeral: true });
|
|
|
|
|
case "satellite": // Get satellite images
|
|
|
|
|
sat = interaction.options.getString("satellite");
|
|
|
|
|
if (!satellites[sat]) return interaction.reply({ content: "Invalid satellite", ephemeral: true });
|
|
|
|
|
// Fetch all the images
|
|
|
|
|
productOptions = []
|
|
|
|
|
await (() => {
|
|
|
|
|
for (const key in sattelites[sat].products) {
|
|
|
|
|
// make a discord customid safe id for the product name, add it to the sattelites object
|
|
|
|
|
sattelites[sat].products[key].customid = key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
|
|
|
for (const key in satellites[sat].products) {
|
|
|
|
|
// make a discord customid safe id for the product name, add it to the satellites object
|
|
|
|
|
satellites[sat].products[key].customid = key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
|
|
|
productOptions.push({
|
|
|
|
|
label: key,
|
|
|
|
|
value: sattelites[sat].products[key].customid
|
|
|
|
|
value: satellites[sat].products[key].customid
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
console.log(JSON.stringify(productOptions, null, 2))
|
|
|
|
@ -1364,7 +1449,7 @@ discord.on("interactionCreate", async (interaction) => {
|
|
|
|
|
sat = satData.sat
|
|
|
|
|
product = interaction.values[0];
|
|
|
|
|
// find the original product name
|
|
|
|
|
product_name = Object.keys(sattelites[sat].products).find(key => sattelites[sat].products[key].customid === product);
|
|
|
|
|
product_name = Object.keys(satellites[sat].products).find(key => satellites[sat].products[key].customid === product);
|
|
|
|
|
imageOptions = []
|
|
|
|
|
satMessages[interaction.customId.split("|")[1]] = {
|
|
|
|
|
sat,
|
|
|
|
@ -1373,13 +1458,13 @@ discord.on("interactionCreate", async (interaction) => {
|
|
|
|
|
images: {}
|
|
|
|
|
}
|
|
|
|
|
await (() => {
|
|
|
|
|
// for key, value in sattelites[sat].products[product_name]
|
|
|
|
|
// for key, value in satellites[sat].products[product_name]
|
|
|
|
|
console.log(product_name)
|
|
|
|
|
for (const key in sattelites[sat].products[product_name]) {
|
|
|
|
|
// make a discord customid safe id for the product name, add it to the sattelites object
|
|
|
|
|
//console.log(sattelites[sat].products[product_name])
|
|
|
|
|
for (const key in satellites[sat].products[product_name]) {
|
|
|
|
|
// make a discord customid safe id for the product name, add it to the satellites object
|
|
|
|
|
//console.log(satellites[sat].products[product_name])
|
|
|
|
|
if (key === "customid") continue;
|
|
|
|
|
satMessages[interaction.customId.split("|")[1]].images[key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()] = sattelites[sat].products[product_name][key];
|
|
|
|
|
satMessages[interaction.customId.split("|")[1]].images[key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()] = satellites[sat].products[product_name][key];
|
|
|
|
|
imageOptions.push({
|
|
|
|
|
label: key,
|
|
|
|
|
value: key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()
|
|
|
|
@ -1505,6 +1590,8 @@ discord.on("guildCreate", async (guild) => {
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}).catch((err) => {
|
|
|
|
|
console.log(`${colors.red("[ERROR]")} Failed to send message to user ${user.id}: ${err.message}`);
|
|
|
|
|
})
|
|
|
|
|
channel.send({
|
|
|
|
|
embeds: [
|
|
|
|
@ -1583,5 +1670,7 @@ process.on("uncaughtException", (error) => {
|
|
|
|
|
return;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Login to discord
|
|
|
|
|
discord.login(config.discord.token);
|