Взаимодействие MasterSCADA 4D с API Telegram

<< Click to Display Table of Contents >>

Navigation:  Проект в MasterSCADA 4D > Рекомендации по созданию проектов >

Взаимодействие MasterSCADA 4D с API Telegram

Важно! Работать с программой Telegram можно используя программы C#, где реализуется взаимодействие с мессенджером. Текст программы зависит от разработчика проекта. В справочной системе рассмотрим пример работы с API Telegram.

Необходимое для работы

Для работы MasterSCADA 4D с API Telegram необходимо:

создать программу C#

подключить пространство имён и пакет NuGet в легенде.

 

Vzaimodejstvie_MasterSCADA_4D_s_API_Telegram

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

using TL;

using System.Xml.Linq;

 

Vzaimodejstvie_MasterSCADA_4D_s_API_Telegram_1

WTelegramClient 2.1.2

Пример программы C#

Можно организовать программу на языке C#, которая прочитает из файла настроек параметры для отправки (логин или номер телефона, код авторизации и др.), отправит произвольное сообщение и сформирует лог-файл.

Компания МПС софт предлагают библиотеку, которая реализует вышеописанную задачу. Получить ее можно при обращении в HelpDesk систему технической поддержки.

Важно! С версии 1.3.5 библиотека TelegramClient включена в стандартную сборку, её можно подключить самостоятельно.

Порядок работы с библиотекой описан в разделе Пример взаимодействия MasterSCADA 4D с API Telegram

В поставляемой библиотеке написана следующая программа на языке С#:

 

public sealed class Program : ScriptBase

{

   WTelegram.Client client;

TL.User my;

static string fullConfigName;

static string LogPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\TelegramClient.log";

static bool UseLog=true;

 

int ActionNum = 0; //счётчик вызова частей программы, например сколько раз запускался Execute с момента старта RT

string ValidUserID = ""; //здесь будем хранить идентификатор пользователя Телеграм от которого будем (разрешим) принимать сообщения

 

//Действие №1

public override void Init()

{

 

  Log(ActionNum, "Работает метод Init");

 

   Ошибка=false;

     ТекстОшибки="";

 

  try

   {

      //Читаем настройки

       TMS.ReadConfig();

   

      Log(ActionNum, "#########################################################################" +

          Environment.NewLine + "Текущие настройки:");

      Log(ActionNum, "ТелефонОтправителя: " + TMS.ТелефонОтправителя);

      Log(ActionNum, "КодАвторизации: " + TMS.КодАвторизации);

      Log(ActionNum, "api_id: " + TMS.api_id);

      Log(ActionNum, "api_hash: " + TMS.api_hash);

      Log(ActionNum, "ПослатьПоНомеру: " + TMS.ПослатьПоНомеру.ToString());

      Log(ActionNum, "НомерТелефона: " + TMS.НомерТелефона);

      Log(ActionNum, "ПослатьПоНику: " + TMS.ПослатьПоНику.ToString());

      Log(ActionNum, "Ник: " + TMS.Ник);

      Log(ActionNum, "ПутьКонфигурации: " + TMS.ПутьКонфигурации);

      Log(ActionNum, "ПутьЛогФайла: " + TMS.ПутьЛогФайла);

      Log(ActionNum, "ИспользоватьЛогФайл: " + TMS.ИспользоватьЛогФайл.ToString());        

      Log(ActionNum, "#########################################################################");

       

           

       ТелефонОтправителя = TMS.ТелефонОтправителя;

       КодАвторизации =  TMS.КодАвторизации;

       

       api_id = TMS.api_id;

       api_hash = TMS.api_hash;

       

       ПослатьПоНомеру = TMS.ПослатьПоНомеру;

       НомерТелефона = TMS.НомерТелефона;

       ПослатьПоНику = TMS.ПослатьПоНику;

       Ник = TMS.Ник;

 

       ПутьКонфигурации = TMS.ПутьКонфигурации;

       ПутьЛогФайла = TMS.ПутьЛогФайла;

       ИспользоватьЛогФайл = TMS.ИспользоватьЛогФайл;                

   }

    catch (Exception Ex)

       {

       Ошибка=true;

           ТекстОшибки="Ошибка при чтении настроек из файла: " + Ex.Message;

       }

           

  //переопределяем путь к конфигурационному файлу

  if (ПутьКонфигурации.Length == 0) {ПутьКонфигурации = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);}

   fullConfigName=Path.Combine(ПутьКонфигурации,ТелефонОтправителя.Replace(@"+", "")  + "WTelegram.session");

 

