<< Click to Display Table of Contents >> Navigation: Проект в MasterSCADA 4D > Рекомендации по созданию проектов > Взаимодействие MasterSCADA 4D с API Telegram |
Важно! Работать с программой Telegram можно используя программы C#, где реализуется взаимодействие с мессенджером. Текст программы зависит от разработчика проекта. В справочной системе рассмотрим пример работы с API Telegram.
Для работы MasterSCADA 4D с API Telegram необходимо:
•создать программу C#
•подключить пространство имён и пакет NuGet в легенде.
•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;
•WTelegramClient 2.1.2
Можно организовать программу на языке 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;
}
}
}