diff --git a/templates/media/smseagle/README.md b/templates/media/smseagle/README.md new file mode 100644 index 000000000000..e4390889bbc9 --- /dev/null +++ b/templates/media/smseagle/README.md @@ -0,0 +1,50 @@ +# SMSEagle webhook + +This guide describes how to integrate your Zabbix installation with SMSEagle hardware SMS gateway using the Zabbix webhook feature. This guide will provide instructions on setting up a media type, a user and an action in Zabbix. +

+## In SMSEagle + +1\. Create a new user in SMSEagle (menu **Users** > **+ Add Users**, user access level: “User”). + +2\. Grant API access to the created user: + +- Click **Access to API** beside the newly created user. +- Enable **APIv2** +- Generate new token +- For text messages, add access permissions in section Messages for: **Send SMS, Send MMS**. +- For voice alerting, add access permissions in section Calls for: **Make a ring call, Make a TTS call, Make a TTS Advanced call**. +- Save settings. + +

+## In Zabbix + +The configuration consists of a _media type_ in Zabbix, which will invoke the webhook to send alerts to SMSEagle device through the Rest API. + + +1\. In the **Administration > Media types** section, import the [media_smseagle.yaml](media_smseagle.yaml). + + +2\. Open the newly added **SMSEagle** media type and replace all *<PLACEHOLDERS>* with your values.
+The following parameters are required:
+**access_token** - API access token created in SMSEagle
+**url** - actual URL of your SMSEagle device (for example: http://10.10.0.100 or https://sms.mycompany.com)
+**type** - type(s) of message(s) to send. Possible values: **sms, mms, tts** and **tts_adv**, respectively for SMS, MMS, TTS Call and Advanced TTS Call.
+Allows multiple types, separated by commas (e.g. "sms,tts_adv"). + +Other required parameters are message type specific. More information can be found on our [APIv2](https://www.smseagle.eu/docs/apiv2/) page. + + +3\. in the **Administration > Users** click on a User, and add a new media called **SMSEagle**. Enter SMS recipient. Available recipient formats:
+Phone number: phone_number
+Contact in SMSEagle Phonebook: contact_id:c
+Group in SMSEagle Phonebook: group_id:g
+ +Multiple recipients can be separated by comma. + + +

+For more information, please see [Zabbix](https://www.zabbix.com/documentation/6.2/manual/config/notifications) and [SMSEagle](https://www.smseagle.eu/integration-plugins/zabbix-sms-integration/) documentation. +

+## Supported Versions + +Zabbix 6.2+ \ No newline at end of file diff --git a/templates/media/smseagle/media_smseagle.yaml b/templates/media/smseagle/media_smseagle.yaml new file mode 100644 index 000000000000..4e2a71d331eb --- /dev/null +++ b/templates/media/smseagle/media_smseagle.yaml @@ -0,0 +1,279 @@ +zabbix_export: + version: '6.0' + media_types: + - + name: SMSEagle v2 + type: WEBHOOK + parameters: + - + name: url + value: '' + - + name: flash + value: 'false' + - + name: recipient + value: '{ALERT.SENDTO}' + - + name: text + value: '{ALERT.MESSAGE}' + - + name: priority + value: '0' + - + name: modem_no + value: 'default' + - + name: oid + value: 'default' + - + name: encoding + value: 'standard' + - + name: date + value: 'YYYYmmDDHHMM' + - + name: send_after + value: 'HH:MM' + - + name: send_before + value: 'HH:MM' + - + name: access_token + value: '' + - + name: type + value: 'sms' + - + name: duration + value: '10' + - + name: voice_id + value: '0' + - + name: test + value: 'false' + script: | + var SMSEagle = { + params: [], + requestBody: {}, + + addParam: function (name, value) { + SMSEagle.requestBody[name] = value; + }, + + setProxy: function (HTTPProxy) { + SMSEagle.HTTPProxy = HTTPProxy; + }, + + setPayload: function (params) { + + defaultValues = { + flash: 'false', + modem_no: 'default', + oid: 'default', + date: 'YYYYmmDDHHMM', + send_before: 'HH:MM', + send_after: 'HH:MM', + encoding: 'default', + voice_id: '0', + priority: '0', + test: 'false' + } + + Object.keys(params).forEach(function (key) { + if (params[key] && params[key] !== "" && params[key].trim() && params[key] !== defaultValues[key]) { + if (key === 'flash' || key === 'test') { + params[key] = (params[key] === 'true'); + } + + if (key === 'priority' || key === 'duration' || key === 'voice_id') { + params[key] = parseInt(params[key]); + } + + SMSEagle.addParam(key, params[key]); + Zabbix.log(4, '[ SMSEagle Webhook ] ' + key + ": " + SMSEagle.requestBody[key]); + } + }); + + var parts = params.recipient.split(','); + + var recipientGroups = []; + var recipientNumbers = []; + var recipientContacts = []; + + var recipientSplit = null; + + parts.forEach(function (value) { + recipientSplit = value.split(':'); + + var recipientType = ''; + if (recipientSplit[1] === 'g') { + recipientGroups.push(parseInt(recipientSplit[0])); + Zabbix.log(4, '[ SMSEagle Webhook ] ' + 'groups' + ": " + parseInt(recipientSplit[0])); + } else if (recipientSplit[1] === 'c') { + recipientContacts.push(parseInt(recipientSplit[0])); + Zabbix.log(4, '[ SMSEagle Webhook ] ' + 'contacts' + ": " + parseInt(recipientSplit[0])); + } else { + recipientNumbers.push(recipientSplit[0]); + Zabbix.log(4, '[ SMSEagle Webhook ] ' + 'to' + ": " + recipientSplit[0]); + } + + SMSEagle.addParam('groups', recipientGroups); + SMSEagle.addParam('contacts', recipientContacts); + SMSEagle.addParam('to', recipientNumbers); + }); + + delete params.recipient; + }, + + request: function (element) { + var dest_url; + + switch (element) { + case 'tts': + dest_url = params.url + '/api/v2/calls/tts'; + break; + case 'tts_adv': + dest_url = params.url + '/api/v2/calls/tts_advanced'; + break; + case 'sms': + dest_url = params.url + '/api/v2/messages/sms'; + break; + case 'mms': + dest_url = params.url + '/api/v2/messages/mms'; + break; + default: + dest_url = params.url + '/api/v2/messages/sms'; + break; + } + + body = JSON.stringify(SMSEagle.requestBody); + + if (typeof SMSEagle.HTTPProxy !== 'undefined' && SMSEagle.HTTPProxy !== '') { + request.setProxy(SMSEagle.HTTPProxy); + } + + Zabbix.log(4, '[ SMSEagle Webhook ] Sending request: ' + dest_url); + + request.addHeader('Content-Type: application/json'); + request.addHeader('access-token: ' + params.access_token); + response = request.post(dest_url, body); + + Zabbix.log(4, '[ SMSEagle Webhook ] Received response with status code ' + request.getStatus() + '\n' + response); + + if (request.getStatus() < 200 || request.getStatus() >= 300) { + var message = 'Request failed with status code ' + request.getStatus(); + + if (response) { + message += ': ' + response; + } + + throw message + '. Check debug log for more information.'; + } + } + }; + + try { + var response, + request, + params = JSON.parse(value), + body; + + ['url', 'access_token', 'text', 'recipient'].forEach(function (field) { + if (typeof params !== 'object' || typeof params[field] === 'undefined' + || !params[field].trim()) { + throw 'Required parameter is not set: "' + field + '".'; + } + }); + + if (params.type.includes('tts_adv')) { + if (typeof params !== 'object' || typeof params['voice_id'] === 'undefined' || !params['voice_id'].trim()) { + throw 'Required parameter is not set: "voice_id".'; + } + } + + if (params.recipient === '{ALERT.SENDTO}') { + throw 'Required parameter is not set: "recipient".'; + } + + if (params.access_token === "") { + throw 'Required parameter is not set: "access_token".'; + } + + if (params.url === "") { + throw 'Required parameter is not set: "url".'; + } + + params.type = params.type.trim(); + var types = params.type.split(","); + + SMSEagle.setPayload(params); + types.forEach(function (element) { + request = new HttpRequest(); + SMSEagle.setProxy(params.HTTPProxy); + SMSEagle.request(element); + }); + + return 'OK'; + } + catch (error) { + Zabbix.log(3, '[ SMSEagle Webhook ] ERROR: ' + error); + throw 'Sending failed: ' + error; + } + message_templates: + - + event_source: TRIGGERS + operation_mode: PROBLEM + subject: '[{EVENT.STATUS}] {EVENT.NAME}' + message: | + [{EVENT.STATUS}] {EVENT.NAME} + Started at {EVENT.TIME} on {EVENT.DATE} + Host: {HOST.NAME} + Severity: {EVENT.SEVERITY} + Operational data: {EVENT.OPDATA} + Event info: {$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID} + - + event_source: TRIGGERS + operation_mode: RECOVERY + subject: 'Resolved in {EVENT.DURATION}: {EVENT.NAME}' + message: | + [{EVENT.STATUS}] {EVENT.NAME} + Resolved in {EVENT.DURATION} at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} + Host: {HOST.NAME} + Severity: {EVENT.SEVERITY} + Event info: {$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID} + - + event_source: TRIGGERS + operation_mode: UPDATE + subject: '[{EVENT.STATUS}] {EVENT.NAME}' + message: | + [{EVENT.STATUS}] {EVENT.NAME} + + {USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}. + {EVENT.UPDATE.MESSAGE} + - + event_source: DISCOVERY + operation_mode: PROBLEM + subject: 'Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS}' + message: | + Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS} + 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: | + Autoregistration: {HOST.HOST} + Host IP: {HOST.IP} + Agent port: {HOST.PORT}