  //переопределяем логирование в соответствии с настройками

  if (ПутьЛогФайла.Length > 0) {    LogPath = ПутьЛогФайла;    } else {ПутьЛогФайла = LogPath;}

   UseLog = ИспользоватьЛогФайл;

   

 

  if (TMS.ТелефонОтправителя == "+70000000000")

   {

       ТекстОшибки="Необходимо произвести настройку подключения";

      return;

   }

 

  try{

 

      Log(ActionNum, "Запускаем в асинхронном режиме инициализацию приложения Telegram - Myini и ждём завершения задачи");

 

      Myinit().Wait();

 

      Log(ActionNum, "Инициализация приложения Telegram - Myini завершена");

       }

        catch (Exception Ex)

       {

      //заполняем параметры ошибки

       Ошибка=true;

           ТекстОшибки=TMS.ErrorHandling(Ex.Message);

       }

}

 

//Действие №2

async Task Myinit()

{

   ActionNum++;

  Log(ActionNum, "Работает: Myinit");

       

       

   WTelegram.Helpers.Log = Log;

 

  //получаем экземпляр приложения Telergam, передавая настройки

   client=new WTelegram.Client(Config);

 

   

    //сведения о пользователе Telergam

    my = await client.LoginUserIfNeeded();

   

  //переопределяем обработчик события обновления данных приложения (будем обрабатывать входящие сообщения)    

    client.Update += client_Update;

   

}

 

//Действие №3

//Задача, выполняемая периодически или по вызову (см. свойство "Задачи.Способ исполнения" для ссылки на ФБ.TelegramSendMessage)

public override void Execute()

{

   

  switch (Задача)

       {

          case 1:                   //отправляем сообщение

                  SendMessage();

                  break;

          case 2:                   //сохраняем конфигурацию

                  SaveConfig();

                  break;

              case 3:                   //перезапускаем подключение к Telegram

                  RestartClient();

                  break;

       }

   

   Задача = 0;

   

}

 

 

static string Config(string what)

       {

          switch (what)

           {

              case "api_id": return TMS.api_id;

              case "api_hash": return TMS.api_hash;

              case "phone_number": return TMS.ТелефонОтправителя; //phone_numberFrom;

              case "session_pathname": return fullConfigName;//полное имя конфига          

      case "verification_code": return TMS.КодАвторизации;

              default: return null;                 // let WTelegramClient decide the default config

           }

       }

 

 

//обработчик события обновления данных приложения (будем обрабатывать входящие сообщения)    

private void client_Update(IObject obj)

{

  if (obj is not UpdatesBase updates) return;

 

  foreach (var update in updates.UpdateList)

  switch (update)

   {

      case UpdateNewMessage unm:

          DisplayMessage(unm.message);

          break;

      case UpdateEditMessage uem:

          DisplayMessage(uem.message, true);

          break;

      default:

          Log(ActionNum, update.GetType().Name);

          break; // there are much more update types than the above cases

   }

 

}

 

//выводим (обрабатываем) входящее сообщение от пользователя, которому мы отправляли сообщение

private void DisplayMessage(MessageBase messageBase, bool edit = false)

{    

  if (messageBase ==null) {return;}

   

  switch (messageBase)

   {

      case TL.Message m:

          if  (m.peer_id.ToString() == ValidUserID && ValidUserID != "") {

              //здесь нужно вставить вызов обработки входящего сообщения, например вызов программы, которая что-нибудь запускает    

               ТекстОшибки = "Входящее сообщение: " + m.message + " от " + m.peer_id.ToString();

           }

          break;

      case MessageService ms:

          break;

   }

}        

 

//метод, отвечающий за отправку сообщения

private void SendMessage()

