diff --git a/README.md b/README.md index 449f900..3c13222 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Templates, scripts and hints for Zabbix. * [certificate](templates/components/certificate/6.0) * [Sensors](templates/sensors) * [ds18b20](templates/sensors/ds18b20/6.0) +* [Media](templates/media) + * [Telegram](templates/media/telegram/6.0) ## Useful links diff --git a/templates/media/telegram/6.0/README.md b/templates/media/telegram/6.0/README.md new file mode 100644 index 0000000..79e34d1 --- /dev/null +++ b/templates/media/telegram/6.0/README.md @@ -0,0 +1,13 @@ +# Telegram webhook + +This template is modifided version of [original](https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/templates/media/telegram) webhook. Template additionally supports topics notification. + +## Zabbix setup + +1\. In the "Administration > Media types" section, import the media_telegram.yaml. + +2\. Configure the added media type: +Copy and paste your Telegram bot token into the "telegramToken" field. + +3\. To receive notifications in Telegram, you need to create a Zabbix user and add Media with the Telegram type. +In the "Send to" field enter Telegram user chat ID or group ID or topic ID (example: ```-100123456789_123```) obtained during Telegram setup. diff --git a/templates/media/telegram/6.0/media_telegram.yaml b/templates/media/telegram/6.0/media_telegram.yaml new file mode 100644 index 0000000..3850877 --- /dev/null +++ b/templates/media/telegram/6.0/media_telegram.yaml @@ -0,0 +1,202 @@ +zabbix_export: + version: '6.0' + date: '2023-12-25T00:00:00Z' + media_types: + - + name: Telegram + type: WEBHOOK + parameters: + - + name: Message + value: '{ALERT.MESSAGE}' + - + name: ParseMode + - + name: Subject + value: '{ALERT.SUBJECT}' + - + name: To + value: '{ALERT.SENDTO}' + - + name: Token + value: '' + script: | + var Telegram = { + token: null, + to: null, + message: null, + proxy: null, + parse_mode: null, + + escapeMarkup: function (str, mode) { + switch (mode) { + case 'markdown': + return str.replace(/([_*\[`])/g, '\\$&'); + + case 'markdownv2': + return str.replace(/([_*\[\]()~`>#+\-=|{}.!])/g, '\\$&'); + + default: + return str; + } + }, + + sendMessage: function () { + var params = { + chat_id: Telegram.to, + text: Telegram.message, + disable_web_page_preview: true, + disable_notification: false + }, + data, + response, + request = new HttpRequest(), + url = 'https://api.telegram.org/bot' + Telegram.token + '/sendMessage'; + + if (Telegram.to.includes('_')) { + params['chat_id'] = Telegram.to.split('_')[0]; + params['message_thread_id'] = Telegram.to.split('_')[1]; + } + + if (Telegram.parse_mode !== null) { + params['parse_mode'] = Telegram.parse_mode; + } + + if (Telegram.proxy) { + request.setProxy(Telegram.proxy); + } + + request.addHeader('Content-Type: application/json'); + data = JSON.stringify(params); + + // Remove replace() function if you want to see the exposed token in the log file. + Zabbix.log(4, '[Telegram Webhook] URL: ' + url.replace(Telegram.token, '')); + Zabbix.log(4, '[Telegram Webhook] params: ' + data); + response = request.post(url, data); + Zabbix.log(4, '[Telegram Webhook] HTTP code: ' + request.getStatus()); + + try { + response = JSON.parse(response); + } + catch (error) { + response = null; + } + + if (request.getStatus() !== 200 || typeof response.ok !== 'boolean' || response.ok !== true) { + if (typeof response.description === 'string') { + throw response.description; + } + else { + throw 'Unknown error. Check debug log for more information.'; + } + } + } + }; + + try { + var params = JSON.parse(value); + + if (typeof params.Token === 'undefined') { + throw 'Incorrect value is given for parameter "Token": parameter is missing'; + } + + Telegram.token = params.Token; + + if (params.HTTPProxy) { + Telegram.proxy = params.HTTPProxy; + } + + params.ParseMode = params.ParseMode.toLowerCase(); + + if (['markdown', 'html', 'markdownv2'].indexOf(params.ParseMode) !== -1) { + Telegram.parse_mode = params.ParseMode; + } + + Telegram.to = params.To; + Telegram.thread = params.Thread; + Telegram.message = params.Subject + '\n' + params.Message; + + if (['markdown', 'markdownv2'].indexOf(params.ParseMode) !== -1) { + Telegram.message = Telegram.escapeMarkup(Telegram.message, params.ParseMode); + } + + Telegram.sendMessage(); + + return 'OK'; + } + catch (error) { + Zabbix.log(4, '[Telegram Webhook] notification failed: ' + error); + throw 'Sending failed: ' + error + '.'; + } + timeout: 10s + description: | + https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/templates/media/telegram + + 1. Register bot: send "/newbot" to @BotFather and follow instructions + 2. Copy and paste the obtained token into the "Token" field above + 3. If you want to send personal notifications, you need to get chat id of the user you want to send messages to: + 3.1. Send "/getid" to "@myidbot" in Telegram messenger + 3.2. Copy returned chat id and save it in the "Telegram Webhook" media for the user + 3.3. Ask the user to send "/start" to your bot (Telegram bot won't send anything to the user without it) + 4. If you want to send group notifications, you need to get group id of the group you want to send messages to: + 4.1. Add "@myidbot" to your group + 4.2. Send "/getgroupid@myidbot" in your group + 4.3. Copy returned group id save it in the "Telegram Webhook" media for the user you created for group notifications + 4.4. Send "/start@your_bot_name_here" in your group (Telegram bot won't send anything to the group without it) + message_templates: + - + event_source: TRIGGERS + operation_mode: PROBLEM + subject: 'Problem: {EVENT.NAME}' + message: | + Problem started at {EVENT.TIME} on {EVENT.DATE} + Problem name: {EVENT.NAME} + Host: {HOST.NAME} + Severity: {EVENT.SEVERITY} + Operational data: {EVENT.OPDATA} + Original problem ID: {EVENT.ID} + {TRIGGER.URL} + - + event_source: TRIGGERS + operation_mode: RECOVERY + subject: 'Resolved in {EVENT.DURATION}: {EVENT.NAME}' + message: | + Problem has been resolved in {EVENT.DURATION} at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} + Problem name: {EVENT.NAME} + Host: {HOST.NAME} + Severity: {EVENT.SEVERITY} + Original problem ID: {EVENT.ID} + {TRIGGER.URL} + - + event_source: TRIGGERS + operation_mode: UPDATE + subject: 'Updated problem: {EVENT.NAME}' + message: | + {USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}. + {EVENT.UPDATE.MESSAGE} + + Current problem status is {EVENT.STATUS}, acknowledged: {EVENT.ACK.STATUS}. + - + event_source: DISCOVERY + operation_mode: PROBLEM + subject: 'Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS}' + message: | + Discovery rule: {DISCOVERY.RULE.NAME} + + Device IP: {DISCOVERY.DEVICE.IPADDRESS} + Device DNS: {DISCOVERY.DEVICE.DNS} + Device status: {DISCOVERY.DEVICE.STATUS} + Device uptime: {DISCOVERY.DEVICE.UPTIME} + + Device service name: {DISCOVERY.SERVICE.NAME} + Device service port: {DISCOVERY.SERVICE.PORT} + Device service status: {DISCOVERY.SERVICE.STATUS} + Device service uptime: {DISCOVERY.SERVICE.UPTIME} + - + event_source: AUTOREGISTRATION + operation_mode: PROBLEM + subject: 'Autoregistration: {HOST.HOST}' + message: | + Host name: {HOST.HOST} + Host IP: {HOST.IP} + Agent port: {HOST.PORT}