/*! * @license * Copyright Squiz Australia Pty Ltd. All Rights Reserved. */ import { SLACK_ALERT_LEVEL_ERROR, SLACK_ALERT_LEVEL_INFO, SLACK_ALERT_LEVEL_SUCCESS, SLACK_ALERT_LEVEL_WARNING, SlackAlertLevel, SlackAlertRequestBody, } from './types/SlackClient.types'; export class SlackClient { private static instance: SlackClient; protected static application: string; protected static environment: string; protected static region: string; protected static webhookUrl: string; /** * Initializes the Slack Client with the required environment vars. * @param {string} environment Deployment environment of application. * @param {string} region Region application is deployed to 'us' | 'uk' | 'au' as per AWS environment. * @param {string} webhookUrl Webhook URL for sending Slack messages. * @param {string} application Name of the application. */ public static initialize(environment = '', region = '', webhookUrl = '', application = ''): void { if (environment === '' || region === '' || webhookUrl === '' || application === '') { throw new Error('Failed to initialize SlackClient, environment vars not set'); } else { SlackClient.environment = `${environment[0].toUpperCase()}${environment.slice(1)}`; SlackClient.region = region.toUpperCase(); SlackClient.webhookUrl = webhookUrl; SlackClient.application = application; } } /** * The static method that controls the access to the singleton instance for Slack Client. * @returns {SlackClient} The singleton instance. */ public static getClient(): SlackClient { if (!SlackClient.instance) { SlackClient.instance = new SlackClient(); } return SlackClient.instance; } /** * Generate the body of the request for sending to Slack. * @param {SlackAlertLevel} level Level associated with alert. * @returns {string | null} The icon matching the alert level. */ public static getIcon = (level: SlackAlertLevel = SLACK_ALERT_LEVEL_INFO): string | null => { let icon = null; switch (level) { case SLACK_ALERT_LEVEL_ERROR: icon = ':alert:'; break; case SLACK_ALERT_LEVEL_WARNING: icon = '⚠️'; break; case SLACK_ALERT_LEVEL_INFO: icon = 'ℹ️'; break; case SLACK_ALERT_LEVEL_SUCCESS: icon = '✅'; break; default: icon = null; break; } return icon; }; /** * Generate the body of the request for sending to Slack. * @param {string} message Message to be sent to Slack channel. * @param {SlackAlertLevel} level Level associated with alert. * @returns {SlackAlertRequestBody} Slack alert request body. */ public static getRequestBody = ( message: string, level: SlackAlertLevel = SLACK_ALERT_LEVEL_INFO, ): SlackAlertRequestBody => { const icon = this.getIcon(level); const header = `${icon} *[${SlackClient.environment}] ${SlackClient.application} ${SlackClient.region}*`; const text = `${header}\n${message}`; const requestBody: SlackAlertRequestBody = { text, }; return requestBody; }; /** * Post a new message/alert to the Webhook URL. * @param {string} message Message to be sent. * @param {SlackAlertLevel} level Level associated with message. */ public sendAlert = async (message: string, level: SlackAlertLevel = SLACK_ALERT_LEVEL_INFO): Promise => { const requestBody = SlackClient.getRequestBody(message, level); try { const request = new Request(`${SlackClient.webhookUrl}`, { method: 'POST', body: JSON.stringify(requestBody), headers: { 'Content-Type': 'application/json', }, }); const response = await fetch(request); if (response.status !== 200) { // eslint-disable-next-line no-console console.log(`SlackClient failed with ${response.status} status`); return; } } catch (e) { /* eslint-disable-next-line no-console */ console.log(`Slack Client api call: ${e}`); throw e; } }; }