diff --git a/package-lock.json b/package-lock.json index 5b2013b..5c703fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,11 +13,13 @@ "discord.js": "^12.5.1", "eslint": "^7.16.0", "i18n": "^0.9.0", + "lodash": "^4.17.21", "mustache": "^4.1.0" }, "devDependencies": { "@types/axios": "^0.14.0", "@types/i18n": "^0.12.0", + "@types/lodash": "^4.14.182", "@types/mustache": "^4.1.1", "@types/node": "^14.0.1", "@typescript-eslint/eslint-plugin": "^3.0.0", @@ -155,6 +157,12 @@ "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "dev": true + }, "node_modules/@types/mustache": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.1.tgz", @@ -1762,10 +1770,9 @@ } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lowercase-keys": { "version": "1.0.1", @@ -2975,6 +2982,12 @@ "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, + "@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "dev": true + }, "@types/mustache": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.1.tgz", @@ -4180,10 +4193,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lowercase-keys": { "version": "1.0.1", diff --git a/package.json b/package.json index 8071321..1326c33 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,13 @@ "discord.js": "^12.5.1", "eslint": "^7.16.0", "i18n": "^0.9.0", + "lodash": "^4.17.21", "mustache": "^4.1.0" }, "devDependencies": { "@types/axios": "^0.14.0", "@types/i18n": "^0.12.0", + "@types/lodash": "^4.14.182", "@types/mustache": "^4.1.1", "@types/node": "^14.0.1", "@typescript-eslint/eslint-plugin": "^3.0.0", diff --git a/src/index.ts b/src/index.ts index d016161..0b5e379 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,12 +17,12 @@ import { sendDm } from './handlers/dm'; import { createActiveEventEmbed, createEmbedFromNewEvent } from './handlers/embeds'; import { PokemonEvents } from './models/events'; import { UrlWatcher } from './services/url-watcher'; -import { post, getWebhookData, WebhookData } from './services/utils'; +import { post, getWebhookData } from './services/utils'; import { ActiveEvent } from './types/events'; const client = new Client(); const urlToWatch = 'https://raw.githubusercontent.com/ccev/pogoinfo/v2/active/events.json'; -const intervalM = 1 * 60 * 1000; +const intervalM = 1 * 60 * 1000; // 60 seconds const NotAvailable = 'N/A'; let started = false; @@ -78,7 +78,7 @@ const createChannels = async (): Promise => { } }; -const createVoiceChannels = async (guildInfo: any, activeEvents: any): Promise => { +const createVoiceChannels = async (guildInfo: any, activeEvents: ActiveEvent[]): Promise => { // Check if event category id set for guild if (!guildInfo.eventsCategoryId) { return; @@ -210,41 +210,47 @@ UrlWatcher(urlToWatch, intervalM, async (): Promise => { // Delete previous event messages if set if (config.deletePreviousEvents) { // Get information returned about webhook - getWebhookData(webhook)?.then((webhookData: WebhookData | null) => { - // Check if - if (webhookData?.guild_id && webhookData?.channel_id) { - const guild = client.guilds.cache.get(webhookData.guild_id); - if (guild) { - const channel = guild.channels.cache.get(webhookData.channel_id); - try { - // Ensure we only try to delete messages from text channels - if (channel?.type == 'text') { - (channel as TextChannel).bulkDelete(100); - } - } catch (err) { - console.error('Error:', err); - } + const webhookData = await getWebhookData(webhook); + if (!webhookData) { + // Failed to get webhook result data from response + console.error(`Failed to get webhook data from ${webhook}`); + continue; + } + // Check if webhook result response has + if (!webhookData?.guild_id || !webhookData?.channel_id) { + // Missing required information from webhook data response + continue; + } + const guild = client.guilds.cache.get(webhookData.guild_id); + if (guild) { + const channel = guild.channels.cache.get(webhookData.channel_id); + try { + // Ensure we only try to delete messages from text channels + if (channel?.type == 'text') { + (channel as TextChannel).bulkDelete(100); } + } catch (err) { + // Fails if messages to delete are older than 14 days + console.error('Error:', err); } - }).catch(err => { - console.error(`Failed to get webhook data for ${webhook}: ${err}`); - }); + } } await post(webhook, payload); } } - // If bot token set we're logged into Discord bot - if (config.token) { + // Check that bot token and user ids list are set + if (config.token && config.userIds.length) { + // Create Discord embed that'll be sent to users const embed = await createActiveEventEmbed(event); // Send direct message to users for (const userId of config.userIds) { const member = client.users.cache.get(userId); - if (member == null) { + if (!member || member == null) { console.error(`Failed to get member by id ${userId}`); continue; } // Send DM info about event to Discord user - await sendDm(member, { embed: embed }); + await sendDm(member, { embed }); console.info(`New event direct message sent to ${member?.username} (${member?.id})`); } } diff --git a/src/services/url-watcher.ts b/src/services/url-watcher.ts index 43f2930..fea7314 100644 --- a/src/services/url-watcher.ts +++ b/src/services/url-watcher.ts @@ -1,6 +1,7 @@ 'use strict'; import { NoParamCallback } from 'fs'; +import { isEqual } from 'lodash'; import { get, deepEqual } from '../services/utils'; let previousData: any; @@ -15,7 +16,7 @@ export const UrlWatcher = (urlToWatch: string, interval: number, changedCallback previousData = data; return; } - if (!deepEqual(previousData, data)) { + if (!isEqual(previousData, data)) { previousData = data; changedCallback(null); } diff --git a/src/services/utils.ts b/src/services/utils.ts index f2ce3af..b59a982 100644 --- a/src/services/utils.ts +++ b/src/services/utils.ts @@ -1,7 +1,6 @@ 'use strict'; const axios = require('axios').default; - const UserAgent = 'PokemonGoEventWatcher'; /** @@ -32,18 +31,17 @@ export const get = async (url: string): Promise => { * @param {*} data */ export const post = async (url: string, data: any): Promise => { - const req = axios({ - url: url, + const req = await axios({ + url, method: 'POST', - data: data, + data, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': UserAgent, }, }); - //const req = await axios.post(url, data); - if (req.status !== 200 && req.statusText !== 'No Content') { + if (req.status !== 200 || (req.status !== 204 && req.statusText !== 'No Content')) { console.error(`Failed to post data to ${url}:`, req.statusText); return null; }