{

 

  Log(ActionNum, "Отправляем сообщение: " + ПосылаемыеДанные);    

 

  if (ПосылаемыеДанные.Length == 0) {return;}

         

  try

   {

       

      if (ПослатьПоНомеру &&  !String.IsNullOrWhiteSpace(НомерТелефона))

           {

          Log(ActionNum, "Будем запускать: SendNumber");                

              #pragma warning disable CS4014

              SendNumber(ПосылаемыеДанные);

              #pragma warning restore CS4014

           }

          else if(ПослатьПоНику && !String.IsNullOrWhiteSpace(Ник)) //Посылака по нику БЕЗ @

           {

          Log(ActionNum, "Будем запускать: SendNick");                    

              #pragma warning disable CS4014

              SendNick(ПосылаемыеДанные);

              #pragma warning restore CS4014

           }

       Ошибка=false;

           ТекстОшибки= "Отправлено сообщение: " +ПосылаемыеДанные;

       ПосылаемыеДанные  = "";

       }

  catch (Exception Ex)

       {

      Log(ActionNum, "Ошибка при отправке сообщения: " + Ex.Message);            

       Ошибка=true;

           ТекстОшибки=Ex.Message;

       }

}

 

  //отправляем сообщение по номеру телефона

    public async Task SendNumber(string Message)

   {

   ActionNum++;

        Log(ActionNum, "Запускаем: SendNumber");

 

  try

          {

          var contactsList = await client.Contacts_GetContacts();

          long tmpAccessHash = 0;

          long tmpId = 0;

          foreach (var currContact in contactsList.users)

           {

          string s = НомерТелефона;

         

              if (currContact.Value.phone.Contains(s.Replace(@"+", "")))

               {

                   tmpAccessHash = currContact.Value.access_hash;

                   tmpId = currContact.Value.ID;

                  break;

               }

           }

 

          if (tmpId != 0 && tmpAccessHash != 0)

           {

               InputPeerUser ipu = new InputPeerUser

               {

                   user_id = tmpId,

                   access_hash = tmpAccessHash

                       

               };

       ValidUserID = "user " + ipu.user_id.ToString();

              await client.SendMessageAsync(ipu, Message);

              //Ошибка=false;

              //ТекстОшибки="";

          }

       }

      catch (Exception Ex)

       {

           Ошибка=true;

           ТекстОшибки=Ex.Message;

       }

       

   }

  //отправляем сообщение по нику БЕЗ символа "@"

public async Task SendNick(string Message)

   {

   ActionNum++;

    Log(ActionNum, "Запускаем: SendNick");

 

  try

          {

          var NickData = await client.Contacts_ResolveUsername(Ник);        

       ValidUserID = NickData.peer.ToString();

       

          await client.SendMessageAsync(NickData, Message);

              //Ошибка=false;

            //ТекстОшибки="";

          }

      catch (Exception Ex)

       {

           Ошибка=true;

           ТекстОшибки=Ex.Message;

       }

       

   }

 

 

//сохраняем настройки из параметров, значения которых передаются из формы, в файл

private void SaveConfig()

{

               

   TMS.ТелефонОтправителя =  ТелефонОтправителя;

   TMS. КодАвторизации = КодАвторизации;

   TMS.api_id = api_id;

   TMS.api_hash = api_hash;

       

   TMS.ПослатьПоНомеру = ПослатьПоНомеру;

   TMS.НомерТелефона  = НомерТелефона;

   TMS.ПослатьПоНику = ПослатьПоНику;

   TMS.Ник = Ник;        

 

   TMS.ПутьКонфигурации = ПутьКонфигурации;

   TMS.ПутьЛогФайла = ПутьЛогФайла;

   TMS.ИспользоватьЛогФайл = ИспользоватьЛогФайл;

   

   TMS.WriteConfig();

   

   ТекстОшибки="Конфигурация сохранена";

   

}

 

 

//перезапуск клиента

private void RestartClient()

{

  Log(ActionNum, "Закрываем подключение к Telegram");    

 

  try {

       client?.Dispose();

      Log(ActionNum, "Подключение к Telegram закрыто");    

       }

  catch (Exception Ex)

       {

      Log(ActionNum, "Ошибка при закрытии подключения к Telegram: " + Ex.Message);            

       Ошибка=true;

           ТекстОшибки=Ex.Message;

       }

   

  //инициализация приложения

  Init();

}

 

private static void Log(int arg1, string arg2)

       {

    #pragma warning disable CS0162

    if(UseLog)

        {

              using StreamWriter sw = File.AppendText(LogPath);

               sw.WriteLine(DateTime.UtcNow+": arg1 = " + arg1+ " | "+"arg2 = "+arg2);

               }

    #pragma warning restore CS0162

       }

 

//класс, отвечающий за чтение и сохранение настроек

public static class TMS

{

 

  public static string ТелефонОтправителя  { get; set; }

  public static string КодАвторизации { get; set; }

  public static string api_id  { get; set; }

  public static string api_hash  { get; set; }

  public static bool ПослатьПоНомеру  { get; set; }

  public static string НомерТелефона   { get; set; }

  public static bool ПослатьПоНику  { get; set; }

  public static string Ник   { get; set; }

  public static string ПутьКонфигурации  { get; set; }

