import { Logger, MethodContext, RequestContext, createMethodContext } from '../logging';
import { jsonifyError } from '../types';
import { TelegramConfig, Report } from '../helpers';
import { axiosPost } from './mockable';
/**
* Creates a formatted message for Telegram alerts
* @param report The report to create the message from
* @param isResolved Whether the alert is being resolved
* @returns Formatted message string
*/
export const createTelegramMessage = (report: Report, isResolved: boolean): string => {
const { timestamp, reason, ids, type, severity, env } = report;
const status = isResolved ? 'Resolved!' : 'Alert!';
return `
Monitor ${env} ${severity} - ${status}
Reason: ${reason}
Type: ${type}
Environment: ${env}
Timestamp: ${new Date(timestamp).toISOString()}
Identifiers: ${ids.join(', ')}
`;
};
/**
* Validates Telegram configuration
* @param telegram The telegram config
* @param logger The logger instance
* @param requestContext The request context
* @param methodContext The method context
* @returns boolean indicating if the config is valid
*/
const validateTelegramConfig = (
telegram: TelegramConfig,
logger: Logger,
requestContext: RequestContext,
methodContext: MethodContext,
): boolean => {
if (!telegram) {
logger.warn('Telegram config not set', requestContext, methodContext);
return false;
}
if (!telegram.apiKey || !telegram.chatId) {
logger.warn('Telegram api key or chat id not set', requestContext, methodContext);
return false;
}
return true;
};
/**
* Sends a message to Telegram
* @param telegram The telegram config
* @param message The message to send
* @param logger The logger instance
* @param requestContext The request context
* @param methodContext The method context
*/
const sendTelegramMessage = async (
telegram: TelegramConfig,
message: string,
logger: Logger,
requestContext: RequestContext,
methodContext: MethodContext,
) => {
try {
await axiosPost(`https://api.telegram.org/bot${telegram!.apiKey}/sendMessage`, {
chat_id: telegram!.chatId,
text: message,
parse_mode: 'Html',
});
logger.info('Telegram message sent successfully', requestContext, methodContext);
} catch (error) {
logger.error('Failed to send Telegram message', requestContext, methodContext, jsonifyError(error as Error));
}
};
/**
* Sends alerts to telegram using axiosPost
* @param report The report that will be sent in the alert
* @param telegram The telegram config
* @param requestContext The request context for the logger
* @returns The response from telegram api
*/
export const alertTelegram = async (report: Report, telegram: TelegramConfig, requestContext: RequestContext) => {
const methodContext = createMethodContext(alertTelegram.name);
const { timestamp, reason, ids, logger, severity } = report;
if (!validateTelegramConfig(telegram, logger, requestContext, methodContext)) {
return;
}
logger.info('Sending message via telegram', requestContext, methodContext, {
timestamp,
reason,
ids,
severity,
});
const message = createTelegramMessage(report, false);
await sendTelegramMessage(telegram, message, logger, requestContext, methodContext);
};
/**
* Sends alerts to telegram using axiosPost indicating a report has been resolved
* @param report The report that will be sent in the alert
* @param telegram The telegram config
* @param requestContext The request context for the logger
* @returns The response from telegram api
*/
export async function resolveTelegramAlert(
report: Report,
telegram: TelegramConfig,
requestContext: RequestContext,
): Promise {
const methodContext = createMethodContext(resolveTelegramAlert.name);
const { timestamp, reason, ids, logger, severity } = report;
if (!validateTelegramConfig(telegram, logger, requestContext, methodContext)) {
return;
}
logger.info('Sending resolution message via telegram', requestContext, methodContext, {
timestamp,
reason,
ids,
severity,
});
const message = createTelegramMessage(report, true);
await sendTelegramMessage(telegram, message, logger, requestContext, methodContext);
}