diff --git a/templates/media/plivo/README.md b/templates/media/plivo/README.md new file mode 100644 index 000000000000..eeac42b05cc3 --- /dev/null +++ b/templates/media/plivo/README.md @@ -0,0 +1,91 @@ +# Plivo webhook + +## Overview + +This guide describes how to integrate your Zabbix installation with Plivo using the Zabbix webhook feature, providing instructions on setting up a media type, user, and action in Zabbix to send notifications via SMS or WhatsApp. + +## Requirements + +Zabbix version: 7.4 and higher. + +## Parameters + +After importing the webhook, you can configure it using webhook parameters. + +### Configurable parameters + +The configurable parameters are intended to be changed according to the webhook setup as well as the user's preferences and environment. + +|Name|Value|Description| +|----|-----|-----------| +|auth_id|\{$PLIVO\.AUTH\_ID\}|Plivo Auth ID.| +|auth_token|\{$PLIVO\.AUTH\_TOKEN\}|Plivo Auth Token.| +|message_type|sms|Message type. Possible values: sms, whatsapp.| +|from_number|\|Sender phone number or alphanumeric sender ID.| + +### Internal parameters + +Internal parameters are reserved for predefined macros that are not meant to be changed. + +|Name|Value|Description| +|----|-----|-----------| +|to_number|\{ALERT\.SENDTO\}|Destination phone number.| +|alert_subject|\{ALERT\.SUBJECT\}|'Default subject' value from action configuration.| +|alert_message|\{ALERT\.MESSAGE\}|'Default message' value from action configuration.| + +> Please be aware that each webhook supports an HTTP proxy. To use this feature, add a new media type parameter with the name `http_proxy` and set its value to the proxy URL. + +## Service setup + +1\. Sign up for a Plivo account at [https://www.plivo.com](https://www.plivo.com). + +2\. In your Plivo console, navigate to **Account Settings** to obtain your Auth ID and Auth Token. + +3\. For SMS messaging: + - Purchase a phone number from Plivo or use an approved alphanumeric sender ID. + +4\. For WhatsApp messaging: + - Set up WhatsApp Business Account integration through Plivo. + - Ensure your WhatsApp Business Account is approved and connected to your Plivo account. + +## Zabbix configuration + +### Create global macros + +1\. Before setting up the webhook, you need to setup the global macros for Plivo credentials. + +2\. In the Zabbix web interface, go to *Administration* > *General* > *Macros*. + +3\. Add the following macros: + - `{$PLIVO.AUTH_ID}` with your Plivo Auth ID + - `{$PLIVO.AUTH_TOKEN}` with your Plivo Auth Token (mark as secret) + +4\. Click the *Update* button to save the macros. + +### Create the Plivo media type + +1\. In the Zabbix interface *Alerts* > *Media types* section, import the [`media_plivo.yaml`](media_plivo.yaml) file. + +2\. Open the newly added **Plivo** media type and configure the following parameters: + - Set `from_number` to your Plivo phone number or approved sender ID + - Set `message_type` to `sms` for SMS messages or `whatsapp` for WhatsApp messages + +3\. Click the *Update* button to save the webhook settings. + +### Create a user for Plivo notifications + +1\. To receive notifications via Plivo, you need to create a Zabbix user and add **Media** with the **Plivo** media type. + +2\. In the *Media* configuration, the **Send to** field should contain the destination phone number in E.164 format (e.g., `+14155551234`). + +3\. Make sure this user has access to all the hosts for which you would like problem notifications to be sent via Plivo. + +For more information, please see [Zabbix](https://www.zabbix.com/documentation/7.4/manual/config/notifications) and [Plivo API](https://www.plivo.com/docs/) documentation. + +## Feedback + +This is a community-contributed media type template. + +Please report any issues, provide feedback, or ask for help at [`ZABBIX forums`](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback). + +For official Zabbix support, please visit [`https://support.zabbix.com`](https://support.zabbix.com). \ No newline at end of file diff --git a/templates/media/plivo/media_plivo.yaml b/templates/media/plivo/media_plivo.yaml new file mode 100644 index 000000000000..5bea6e89c2b9 --- /dev/null +++ b/templates/media/plivo/media_plivo.yaml @@ -0,0 +1,191 @@ +zabbix_export: + version: '7.4' + media_types: + - name: Plivo SMS/WhatsApp + type: WEBHOOK + parameters: + # ── Plivo credentials and settings ────────────────────────────── + - name: auth_id + value: '{$PLIVO.AUTH_ID}' + - name: auth_token + value: '{$PLIVO.AUTH_TOKEN}' + - name: message_type + value: 'sms' + - name: from_number + value: '' + # ── Message-specific parameters ──────────────────────────────── + - name: to_number + value: '{ALERT.SENDTO}' + - name: alert_subject + value: '{ALERT.SUBJECT}' + - name: alert_message + value: '{ALERT.MESSAGE}' + - name: event_id + value: '{EVENT.ID}' + - name: event_nseverity + value: '{EVENT.NSEVERITY}' + - name: event_source + value: '{EVENT.SOURCE}' + - name: event_value + value: '{EVENT.VALUE}' + # optional HTTP proxy + - name: http_proxy + value: '' + status: DISABLED + attempts: '3' + max_sessions: '0' + process_tags: 'NO' + script: | + /** + * Plivo SMS/WhatsApp webhook for Zabbix + * Supports both SMS and WhatsApp via Plivo API + * Docs: https://www.plivo.com/docs/messaging/api/message/send-a-message + */ + try { + var params = JSON.parse(value), + request = new HttpRequest(), + response, + apiUrl, + payload, + messageType; + + /* Proxy support */ + if (typeof params.http_proxy === 'string' && params.http_proxy.trim() !== '') { + request.setProxy(params.http_proxy); + } + + /* Basic sanity checks */ + if (typeof params.auth_id !== 'string' || params.auth_id.trim() === '') { + throw 'Parameter "auth_id" is missing'; + } + if (typeof params.auth_token !== 'string' || params.auth_token.trim() === '') { + throw 'Parameter "auth_token" is missing'; + } + if (typeof params.from_number !== 'string' || params.from_number.trim() === '' || params.from_number === '') { + throw 'Parameter "from_number" is not set'; + } + if (typeof params.to_number !== 'string' || params.to_number.trim() === '') { + throw 'Parameter "to_number" is empty (did you set "Send to" field?)'; + } + + if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) { + throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.'; + } + + if (params.event_value !== '0' && params.event_value !== '1' + && (params.event_source === '0' || params.event_source === '3')) { + throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.'; + } + + if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) { + params.event_nseverity = '0'; + } + + /* Determine message type and API endpoint */ + messageType = (typeof params.message_type === 'string') ? params.message_type.toLowerCase() : 'sms'; + + if (['sms', 'whatsapp'].indexOf(messageType) === -1) { + throw 'Invalid message_type: "' + messageType + '". Must be "sms" or "whatsapp"'; + } + + /* Plivo uses same endpoint for both SMS and WhatsApp */ + apiUrl = 'https://api.plivo.com/v1/Account/' + params.auth_id + '/Message/'; + + /* Build JSON payload */ + var messageBody = (params.alert_subject ? params.alert_subject + '\n' : '') + params.alert_message; + + var payloadObj = { + src: params.from_number, + dst: params.to_number, + text: messageBody, + type: messageType // Plivo API requires 'type' parameter: 'sms', 'mms', or 'whatsapp' + }; + + /* WhatsApp-specific formatting */ + if (messageType === 'whatsapp') { + /* WhatsApp supports basic formatting */ + payloadObj.text = messageBody + .replace(/\*([^*]+)\*/g, '*$1*') // Keep bold formatting + .replace(/Problem:/g, '*Problem:*') + .replace(/Resolved:/g, '*Resolved:*'); + } + + payload = JSON.stringify(payloadObj); + + /* Prepare HTTP request */ + request.addHeader('Content-Type: application/json'); + request.setBasicAuth(params.auth_id, params.auth_token); + + Zabbix.log(4, '[ Plivo ' + messageType.toUpperCase() + ' ] Sending POST to ' + apiUrl + ' with body: ' + payload); + response = request.post(apiUrl, payload); + Zabbix.log(4, '[ Plivo ' + messageType.toUpperCase() + ' ] Response code ' + request.getStatus() + ': ' + response); + + if (request.getStatus() >= 200 && request.getStatus() < 300) { + return 'OK'; + } + + throw 'HTTP ' + request.getStatus() + ' - ' + response; + } + catch (error) { + Zabbix.log(4, '[ Plivo Webhook ] Plivo notification failed: ' + error); + throw 'Plivo notification failed: ' + error; + } + description: | + Please refer to setup guide here: https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/templates/media/plivo + + Set auth_id and auth_token parameters to your Plivo credentials. + Set message_type to 'sms' or 'whatsapp'. + When assigning Plivo media to the Zabbix user - add destination phone number into send to field. + 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 at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} + Problem name: {EVENT.NAME} + Problem duration: {EVENT.DURATION} + Host: {HOST.NAME} + Severity: {EVENT.SEVERITY} + Original problem ID: {EVENT.ID} + {TRIGGER.URL} + - event_source: TRIGGERS + operation_mode: UPDATE + subject: 'Updated problem in {EVENT.AGE}: {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}, age is {EVENT.AGE}, 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} \ No newline at end of file diff --git a/templates/media/twilio/README.md b/templates/media/twilio/README.md new file mode 100644 index 000000000000..a82c2b7de170 --- /dev/null +++ b/templates/media/twilio/README.md @@ -0,0 +1,92 @@ +# Twilio webhook + +## Overview + +This guide describes how to integrate your Zabbix installation with Twilio using the Zabbix webhook feature, providing instructions on setting up a media type, user, and action in Zabbix to send notifications via SMS or WhatsApp. + +## Requirements + +Zabbix version: 7.4 and higher. + +## Parameters + +After importing the webhook, you can configure it using webhook parameters. + +### Configurable parameters + +The configurable parameters are intended to be changed according to the webhook setup as well as the user's preferences and environment. + +|Name|Value|Description| +|----|-----|-----------| +|account_sid|\{$TWILIO\.ACCOUNT\_SID\}|Twilio Account SID.| +|auth_token|\{$TWILIO\.AUTH\_TOKEN\}|Twilio Auth Token.| +|message_type|sms|Message type. Possible values: sms, whatsapp.| +|from_number|\|Twilio-verified sender phone number.| + +### Internal parameters + +Internal parameters are reserved for predefined macros that are not meant to be changed. + +|Name|Value|Description| +|----|-----|-----------| +|to_number|\{ALERT\.SENDTO\}|Destination phone number.| +|alert_subject|\{ALERT\.SUBJECT\}|'Default subject' value from action configuration.| +|alert_message|\{ALERT\.MESSAGE\}|'Default message' value from action configuration.| + +> Please be aware that each webhook supports an HTTP proxy. To use this feature, add a new media type parameter with the name `http_proxy` and set its value to the proxy URL. + +## Service setup + +1\. Sign up for a Twilio account at [https://www.twilio.com](https://www.twilio.com). + +2\. In your Twilio console, navigate to **Account Settings** to obtain your Account SID and Auth Token. + +3\. For SMS messaging: + - Purchase a phone number from Twilio. + +4\. For WhatsApp messaging: + - Set up WhatsApp Business Account through Twilio. + - Submit your WhatsApp Business Account for approval by Twilio. + - Wait for approval before using WhatsApp messaging. + +## Zabbix configuration + +### Create global macros + +1\. Before setting up the webhook, you need to setup the global macros for Twilio credentials. + +2\. In the Zabbix web interface, go to *Administration* > *General* > *Macros*. + +3\. Add the following macros: + - `{$TWILIO.ACCOUNT_SID}` with your Twilio Account SID + - `{$TWILIO.AUTH_TOKEN}` with your Twilio Auth Token (mark as secret) + +4\. Click the *Update* button to save the macros. + +### Create the Twilio media type + +1\. In the Zabbix interface *Alerts* > *Media types* section, import the [`media_twilio.yaml`](media_twilio.yaml) file. + +2\. Open the newly added **Twilio** media type and configure the following parameters: + - Set `from_number` to your Twilio phone number (e.g., `+14155551234`) + - Set `message_type` to `sms` for SMS messages or `whatsapp` for WhatsApp messages + +3\. Click the *Update* button to save the webhook settings. + +### Create a user for Twilio notifications + +1\. To receive notifications via Twilio, you need to create a Zabbix user and add **Media** with the **Twilio** media type. + +2\. In the *Media* configuration, the **Send to** field should contain the destination phone number in E.164 format (e.g., `+14155551234`). + +3\. Make sure this user has access to all the hosts for which you would like problem notifications to be sent via Twilio. + +For more information, please see [Zabbix](https://www.zabbix.com/documentation/7.4/manual/config/notifications) and [Twilio API](https://www.twilio.com/docs/) documentation. + +## Feedback + +This is a community-contributed media type template. + +Please report any issues, provide feedback, or ask for help at [`ZABBIX forums`](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback). + +For official Zabbix support, please visit [`https://support.zabbix.com`](https://support.zabbix.com). \ No newline at end of file diff --git a/templates/media/twilio/media_twilio.yaml b/templates/media/twilio/media_twilio.yaml new file mode 100644 index 000000000000..ef19f4c2cf2a --- /dev/null +++ b/templates/media/twilio/media_twilio.yaml @@ -0,0 +1,192 @@ +zabbix_export: + version: '7.4' + media_types: + - name: Twilio SMS/WhatsApp + type: WEBHOOK + parameters: + # ── Twilio credentials and settings ─────────────────────────────── + - name: account_sid + value: '{$TWILIO.ACCOUNT_SID}' + - name: auth_token + value: '{$TWILIO.AUTH_TOKEN}' + - name: message_type + value: 'sms' + - name: from_number + value: '' + # ── Message-specific parameters ─────────────────────────────────── + - name: to_number + value: '{ALERT.SENDTO}' + - name: alert_subject + value: '{ALERT.SUBJECT}' + - name: alert_message + value: '{ALERT.MESSAGE}' + - name: event_id + value: '{EVENT.ID}' + - name: event_nseverity + value: '{EVENT.NSEVERITY}' + - name: event_source + value: '{EVENT.SOURCE}' + - name: event_value + value: '{EVENT.VALUE}' + # optional HTTP proxy for outbound call + - name: http_proxy + value: '' + status: DISABLED + attempts: '3' + max_sessions: '0' + process_tags: 'NO' + script: | + /** + * Twilio SMS/WhatsApp webhook for Zabbix + * Supports both SMS and WhatsApp via Twilio API + * Docs: https://www.twilio.com/docs/messaging/api/message-resource + */ + try { + var params = JSON.parse(value), + request = new HttpRequest(), + response, + apiUrl, + payload, + fromNumber, + toNumber; + + /* Proxy support */ + if (typeof params.http_proxy === 'string' && params.http_proxy.trim() !== '') { + request.setProxy(params.http_proxy); + } + + /* Basic sanity checks */ + if (typeof params.account_sid !== 'string' || params.account_sid.trim() === '') { + throw 'Parameter "account_sid" is missing'; + } + if (typeof params.auth_token !== 'string' || params.auth_token.trim() === '') { + throw 'Parameter "auth_token" is missing'; + } + if (typeof params.from_number !== 'string' || params.from_number.trim() === '' || params.from_number === '') { + throw 'Parameter "from_number" is not set'; + } + if (typeof params.to_number !== 'string' || params.to_number.trim() === '') { + throw 'Parameter "to_number" is empty (did you set "Send to" field?)'; + } + + if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) { + throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.'; + } + + if (params.event_value !== '0' && params.event_value !== '1' + && (params.event_source === '0' || params.event_source === '3')) { + throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.'; + } + + if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) { + params.event_nseverity = '0'; + } + + /* Determine message type and format numbers accordingly */ + var messageType = (typeof params.message_type === 'string') ? params.message_type.toLowerCase() : 'sms'; + + if (messageType === 'whatsapp') { + /* WhatsApp format: whatsapp:+1234567890 */ + fromNumber = params.from_number.indexOf('whatsapp:') === 0 ? params.from_number : 'whatsapp:' + params.from_number; + toNumber = params.to_number.indexOf('whatsapp:') === 0 ? params.to_number : 'whatsapp:' + params.to_number; + } else { + /* SMS format: regular phone numbers */ + fromNumber = params.from_number.replace(/^whatsapp:/, ''); + toNumber = params.to_number.replace(/^whatsapp:/, ''); + } + + /* Compose API endpoint */ + apiUrl = 'https://api.twilio.com/2010-04-01/Accounts/' + params.account_sid + '/Messages.json'; + + /* Build application/x-www-form-urlencoded payload */ + var messageBody = (params.alert_subject ? params.alert_subject + '\n' : '') + params.alert_message; + + /* WhatsApp supports basic formatting */ + if (messageType === 'whatsapp') { + messageBody = messageBody + .replace(/\*([^*]+)\*/g, '*$1*') // Keep bold formatting + .replace(/Problem:/g, '*Problem:*') + .replace(/Resolved:/g, '*Resolved:*'); + } + + payload = 'To=' + encodeURIComponent(toNumber) + + '&From=' + encodeURIComponent(fromNumber) + + '&Body=' + encodeURIComponent(messageBody); + + /* Prepare HTTP request */ + request.addHeader('Content-Type: application/x-www-form-urlencoded'); + request.setBasicAuth(params.account_sid, params.auth_token); + + Zabbix.log(4, '[ Twilio ' + messageType.toUpperCase() + ' ] Sending POST to ' + apiUrl + ' with body: ' + payload); + response = request.post(apiUrl, payload); + Zabbix.log(4, '[ Twilio ' + messageType.toUpperCase() + ' ] Response code ' + request.getStatus() + ': ' + response); + + if (request.getStatus() >= 200 && request.getStatus() < 300) { + return 'OK'; + } + + throw 'HTTP ' + request.getStatus() + ' - ' + response; + } + catch (error) { + Zabbix.log(4, '[ Twilio Webhook ] Twilio notification failed: ' + error); + throw 'Twilio notification failed: ' + error; + } + description: | + Please refer to setup guide here: https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/templates/media/twilio + + Set account_sid and auth_token parameters to your Twilio credentials. + Set message_type to 'sms' or 'whatsapp'. + When assigning Twilio media to the Zabbix user - add destination phone number into send to field. + 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 at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} + Problem name: {EVENT.NAME} + Problem duration: {EVENT.DURATION} + Host: {HOST.NAME} + Severity: {EVENT.SEVERITY} + Original problem ID: {EVENT.ID} + {TRIGGER.URL} + - event_source: TRIGGERS + operation_mode: UPDATE + subject: 'Updated problem in {EVENT.AGE}: {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}, age is {EVENT.AGE}, 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} \ No newline at end of file