  public static string ПутьЛогФайла   { get; set; }

  public static bool ИспользоватьЛогФайл    { get; set; }

   

  private static string cfg = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\TelegramSendMessageSettings.xml";

           

  public static void WriteConfig()

   {

       

      try

       {

           XDocument d = new XDocument(

              new XElement("Настройки",  

                                      new XElement("Отправитель",

                                                                new XElement("ТелефонОтправителя",  ТелефонОтправителя),

                                                          new XElement("КодАвторизации", КодАвторизации),

                                                          new XElement("api_id", api_id),

                                                          new XElement("api_hash", api_hash)

                                                                ),

                                      new XElement("Получатель",

                                                                new XElement("ПослатьПоНомеру",  ПослатьПоНомеру),

                                                          new XElement("НомерТелефона", НомерТелефона),

                                                          new XElement("ПослатьПоНику", ПослатьПоНику),

                                                          new XElement("Ник", Ник)

                                                                ),

                                      new XElement("Параметры",

                                                                new XElement("ПутьКонфигурации",  ПутьКонфигурации),

                                                          new XElement("ПутьЛогФайла", ПутьЛогФайла),

                                                          new XElement("ИспользоватьЛогФайл", ИспользоватьЛогФайл)

                                                                )                                                                              

                               )

               );

           d.Declaration = new XDeclaration("1.0", "utf-8", "true");

           d.Save(cfg);                        

       }

      catch (Exception Ex)

           {

          throw new Exception(Ex.Message);

           }                          

   }

   

  public static void ReadConfig()

   {

 

      try

       {

       

          if (System.IO.File.Exists(cfg))

               {

           

               XDocument d = XDocument.Load(cfg);

               

              //Данные отправителя        

               XElement sender = d.Descendants("Отправитель").First();            

 

               TMS.ТелефонОтправителя = sender.Element("ТелефонОтправителя").Value.ToString();            

               TMS.КодАвторизации = sender.Element("КодАвторизации").Value.ToString();

               TMS.api_id = sender.Element("api_id").Value.ToString();

               TMS.api_hash = sender.Element("api_hash").Value.ToString();

 

           

              //Данные получателя

               XElement reciever = d.Descendants("Получатель").First();        

               TMS.ПослатьПоНомеру =  Convert.ToBoolean(reciever.Element("ПослатьПоНомеру").Value);

               TMS.НомерТелефона =reciever.Element("НомерТелефона").Value.ToString();

               TMS.ПослатьПоНику =Convert.ToBoolean(reciever.Element("ПослатьПоНику").Value);

               TMS.Ник = reciever.Element("Ник").Value.ToString();    

   

              //Параметры

               XElement options = d.Descendants("Параметры").First();        

               TMS.ПутьКонфигурации =  options.Element("ПутьКонфигурации").Value.ToString();

               TMS.ПутьЛогФайла =options.Element("ПутьЛогФайла").Value.ToString();

               TMS.ИспользоватьЛогФайл =Convert.ToBoolean(options.Element("ИспользоватьЛогФайл").Value);            

           }

          else

           {

              //Данные отправителя        

               TMS.ТелефонОтправителя = "+70000000000";            

               TMS.КодАвторизации = "";

               TMS.api_id = "Укажите api_id";

               TMS.api_hash = "Укажите api_hash";

           

              //Данные получателя

               TMS.ПослатьПоНомеру = true;

               TMS.НомерТелефона ="+70000000000";

               TMS.ПослатьПоНику =false;

               TMS.Ник = "";    

   

              //Параметры

               TMS.ПутьКонфигурации = "";

               TMS.ПутьЛогФайла ="";

               TMS.ИспользоватьЛогФайл =true;            

           }

       

       }

      catch (Exception Ex)

           {

          throw new Exception(Ex.Message);

           }        

           

   }

   

  //Обработчик сообщений об ошибках от Telegram

  public static string ErrorHandling(string ErrMessage)

   {

      string ret = ErrMessage + Environment.NewLine;    

 

      switch (ErrMessage) {            

      case "One or more errors occurred. (PHONE_CODE_INVALID)":

           ret = ret + "Укажите код подтверждения из служебного уведомления Telrgram, сохраните настройки и  повторите попытку подключения";

          break;

      case "One or more errors occurred. (The input is not a valid hex string as it contains a non-hex character.)":            

           ret = ret + "Проверьте настройку api_hash";        

          break;

      default:

          break;            

       }

      return ret;

       

   }

}

 

 

}