User Tools

Site Tools


telegram

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
telegram [2025/04/16 12:05] – created walhitelegram [2025/10/23 09:05] (current) walhi
Line 33: Line 33:
 req.childAdd("cnt").setAttr("name", "disable_notification").setText("true"); req.childAdd("cnt").setAttr("name", "disable_notification").setText("true");
 tr.messIO(req,"HTTP"); tr.messIO(req,"HTTP");
 +</code>
 +
 +===== Получение сообщений =====
 +
 +Для получения сообщений используется метод ''getUpdates'' [[https://telegram-bot-sdk.readme.io/reference/getupdates|Telegram API]]. Ответы от сервера приходят в формате JSON. Данный формат не поддерживается "из коробки", однако сообществом разработана [[json|библиотека]], которая преобразует JSON строку в объект, с которым удобно работать в JavaLikeCalc.
 +
 +В коде ниже используются 3 переменных.
 +|Имя|Тип|Описание|
 +|Transport|Строка|Имя транспорта в "Транспорты > SSL"|
 +|APIKey|Строка|Ключ, полученный от @BotFather|
 +|updateId|Целочисленный|ID последнего полученного сообщения, при первом запуске значение 0|
 +
 +<code java>
 +jsonLib = SYS.DAQ.JavaLikeCalc.lib_Json;
 +
 +tr = SYS.Transport.SSL.nodeAt("out_" + Transport);
 +
 +messagesCount = 1;
 +
 +while(messagesCount){
 +    updateId += 1;
 +    req = SYS.XMLNode("POST");
 +    req.setAttr("URI", "/bot" + APIKey + "/getUpdates");
 +    req.childAdd("cnt").setAttr("name", "offset").setText(updateId.toString());
 +    tr.messIO(req,"HTTP");
 +
 +    deser_err = "";
 +    outputObject = jsonLib.deserialize(req.text(), deser_err);
 +
 +    messagesCount = outputObject.result.length;
 +    for (var i = 0; i < outputObject.result.length; i++){
 +        item = outputObject.result[i];
 +        updateId = max(updateId, item.update_id);
 +        username = item.message.from.username;
 +        chatID = item.message.from.id;
 +        messageText = item.message.text;
 +    }
 +}
 +</code>
 +
 +Данный код будет загружать все доступные сообщения. Между вызовами требуется хранить последнее значение ''updateId'', так как этот параметр позволяет пропускать уже обработанные сообщения
 +
 +
 +===== Библиотека для работы =====
 +
 +Данные примеры кода стоит оформить в виде библиотеки в Сбор данных -> Вычислитель на Java-подобном языке -> Библиотека. Так будет гораздо удобнее использовать код повторно. 
 +
 +===== Отправка оповещений группе пользователей =====
 +
 +Обычно телеграм бот нужен для оповещений об аварийных ситуациях. И оповещать приходится группу сотрудников. 
 +
 +Где брать список абонентов, которым рассылать оповещения? Логично было бы использовать список пользователей OpenSCADA и добавлять их в дополнительную группу. Так будет проще управлять списком получателей.
 +
 +Где хранить ID пользователя Telegram? Логично, что в описании пользователя OpenSCADA. В поле "Описание" можно хранить все, что необходимо. Если таких параметров конфигурации требуется больше чем один, то не проблема. По одному в строку в формате ''<TYPE>:<VALUE>''. В моем случае в данном поле хранятся телефон, адрес почты и ID пользователя Telegram.
 +
 +
 +В коде ниже есть 4 переменных.
 +|Имя|Тип|Описание|
 +|Transport|Строка|Имя транспорта в "Транспорты > SSL"|
 +|Group|Строка|Имя группы пользователей для оповещения|
 +|APIKey|Строка|Ключ, полученный от @BotFather|
 +|Message|Строка|Сообщение |
 +<code java>
 +TelegramLib = SYS.DAQ.JavaLikeCalc.lib_Telegram;
 +
 +users = SYS.Security.nodeList("usr_");
 +
 +for (var j = 0; j < users.length; j++){
 +    user = SYS.Security.nodeAt(users[j]);
 +    
 +    // Пропуск пользователей, которым не разрешены уведомления
 +    if (user.groups().indexOf(Group) == -1) continue;
 +    
 +    // Обработка сохраненных транспортов для уведомлений
 +    transports = user.cfg("LONGDESCR");
 +    for(offset = 0; (transport = transports.parse(0, "\n", offset)).length; ){
 +        tmp = transport.split(":");
 +        TransportType = tmp[0];
 +        TransportValue = tmp[1];
 +        
 +        if (TransportType == "telegram"){
 +            TelegramLib.SendMessage(Transport, APIKey, TransportValue, Message);
 +            break;
 +        }
 +    }
 +}
 +</code>
 +
 +
 +===== Отправка журнала ошибок =====
 +
 +Выше есть код для массовой отправки сообщений, но добавлять в каждый обработчик датчика код для отправки - плохая идея. Обработчик должен формировать сообщение в журнал, а отдельный виртуальный контроллер отправлять сообщения из журнала по какому-то каналу связи.
 +
 +При помощи функции ''SYS.Archive.messGet'' запрашиваем все сообщения за определенный период, которые подходят под указанную категорию. Категорией может быть просто звездочка для всех сообщений или немного сложнее. Можно и регулярным выражением воспользоваться при необходимости.
 +
 +
 +В коде ниже есть 7 переменных.
 +|Имя|Тип|Описание|
 +|TelegramTransport|Строка|Имя транспорта в "Транспорты > SSL"|
 +|TelegramAPIKey|Строка|Ключ, полученный от @BotFather|
 +|TelegramGroup|Строка|Имя группы пользователей для оповещения через Telegram|
 +|MessagesLevel|Строка|Минимальный уровень сообщений из журнала |
 +|MessagesCat|Строка|Категория сообщений из журнала |
 +|TimeBegin|Целый|Время начала|
 +|utmLast|Целый|Микросекунды последнего сообщения|
 +
 +<code java>
 +using Special.FLibSYS;
 +TelegramLib = SYS.DAQ.JavaLikeCalc.lib_Telegram;
 +
 +if (f_start){
 +    TimeBegin = SYS.time();
 +}
 +
 +// Запрос сообщений по шаблону
 +TimeFinish = SYS.time();
 +messages = SYS.Archive.messGet(TimeBegin, TimeFinish, MessagesCat, MessagesLevel);
 +
 +// Обновляем время для следующей итерации
 +TimeBegin = TimeFinish;
 +utmLast = -1;
 +for (var i = 0; i < messages.length; i++){
 +    message = messages[i];
 +    tm = message.tm;
 +    if ((TimeBegin == tm) && (utmLast > message.utm)) continue;
 +    utmLast = message.utm; // Сохраняем микросекунды для следующей итерации
 +    TimeStr = tmFStr(tm,"%d.%m.%Y %H:%M:%S");
 +    messageText = TimeStr + ": " + message.mess;
 +    
 +    TelegramLib.SendAll(TelegramTransport, TelegramGroup, TelegramAPIKey, messageText);
 +}
 </code> </code>
telegram.1744805133.txt.gz · Last modified: 2025/04/16 12:05 by walhi

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki