Merge pull request 'Merge feat-slash-outlook' (#10) from feat-slash-outlook into main

Reviewed-on: ChrisChrome/weather-bot#10
This commit is contained in:
Christopher Cookman 2024-05-19 10:29:52 -06:00
commit 2138bac3bb
2 changed files with 131 additions and 4 deletions

22
data/outlook.json Normal file
View file

@ -0,0 +1,22 @@
{
"storm": [
"https://www.spc.noaa.gov/products/outlook/day1otlk.gif",
"https://www.spc.noaa.gov/products/outlook/day2otlk.gif",
"https://www.spc.noaa.gov/products/outlook/day3otlk.gif",
"https://www.spc.noaa.gov/products/exper/day4-8/day4prob.gif",
"https://www.spc.noaa.gov/products/exper/day4-8/day5prob.gif",
"https://www.spc.noaa.gov/products/exper/day4-8/day6prob.gif",
"https://www.spc.noaa.gov/products/exper/day4-8/day7prob.gif",
"https://www.spc.noaa.gov/products/exper/day4-8/day8prob.gif"
],
"fire": [
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day1otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day2otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day3otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day4otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day5otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day6otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day7otlk_fire.gif",
"https://www.spc.noaa.gov/products/exper/fire_wx/imgs/day8otlk_fire.gif"
]
}

109
index.js
View file

@ -4,6 +4,7 @@ const config = require("./config.json");
const wfos = require("./data/wfos.json"); const wfos = require("./data/wfos.json");
const blacklist = require("./data/blacklist.json"); const blacklist = require("./data/blacklist.json");
const events = require("./data/events.json"); const events = require("./data/events.json");
const outlookURLs = require("./data/outlook.json");
const { client, xml } = require("@xmpp/client"); const { client, xml } = require("@xmpp/client");
const fetch = require("node-fetch"); const fetch = require("node-fetch");
const html = require("html-entities") const html = require("html-entities")
@ -39,6 +40,15 @@ const db = new sqlite3.Database("channels.db", (err) => {
// Random funcs // Random funcs
function toTitleCase(str) {
return str.replace(
/\w\S*/g,
function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}
);
}
const parseProductID = function (product_id) { const parseProductID = function (product_id) {
const [timestamp, station, wmo, pil] = product_id.split("-"); const [timestamp, station, wmo, pil] = product_id.split("-");
return { return {
@ -346,7 +356,7 @@ xmpp.on("stanza", (stanza) => {
// Send discord msg // Send discord msg
let embed = { let embed = {
description: `<t:${product_id.timestamp/1000}:T> <t:${product_id.timestamp/1000}:R> ${bodyData.string}`, description: `<t:${product_id.timestamp / 1000}:T> <t:${product_id.timestamp / 1000}:R> ${bodyData.string}`,
color: parseInt(config.priorityColors[evt.priority].replace("#", ""), 16) || 0x000000, color: parseInt(config.priorityColors[evt.priority].replace("#", ""), 16) || 0x000000,
timestamp: product_id.timestamp, timestamp: product_id.timestamp,
footer: { footer: {
@ -691,6 +701,69 @@ discord.on('ready', async () => {
"name": "userlist", "name": "userlist",
"description": "List all subscribed alerts for this user", "description": "List all subscribed alerts for this user",
"type": 1 "type": 1
},
{
"name": "outlook",
"description": "Get day 1-8 storm or fire outlook from the SPC",
"type": 1,
"options": [
{
"name": "day",
"description": "Day of outlook",
"type": 4,
"required": true,
"choices": [
{
"name": "Day 1",
"value": 0
},
{
"name": "Day 2",
"value": 1
},
{
"name": "Day 3",
"value": 2
},
{
"name": "Day 4",
"value": 3
},
{
"name": "Day 5",
"value": 4
},
{
"name": "Day 6",
"value": 5
},
{
"name": "Day 7",
"value": 6
},
{
"name": "Day 8",
"value": 7
}
]
},
{
"name": "type",
"description": "Type of outlook",
"type": 3,
"required": true,
"choices": [
{
"name": "Fire",
"value": "fire"
},
{
"name": "Storm",
"value": "storm"
}
]
}
]
} }
]; ];
@ -1147,8 +1220,39 @@ discord.on("interactionCreate", async (interaction) => {
} }
}); });
break; break;
case "outlook":
day = interaction.options.getInteger("day");
type = interaction.options.getString("type");
if (day < 0 || day > 7) return interaction.reply({ content: "Invalid day", ephemeral: true });
if (type !== "fire" && type !== "storm") return interaction.reply({ content: "Invalid type", ephemeral: true });
url = outlookURLs[type][day];
await interaction.deferReply();
fetch(url).then((res) => {
if (res.status !== 200) {
interaction.editReply({ content: "Failed to get outlook", ephemeral: true });
return;
}
// Returns image, send embed with image as attachment (we need to bypass discord cache)
res.buffer().then(async (buffer) => {
interaction.editReply({
embeds: [{
title: `${toTitleCase(type)} Outlook Day ${day + 1}`,
image: {
url: `attachment://${type}_${day}.png`
},
color: 0x00ff00
}],
files: [{
attachment: buffer,
name: `${type}_${day}.png`
}]
});
});
}).catch((err) => {
interaction.editReply({ content: "Failed to get outlook", ephemeral: true });
});
break;
} }
break;
case Discord.InteractionType.MessageComponent: case Discord.InteractionType.MessageComponent:
if (interaction.customId) { if (interaction.customId) {
const product_id = interaction.customId; const product_id = interaction.customId;
@ -1182,6 +1286,7 @@ discord.on("interactionCreate", async (interaction) => {
break; break;
} }
}); });
discord.on("guildCreate", (guild) => { discord.on("guildCreate", (guild) => {