Ad Widget

Collapse

оповещение sms через API

Collapse
This topic has been answered.
X
X
 
  • Time
  • Show
Clear All
new posts
  • djin59
    Member
    • Jul 2023
    • 86

    #1

    оповещение sms через API

    Zabbix 7.0.8
    застрял ....
    цель создать оповещение webhook в параметрах задать следущее:
    Click image for larger version  Name:	image.png Views:	0 Size:	37.4 KB ID:	498178
    помогите с реализацией JAVA SCRIPT - НУЖЕН СКРИПТ или там можно вписать не только JS????... что-то с ИИ пока не получилось разобраться ...


    При этом запрос из самой ОС работает
    curl -X POST "https://фффффффффффф/hффффv1/mфффages" \
    -H "Authorization: Basic 111111111111111111111111111111" \
    -H "Content-Type: application/json" \
    -x "http://uффф.ффф.ru:8080" \
    -d '{
    "messages": [
    {
    "content": { "short_text": "Тестовое SMS " },
    "from": { "sms_address": "вввввв" },
    "to": [ { "msisdn": "+79000000" } ]
    }
    ]
    }'

    Нужно , если это реализуемо именно через Webhook не создавай скриптов sh - не хочу через bash
    Last edited by djin59; 30-01-2025, 11:59.
  • Answer selected by djin59 at 31-01-2025, 14:13.
    djin59
    Member
    • Jul 2023
    • 86

    Спасибо! с Вашей и ИИ помощью справился вот моё решение :

    Code:
    'use strict';
    
    try {
        // Парсим входные данные
        var params = JSON.parse(value);
        
        // Проверка обязательных параметров
        if (!params.To || params.To.trim() === '') {
            throw 'Параметр "To" обязателен!';
        }
        if (!params.Message || params.Message.trim() === '') {
            throw 'Параметр "Message" обязателен!';
        }
    
        // Форматируем номер телефона
        var msisdn = params.To.replace(/^\+/, ''); // Удаляем + в начале
        
        // Формируем тело запроса
        var requestBody = {
            messages: [{
                content: { short_text: params.Message.trim() },
                from: { sms_address: "ZZZZZZZZZZZZZ" },
                to: [{ msisdn: msisdn }]
            }]
        };
        
        // Создаем HTTP-запрос
        var req = new HttpRequest();
        req.addHeader('Content-Type: application/json');
        req.addHeader('Authorization: Basic ZZZZZZZZZZZZZZZZZZZZZZZZZZZ');
        
        // Настраиваем прокси (если требуется)
        req.setProxy("http://ZZZZZZZZZZZZZZZZZZ:8080");
        
        // Отправляем POST-запрос
        var response = req.post(
            'https://ZZZZZZZZZZZZZZZZZZZu/messages',
            JSON.stringify(requestBody)
        );
        
        // Логирование
        Zabbix.Log(4, '[SMS Webhook] Request body: ' + JSON.stringify(requestBody));
        Zabbix.Log(4, '[SMS Webhook] Response: ' + response);
        
        // Проверяем статус ответа
        if (req.getStatus() < 200 || req.getStatus() >= 300) {
            throw 'HTTP Error: ' + req.getStatus() + ' - ' + response;
        }
        
        return 'OK';
    }
    catch (error) {
        Zabbix.Log(3, '[SMS Webhook] ERROR: ' + error);
        throw 'Ошибка отправки: ' + error;
    }

    Comment

    • djin59
      Member
      • Jul 2023
      • 86

      #2
      Если кому-то пригодиться вот реализация через bash
      #------------------------------------------------------------------------------скрипт- send_sms_by_inet.sh----------------------------
      #!/bin/bash

      # Параметры
      SENDTO=$1
      MESSAGE=$2

      # Проверка наличия необходимых параметров
      if [ -z "$SENDTO" ] || [ -z "$MESSAGE" ]; then
      echo "Ошибка: Необходимы два параметра: sendto (номер телефона) и message (текст сообщения)"
      exit 1
      fi

      # Отправка SMS через API
      curl -X POST "https://адресдоAPI" \
      -H "Authorization: Basic Z3111111111111111111111111111" \
      -H "Content-Type: application/json" \
      -x "http://ВАШПРОКСИ:ПОРТ" \
      -d '{
      "messages": [
      {
      "content": { "short_text": "'"$MESSAGE"'" },
      "from": { "sms_address": "ОТ КОГО ШЛЕМ " },
      "to": [ { "msisdn": "'"$SENDTO"'" } ]
      }
      ]
      }'
      #----------------------------------------------------------------------конец скрипта----------------------------------------------------------------------
      Создаем способ оповещения :
      Click image for larger version  Name:	image.png Views:	0 Size:	30.5 KB ID:	498192


      в настройках конфига сервера не забудьте задать AlertScriptsPath (путь то места где лежат у Вас скрипты)



      p/s надеюсь кто-нибудь поможет мне с вебхуком​

      Comment

      • Kos
        Senior Member
        Zabbix Certified SpecialistZabbix Certified Professional
        • Aug 2015
        • 3404

        #3
        Честно говоря, лениво переписывать с одного языка на другой, при этом не имея возможности поотлаживаться.
        Но я решал очень похожую задачу - отсылку SMS через гейт Kannel (ссылка на их API). Там API тоже сводится к отсылке HTTP-запроса (возможно, через HTTP-прокси), главное - правильно сформулировать этот запрос (в их случае всё передавалось через URL). Тоже делал через отдельный канал доставки с типом "вебхук", так что очень похоже.
        Если интересно, то могу поделиться решением - подправите его под свои нужды; вроде, ничего особо сложного там нет. Надо?

        Comment


        • djin59
          djin59 commented
          Editing a comment
          да, очень, интересно... так как я реализовал работает , но я так не хочу...
      • Kos
        Senior Member
        Zabbix Certified SpecialistZabbix Certified Professional
        • Aug 2015
        • 3404

        #4
        да, очень, интересно
        Ну, что ж. Скопирую сюда своё же описание того, как настроить отсылку уведомлений через SMS-шлюз на основе opensource-продукта Kannel.
        Описывал ещё для версии Zabbix 5.0; в 7.0 чуть поменялась структура меню в веб-интерфейсе, но, думаю, найти нужные места не составит проблемы.
        Ещё несколько замечаний:
        • мы у себя те триггеры, события для которых нужно отсылать через этот канал уведомлений, помечаем тегом "sms" со значением "kannel". В веб-хуке есть проверка наличия этого тега, а действие отсылки уведомлений настроено на использование этого тега с этим значением;
        • нужно ли использовать прокси, вынесено в настройки (в нашем случае SMS-шлюз находится во внутренней сети, так что прокси не используется);
        • Kannel требует указывать полный номер телефона, включающий код страны, но без всяких префиксов вроде знака "плюс", поэтому в коде веб-хука есть проверка: если переданный номер начинается с плюса, то этот знак отрезается, а если номер указан без международного кода (т.е. имеет длину не более 8 цифр), то к нему добавляется "371" (международный код Латвии);
        • если при тестировании не указывать конкретные значения макросов, то они остаются нераскрытыми, на этот случай тоже есть проверки.

        Итак, поехали:

        Для этого нужно сделать следующие настройки:
        • (однократно на уровне системы Zabbix) Через веб-интерфейс (меню Administration → Media types) добавить новый канал уведомлений (кнопка "Create media type"). При этом указать следующие параметры:
          • Name: SMS (Kannel)
          • Type: Webhook
          • Parameters: см. таблицу
        event_source {EVENT.SOURCE}
        HTTPProxy (пусто)
        kannel_password {$KANNEL_PASSWORD}
        kannel_user {$KANNEL_USER}
        message {ALERT.MESSAGE}
        subject {ALERT.SUBJECT}
        tag_sms {EVENT.TAGS.sms}
        to {ALERT.SENDTO}
        url https://ваш.гейт.kannel:порт/cgi-bin/sendsms
        1. ​Script: (см. след. сообщение)
          • Timeout: 10s
          • Process tags: no
          • Include event menu entry: no
          • Enabled: yes
        • (однократно на уровне системы Zabbix) Через веб-интерфейс (меню Administration → General → Macros) определить макросы {$KANNEL_USER} и {$KANNEL_PASSWORD} (задать их скрытыми, чтобы не показывать другим). Это credentials для доступа к системе Kannel.
        • для каждого пользователя – получателя SMS – нужно прописать его адрес доставки для данного канала уведомлений. Меню Administration → Users → пользователь → Media → Add, выбрать: Type: "SMS (Kannel)", Send to: номер телефона (остальное по умолчанию).
        • для каждого пользователя – получателя SMS – нужно создать действие для отсылки уведомлений по данному каналу. В графе "Operations" указываем конкретный канал доставки: "SMS (Kannel)".
        .
        Last edited by Kos; 31-01-2025, 11:14.

        Comment

        • Kos
          Senior Member
          Zabbix Certified SpecialistZabbix Certified Professional
          • Aug 2015
          • 3404

          #5
          Текст скрипта:
          Code:
            'use strict';
            const ascii = /^[ -~\t\n\r]+$/;
            try {
                //Variables and validation block.
                //"params" is an object holding parsed data from the "value" variable
                var params = JSON.parse(value);
                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_source !== '0' || params.tag_sms !== 'kannel') {
                    throw 'Ignore sending for non-triggered or non-tagged events';
                }
                if (params.kannel_user === '' || params.kannel_user === '{$KANNEL_USER}' || params.kannel_password === '' || params.kannel_password === '{$KANNEL_PASSWORD}') {
                    throw 'The credentials ("kannel_user" and "kannel_password") must be provided!';
                }
                if (params.to === '' || params.to === '{ALERT.SENDTO}') {
                    throw 'The valid phone number ("to") must be provided!';
                }
                if (params.to.startsWith('+')) {
                    params.to = params.to.substring(1);
                }
                if (params.to.length <= 8) {
                    params.to = '371' + params.to;
                }
                const url_start = params.url + '?username=' + params.kannel_user + '&password=' + encodeURIComponent(params.kannel_password)
                  +'&from=ZBX-sms&charset=UTF-8&coding=2&to=' + params.to + '&text=';
                var message = params.message.trim();
                var message_part;
                var req = new CurlHttpRequest();
                if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
                    request.SetProxy(params.HTTPProxy);
                }
                var full_url, resp;
                Zabbix.Log(4, '[Webhook Kannel] request value='+value+'; url_start='+url_start);
            
                //Logic block
                for (var i = 5; i > 0 && message.length > 0; i--) {
                    if (message.length <= 70 || (message.length <= 160 && ascii.test(message)) ) {
                        message_part = message;
                        i = 0; //it will be the last part
                    }
                    else {//either >160, or (>70 and contains non-ASCII): in any case, it is needed to be sent by parts
                        message_part = message.substring(0,160);
                        if (ascii.test(message_part)) {
                            message = message.substring(160);
                        }
                        else {//first 160 characters contain non-ASCII, it's needed be splitted on parts by 70 characters only
                            message_part = message.substring(0,70);
                            message = message.substring(70);
                        }
                    }
                    full_url = url_start + encodeURIComponent(message_part);
                    Zabbix.Log(4, '[Webhook Kannel] i='+i+'; webhook full_url='+full_url);
                    resp = req.Get(full_url,'');
                    Zabbix.Log(4, '[Webhook Kannel] response code: '+req.Status()+'; response: '+resp);
                    if (req.Status() < 200 || req.Status() >= 300 || resp.trim() != '0: Accepted for delivery') {
                        throw 'Response RC=' + req.Status() + '; ' + resp;
                    }
                }//for
            
                return 'OK';
            }
            catch (error) {
                Zabbix.Log(3, '[Webhook Kannel] ERROR: ' + error);
                throw 'Sending failed: ' + error;
            }

          Comment

          • Kos
            Senior Member
            Zabbix Certified SpecialistZabbix Certified Professional
            • Aug 2015
            • 3404

            #6
            В вашем случае, видимо, не нужно будет извращаться с формированием длинного URL, а вместо этого формировать нужный JSON, передаваемый в теле запроса.
            И ещё отличия:
            • использовать не класс CurlHttpRequest, а HttpRequest (этот класс был переименован в какой-то из прежних версий Zabbix);
            • использовать не метод этого класса Get() (который тоже был переименован в get()), а post();
            • метод Status() тоже был переименован в getStatus() (поменять в скрипте несколько раз);
            • перед вызовом метода put() добавить нужные заголовки:
            Code:
            req.addHeader('Content-Type: application/json');
            req.addHeader('Authorization: Basic ' + ваш_токен);
            Если нужны ещё какие-либо комментарии - спрашивайте.
            Last edited by Kos; 31-01-2025, 11:34.

            Comment

            • djin59
              Member
              • Jul 2023
              • 86

              #7
              Спасибо! с Вашей и ИИ помощью справился вот моё решение :

              Code:
              'use strict';
              
              try {
                  // Парсим входные данные
                  var params = JSON.parse(value);
                  
                  // Проверка обязательных параметров
                  if (!params.To || params.To.trim() === '') {
                      throw 'Параметр "To" обязателен!';
                  }
                  if (!params.Message || params.Message.trim() === '') {
                      throw 'Параметр "Message" обязателен!';
                  }
              
                  // Форматируем номер телефона
                  var msisdn = params.To.replace(/^\+/, ''); // Удаляем + в начале
                  
                  // Формируем тело запроса
                  var requestBody = {
                      messages: [{
                          content: { short_text: params.Message.trim() },
                          from: { sms_address: "ZZZZZZZZZZZZZ" },
                          to: [{ msisdn: msisdn }]
                      }]
                  };
                  
                  // Создаем HTTP-запрос
                  var req = new HttpRequest();
                  req.addHeader('Content-Type: application/json');
                  req.addHeader('Authorization: Basic ZZZZZZZZZZZZZZZZZZZZZZZZZZZ');
                  
                  // Настраиваем прокси (если требуется)
                  req.setProxy("http://ZZZZZZZZZZZZZZZZZZ:8080");
                  
                  // Отправляем POST-запрос
                  var response = req.post(
                      'https://ZZZZZZZZZZZZZZZZZZZu/messages',
                      JSON.stringify(requestBody)
                  );
                  
                  // Логирование
                  Zabbix.Log(4, '[SMS Webhook] Request body: ' + JSON.stringify(requestBody));
                  Zabbix.Log(4, '[SMS Webhook] Response: ' + response);
                  
                  // Проверяем статус ответа
                  if (req.getStatus() < 200 || req.getStatus() >= 300) {
                      throw 'HTTP Error: ' + req.getStatus() + ' - ' + response;
                  }
                  
                  return 'OK';
              }
              catch (error) {
                  Zabbix.Log(3, '[SMS Webhook] ERROR: ' + error);
                  throw 'Ошибка отправки: ' + error;
              }

              Comment

              Working...