From 8d3ffb83297a634c2176a85c20dc07d6723a1f4f Mon Sep 17 00:00:00 2001 From: klords Date: Wed, 28 Apr 2021 02:58:04 -0700 Subject: [PATCH] fix(captcha): use Slack captcha handler token when provided --- src/messaging/discord.ts | 5 ++- src/messaging/slack.ts | 87 ++++++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/src/messaging/discord.ts b/src/messaging/discord.ts index 3ddea466c9..31de6c2cba 100644 --- a/src/messaging/discord.ts +++ b/src/messaging/discord.ts @@ -114,6 +114,8 @@ export async function sendDMAsync( } catch (error: unknown) { logger.error("✖ couldn't send discord DM", error); } + } else { + logger.warn("✖ couldn't send discord DM, missing configuration"); } return; } @@ -122,6 +124,7 @@ export async function getDMResponseAsync( botMessage: Discord.Message | undefined, timeout: number ): Promise { + if (!botMessage) return ''; const iterations = Math.max(Math.floor(timeout / pollInterval), 1); let iteration = 0; const client = await getDiscordClientAsync(); @@ -195,7 +198,7 @@ async function getDiscordClientAsync() { } async function getDMChannelAsync(client?: Discord.Client) { - if (!dmChannelInstance && userId && !!client) { + if (!dmChannelInstance && userId && client) { const user = await new Discord.User(client, { id: userId, }).fetch(); diff --git a/src/messaging/slack.ts b/src/messaging/slack.ts index dfd4d0e6ee..2bc370a16f 100644 --- a/src/messaging/slack.ts +++ b/src/messaging/slack.ts @@ -3,19 +3,35 @@ import {Print, logger} from '../logger'; import {WebClient} from '@slack/web-api'; import {config} from '../config'; -const {channel, token} = config.notifications.slack; -const {pollInterval, responseTimeout, userId} = config.captchaHandler; -const web = new WebClient(token); +type ClientTypes = 'service' | 'captcha'; +type ClientMap = { + [clientType in ClientTypes]: T; +}; -export function sendSlackMessage(link: Link, store: Store) { - if (channel && token) { +const {channel} = config.notifications.slack; +const {pollInterval, responseTimeout, userId} = config.captchaHandler; +const clients: ClientMap = { + service: undefined, + captcha: undefined, +}; +const tokens: ClientMap = { + service: config.notifications.slack.token, + captcha: config.captchaHandler.token, +}; + +export function sendSlackMessage( + link: Link, + store: Store, + client: WebClient = getClient() +) { + if (channel && client.token) { logger.debug('↗ sending slack message'); (async () => { const givenUrl = link.cartUrl ? link.cartUrl : link.url; try { - const result = await web.chat.postMessage({ + const result = await client.chat.postMessage({ channel: channel.replace('#', ''), text: `${Print.inStock(link, store)}\n${givenUrl}`, }); @@ -33,12 +49,15 @@ export function sendSlackMessage(link: Link, store: Store) { } } -export async function sendDMAsync(payload: string) { - if (userId && token) { +export async function sendDMAsync( + payload: string, + client: WebClient = getClient() +) { + if (userId && client.token) { logger.debug('↗ sending slack DM'); try { - const dmResult = await web.conversations.open({ + const dmResult = await client.conversations.open({ users: `${userId}`, return_im: false, }); @@ -48,8 +67,10 @@ export async function sendDMAsync(payload: string) { return; } - const result = await web.chat.postMessage({ - channel: (dmResult as any).channel?.id.replace('#', ''), + const dmChannel = (dmResult as any).channel?.id.replace('#', ''); + logger.debug(`sending DM to channel id ${dmChannel}...`); + const result = await client.chat.postMessage({ + channel: dmChannel, text: payload, }); @@ -59,19 +80,22 @@ export async function sendDMAsync(payload: string) { } logger.info('✔ slack DM sent'); - - return {ts: (result as any).ts, channel: (result as any).channel}; + return result as any; } catch (error: unknown) { logger.error("✖ couldn't send slack DM", error); } + } else { + logger.warn("✖ couldn't send slack DM, missing configuration"); } return; } export async function getDMResponseAsync( - dmId: any, - timeout: number + botMessage: any, + timeout: number, + client: WebClient = getClient() ): Promise { + if (!botMessage || !client.token) return ''; const iterations = Math.max(Math.floor(timeout / pollInterval), 1); let iteration = 0; return new Promise(resolve => { @@ -84,9 +108,9 @@ export async function getDMResponseAsync( try { iteration++; - const threadResult = await web.conversations.replies({ - channel: dmId.channel, - ts: dmId.ts, + const threadResult = await client.conversations.replies({ + channel: botMessage.channel, + ts: botMessage.ts, }); if (!threadResult.ok) { @@ -106,9 +130,9 @@ export async function getDMResponseAsync( .sort((a: any, b: any) => Number(b.ts) - Number(a.ts))[0]; if (!lastUserMessage) { if (iteration >= iterations) { - await web.chat.postMessage({ - channel: dmId.channel, - thread_ts: dmId.ts, + await client.chat.postMessage({ + channel: botMessage.channel, + thread_ts: botMessage.ts, text: 'Timed out waiting for response... :crying_cat_face:', }); logger.error('✖ no response from user'); @@ -117,8 +141,8 @@ export async function getDMResponseAsync( } else { response = lastUserMessage.text; - await web.reactions.add({ - channel: dmId.channel, + await client.reactions.add({ + channel: botMessage.channel, name: 'white_check_mark', timestamp: lastUserMessage.ts, }); @@ -140,6 +164,19 @@ export async function getSlackCaptchaInputAsync( payload: string, timeout?: number ): Promise { - const dmId = await sendDMAsync(payload); - return await getDMResponseAsync(dmId, timeout || responseTimeout); + const captchaClient = getClient('captcha'); + const botMessage = await sendDMAsync(payload, captchaClient); + return await getDMResponseAsync( + botMessage, + timeout || responseTimeout, + captchaClient + ); +} + +function getClient(clientType: ClientTypes = 'service'): WebClient { + if (!clients[clientType]) { + const token = tokens[clientType] || tokens['service']; // attempt to fall back to service token + clients[clientType] = new WebClient(token); + } + return clients[clientType] as WebClient; }