import axios, { AxiosError } from 'axios'; import { WebClient } from '@slack/web-api'; import { generateWebClient } from './webclient-factory'; import { ConnectionStatus } from '../interfaces/connection-status'; /** * Check whether the HTTP server responds or not. * * @param serverUri Server URI to connect * @returns AxiosError when error is occured */ export const connectToHttpServer = async(serverUri: string): Promise => { try { await axios.get(serverUri, { maxRedirects: 0, timeout: 3000 }); } catch (err) { return err as AxiosError; } }; /** * Check whether the Slack API server responds or not. * * @returns AxiosError when error is occured */ export const connectToSlackApiServer = async(): Promise => { return connectToHttpServer('https://slack.com/api/'); }; /** * Test Slack API * @param client */ const testSlackApiServer = async(client: WebClient): Promise => { const result = await client.api.test(); if (!result.ok) { throw new Error(result.error); } return result; }; const checkSlackScopes = (result: any) => { const slackScopes = result.response_metadata.scopes; const correctScopes = ['commands', 'team:read', 'chat:write']; if (correctScopes.every(e => slackScopes.includes(e))) { return; } throw new Error('Scope error'); }; /** * Retrieve Slack workspace name * @param client */ const retrieveWorkspaceName = async(client: WebClient): Promise => { const result = await client.team.info(); if (!result.ok) { throw new Error(result.error); } return (result as any).team?.name; }; /** * Get token string to ConnectionStatus map * @param tokens Array of bot OAuth token * @returns */ export const getConnectionStatuses = async(tokens: string[]): Promise<{[key: string]: ConnectionStatus}> => { const map = tokens .reduce>>( async(acc, token) => { const client = generateWebClient(token); const status: ConnectionStatus = {}; try { // try to connect await testSlackApiServer(client); // retrieve workspace name status.workspaceName = await retrieveWorkspaceName(client); } catch (err) { status.error = err; } (await acc).set(token, status); return acc; }, // define initial accumulator Promise.resolve(new Map()), ); // convert to object return Object.fromEntries(await map); }; /** * @param token bot OAuth token * @returns */ export const testToSlack = async(token:string): Promise => { const client = generateWebClient(token); const res = await testSlackApiServer(client); await checkSlackScopes(res); };