Интеграция с Telegram-ботом. Пример: настройка приложения, Telegram и кода бота
Содержание
Введение
В этой статье разберём пример того, как настроить интеграцию Comindware Business Application Platform и Telegram-бота.
Telegram-бот будет представлять собой проект в Visual Studio на языке C# (Windows Forms Application).
Скачайте готовый проект Visual Studio с исходным кодом бота по ссылке: TelegramBotComindwareIntegration.zip
Также можно воспользоваться аналогичным кодом на языке Python в файле TelegramBotComplete.py
по ссылке: TelegramBotComindwareIntegrationPython.zip
Прикладная задача
Требуется создать Telegram-бот, в котором пользователь мог бы взаимодействовать с Comindware Business Application Platform.
Перед использованием бота пользователь должен пройти авторизацию следующим образом:
- При первом обращении бот запрашивает в адрес эл. почты пользователя.
- Бот ищет аккаунт с указанным адресом в Comindware Business Application Platform.
- Если аккаунт найден:
- бот высылает 4-значный код авторизации на эл. почту пользователя с помощью процесса в Comindware Business Application Platform;
- бот запрашивает код авторизации у пользователя в чате
- Если пользователь указывает верный код авторизации, авторизация считается пройденной.
Алгоритм авторизации
- На сервере выполняется бот, передающий данные между API Telegram и API Comindware Business Application Platform.
- Пользователь пишет боту сообщение в Telegram.
- Бот предлагает пользователю авторизоваться, указав адрес эл. почты, с которым пользователь зарегистрирован в Comindware Business Application Platform.
- Пользователь сообщает боту свой адрес эл. почты.
- Бот отправляет GET-запрос в Comindware Business Application Platform для получения данных аккаунтов в Системе.
- Бот получает JSON-ответ с данными аккаунтов и ищет среди них аккаунт с указанным адресом эл. почты.
- Если аккаунт найден, выполняется следующая процедура:
- Бот генерирует 4-значный код авторизации.
- Бот записывает код авторизации в атрибут аккаунта с помощью POST-запроса.
- С помощью POST-запроса бот отправляет эл. письмо пользователю с кодом авторизации.
- Пользователь указывает Telegram-боту код авторизации, полученный из эл. письма
- Если код, записанный в Comindware Business Application Platform и полученный ботом в последнем сообщении совпадают, авторизация считается пройденной.
- После прохождения авторизации пользователь может посредством бота инициировать действия в Comindware Business Application Platform.
Примечание
На основе созданного промежуточного ПО и примера настройки взаимодействия бота с Comindware Business Application Platform можно в дальнейшем реализовать различные сценарии: подача заявок, заявлений на отпуск, запрос какой-либо информации из системы и т.д.
Предварительная настройка со стороны Comindware Business Application Platform
-
Создайте шаблон аккаунта «Sotrudniki» (с таким же системным именем). В этом шаблоне уже есть системные атрибуты, такие как имя, почта и т.д.
-
Добавьте атрибут «ChatID» типа «Текст» (в нашем примере ID атрибута — op.13).
-
Добавьте атрибут «Proverochnyykod» типа «Текст» (в нашем примере ID атрибута — op.14).
-
Создайте и настройте шаблон процесса для отправки эл. почты пользователю (в нашем примере ID шаблона — pa.3).
-
В связанном с шаблоном процесса шаблоне записи создайте два атрибута типа «Текст»:
-
Код (в нашем примере ID атрибута — op.23) — значение этого атрибута процесс должен отправлять пользователю;
-
Кому (в нашем примере ID атрибута — op.24) — адрес, на который процесс должен отправлять код.
-
-
Примечание
В исходном коде промежуточного ПО замените ID и системные имена атрибутов и шаблонов на фактически используемые.
Настройка интеграции
- В Telegram найдите BotFather (https://t.me/BotFather) и запросите у него создание бота. Подробные инструкции см. в официальной документации Telegram.
- Скачайте и распакуйте проект для Visual Studio с промежуточным ПО по ссылке: TelegramBotComindwareIntegration.zip
-
Восстановите библиотеки с помощью команды Restore NuGet Packages: Newtonsoft.Json, RestSharp, Telegram.Bot и Telegram.bot.Extensions.Polling.
- При необходимости установите пакет .Net SDK 3.1.
-
Откройте файл
MainWindow.xaml
с формой приложения. -
Замените в разделе
Grid
значения атрибутовText
на фактические значения:<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Width="150" Height="30" Click="Button_Click" Grid.Row="0">Старт</Button>
<StackPanel Grid.Row="1">
<Label Height="25" Margin="10,5,0,5">Токен API Telegram-бота</Label>
<TextBox x:Name="apitoken" Text="введите токен API своего Telegram-бота" Width="240" Height="25"/>
</StackPanel>
<StackPanel Grid.Row="2">
<Label Height="25" Margin="10,5,0,5">Путь к API Comindware Business Application Platform</Label>
<TextBox x:Name="Apipath" Text="http://yourinstance/api/public/" Width="240" Height="25" />
</StackPanel>
<StackPanel Grid.Row="3">
<Label Height="25" Margin="10,5,0,5">Имя пользователя</Label>
<TextBox x:Name="login" Text="введите имя пользователя, у которого есть доступ к API Comindware Business Application Platform" Width="240" Height="25" />
</StackPanel>
<StackPanel Grid.Row="4">
<Label Height="25" Margin="10,5,0,5">Пароль</Label>
<PasswordBox x:Name="password" Password="введите пароль пользователя API Comindware Business Application Platform" Width="240" Height="25" />
</StackPanel>
</Grid>
-
Откройте файл
MainWindow.xaml.cs
с исходным кодом проекта и вставьте в него приведённый ниже код.using System.Windows;
using System;
using System.Threading;
using System.Threading.Tasks;
using Telegram.Bot;
using Telegram.Bot.Extensions.Polling;
using Telegram.Bot.Types;
namespace Telegram
{
public partial class MainWindow : Window
{
static ITelegramBotClient bot;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
bot = new TelegramBotClient(apitoken.Text);
var cts = new CancellationTokenSource();
var cancellationToken = cts.Token;
var receiverOptions = new ReceiverOptions
{
AllowedUpdates = { }, // receive all update types
};
bot.StartReceiving(
HandleUpdateAsync,
HandleErrorAsync,
receiverOptions,
cancellationToken
);
MessageBox.Show("Бот запущен");
}
public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
try
{
if (update.Type == Telegram.Bot.Types.Enums.UpdateType.Message)
{
var message = update.Message;
await bot.SendTextMessageAsync(message.Chat.Id, "Вы написали мне: " + message.Text, Telegram.Bot.Types.Enums.ParseMode.Markdown);
}
}catch { }
}
public async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
{
MessageBox.Show("Ошибка " + exception.Message);
}
}}
-
Сохраните файл.
-
Скомпилируйте и запустите приложение.
- В окне приложения нажмите кнопку «Старт» и подтвердите запуск ПО.
- Напишите в Telegram-бот сообщение, например: «Привет».
-
Бот должен ответить: «Вы написали мне: Привет».
Примечание
Вы можете воспользоваться аналогичным кодом простейшей реализации бота на языке Python из файла
TelegramBotPrimer.py
по ссылке: TelegramBotComindwareIntegrationPython.zipЗапуск бота
-
Для взаимодействия с Comindware Business Application Platform воспользуемся Solution API.
-
Допишите
/Docs/SolutionApi/
в адресной строке браузера после адреса экземпляра Comindware Business Application Platform. -
Отобразится страница Swagger с перечнем доступных методов Solution API.
Переход в область SolutionApi
Примечание
На последующих шагах используйте готовый исходный код (TelegramBotComindwareIntegration.zip) или копируйте приведённые ниже фрагменты кода.
-
Добавьте в файл
MainWindow.xaml.cs
две функции:-
Get()
будет делать GET-запрос для получения данных из шаблона аккаунта «Sotrudniki». Результатом будет JSON-ответ. -
ValueFromJSON()
будет извлекать из этого ответа нужный атрибут.private string Get(string OA_system_name)
{
var client = new RestClient(Domain);
client.Authenticator = new HttpBasicAuthenticator(Login, Password);
var request = new RestRequest("solution/" + OA_system_name, Method.Get);
request.AddHeader("Accept", "application/json" );
var response = client.Execute(request);
return response.Content;
}
private string ValueFromJSON(string data, string attribute_name, string chat_id)
{
var doc = JsonDocument.Parse(data);
JsonElement root = doc.RootElement;
var users = root.EnumerateArray();
while (users.MoveNext())
{
var user = users.Current;
var props = user.EnumerateObject();
string value_ = "" , chat_id_ = "";
while (props.MoveNext())
{
var prop = props.Current;
if (prop.Name.ToLower() == attribute_name.ToLower())
{
value_ = prop.Value.ToString();
}
if (prop.Name.ToLower() == "chatid" )
{
chat_id_ = prop.Value.ToString();
}
}
if (chat_id_ == chat_id)
{
return value_;
}
}
return "";
}
-
- Теперь при запуске промежуточного ПО Telegram-бот запросит авторизацию.
-
Реализуем процесс авторизации следующим образом: если пользователь по ChatID не найден, то будем рассматривать 3 варианта:
- сообщение содержит символ '@', следовательно в сообщении указат адрес эл. почты — запускаем процесс отправки 4-значного кода;
- длина сообщения — 4 символа — проверка отправленного кода на соответствие;
- во всех остальных случаях бот отвечает: «Укажите адрес эл. почты для авторизации».
-
Добавьте в файл
MainWindow.xaml.cs
следующую функцию для обработки сообщений от пользователя.public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
try
{
if (update.Type == Telegram.Bot.Types.Enums.UpdateType.Message)
{
var message = update.Message;
string data = Get("Sotrudniki");
if (ValueFromJSON(data, "ChatID", message.Chat.Id.ToString()) == "")
{
if (message.Text.Contains("@"))
{
var doc = JsonDocument.Parse(data);
JsonElement root = doc.RootElement;
var users = root.EnumerateArray();
while (users.MoveNext())
{
var user = users.Current;
var props = user.EnumerateObject();
string account_id = "", current_email = "";
while (props.MoveNext())
{
var prop = props.Current;
if (prop.Name.ToLower() == "mbox")
{
current_email = prop.Value.ToString();
}
if (prop.Name.ToLower() == "id")
{
account_id = prop.Value.ToString();
}
}
if (current_email.ToLower() == message.Text.ToLower())
{
var symbols = "0123456789";
string code = "";
var random = new Random();
for ( int i = 0; i < 4; i++)
{
code += symbols[random.Next(symbols.Length)].ToString();
}
// найденному пользователю в системе проставим ChatID с пометкой _NA (т.е. не авторизован)
// и сгенерированный 4-х значный код
var data_ = new Dictionary<string, object >
{
{"op.13", message.Chat.Id.ToString() + "_NA"},//ChatId
{"op.14", code}//Proverochnyykod
};
var client = new RestClient(Domain);
client.Authenticator = new HttpBasicAuthenticator(Login, Password);
var request = new RestSharp.RestRequest("system/TeamNetwork/ObjectService/Edit", Method.Post); // POST-запрос к найденному пользователю для обновления данных
request.AddHeader("content-type", "application/json");
var sendData = new Dictionary<string, object >
{
{"objectId", account_id},
{"objectData", data_ }
};
request.AddParameter("application/json", JsonSerializer.Serialize(sendData), ParameterType.RequestBody);
client.Execute(request);
// запустим процесс отправки сгенерированного кода на email
var data_for_proccess = new Dictionary<string, object >
{
{"op.23", code}, // Код
{"op.24", current_email} // Кому
};
request = new RestSharp.RestRequest("system/Process/ProcessObjectService/Create1", Method.Post);
request.AddHeader("content-type", "application/json");
data_ = new Dictionary<string, object>
{
{"processAppId", "pa.3"}, // process_id
{"objectName", null},
{"syncActivityQuantity", 2},
{"objectData", data_for_proccess}
};
request.AddParameter("application/json", JsonSerializer.Serialize(data_), ParameterType.RequestBody);
client.Execute(request);
await bot.SendTextMessageAsync(message.Chat.Id, "На указанную почту отправлено письмо с 4-значным кодом, введите его ниже для авторизации");
}
}
}
else if (message.Text.Length == 4)
{
string value = ValueFromJSON(data, "Proverochnyykod", message.Chat.Id.ToString() + "_NA");
if (message.Text == value )
{
// у ChatID убираем пометку "_NA" и очищаем поле "Проверочный код"
var data_ = new Dictionary<string, object >
{
{"op.13", message.Chat.Id.ToString()},//ChatId
{"op.14", null}//Proverochnyykod
};
var client = new RestClient(Domain);
client.Authenticator = new HttpBasicAuthenticator(Login, Password);
value = ValueFromJSON(data, "id", message.Chat.Id.ToString() + "_NA");
var request = new RestSharp.RestRequest("system/TeamNetwork/ObjectService/Edit", Method.Post);
request.AddHeader("content-type", "application/json");
var sendData = new Dictionary<string, object>
{
{"objectId", value},
{"objectData", data_}
};
request.AddParameter("application/json", JsonSerializer.Serialize(sendData), ParameterType.RequestBody);
client.Execute(request);
await bot.SendTextMessageAsync(message.Chat.Id, "Вы успешно авторизованы");
}
}
else
{
await bot.SendTextMessageAsync(message.Chat.Id, "Укажите адрес эл. почты для авторизации");
}
}
else
{
string name = ValueFromJSON(data, "fullName", message.Chat.Id.ToString());
await bot.SendTextMessageAsync(message.Chat.Id, "Добрый день, " + name + "! Вы успешно авторизованы");
}
}
}
catch { }
}
public async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
{
MessageBox.Show("Ошибка " + exception.Message);
}
-
Протестируйте работу промежуточного ПО и Telegram-бота.
Авторизация через бот
Эта статья была полезна 2 чел.