From f41b4db6a02e39f9853e21f1f277ea230afd918e Mon Sep 17 00:00:00 2001 From: Andrea Brancaleoni Date: Wed, 15 May 2024 17:52:52 +0200 Subject: [PATCH] sendSlackMessage.js: debounce messages Debounce a message if it was already sent in the last 24 hours --- src/sendSlackMessage.js | 49 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/sendSlackMessage.js b/src/sendSlackMessage.js index e068d94f..cecee4bc 100644 --- a/src/sendSlackMessage.js +++ b/src/sendSlackMessage.js @@ -1,3 +1,22 @@ +async function findChannelId (web, name) { + let cursor = null + + while (true) { + const r = await web.conversations.list({ cursor }) + const f = r.channels.find(c => c.name === name || c.name === name.substring(1)) + + if (f) { + return f.id + } + + if (!r.response_metadata.next_cursor) { + throw new Error('channel not found') + } + + cursor = r.response_metadata.next_cursor + } +} + // send markdown message to slack channel export default async function sendSlackMessage ({ token = null, @@ -22,14 +41,21 @@ export default async function sendSlackMessage ({ if (debug) { console.log(`token.length: ${token.length}, channel: ${channel}, message: ${message}`) } - const { WebClient } = await import('@slack/web-api') const { markdownToBlocks } = await import('@tryfabric/mack') + const { WebClient } = await import('@slack/web-api') const web = new WebClient(token) let blocks = await markdownToBlocks(message) + // calculate the sha256 hash of the message + const crypto = await import('crypto') + const hash = crypto.createHash('sha256') + hash.update(message) + const hashHex = hash.digest('hex') + if (debug) { console.log(blocks) } + // slack blocks have a limit of 50 blocks, remove the last blocks if there are more if (blocks.length > 50) { blocks = blocks.slice(0, 49) blocks.push({ @@ -41,11 +67,30 @@ export default async function sendSlackMessage ({ }) } + // get the channel id + const channelId = await findChannelId(web, channel) + + // get last 50 messages from the channel, in the last day + const history = await web.conversations.history({ + channel: channelId, + limit: 50, + oldest: Date.now() / 1000 - 60 * 60 * 24 // a day ago + }) + + // debounce messages if the same message was sent in the last day + if (history.messages.some(m => m.metadata?.event_type === hashHex)) { + throw new Error('debounce message') + } + + const metadata = { event_type: hashHex, event_payload: { } } + + // send the message const result = await web.chat.postMessage({ username, text: `${username} alert`, channel, - blocks + blocks, + metadata }) if (debug) { console.log(`result: ${JSON.stringify(result)}`) }