Comindware интеграция с Telegram-ботом
В этой статье разберём пример того, как настроить интеграцию Comindware Business Application Platform и Telegram-бота. Программу будем разрабатывать в Visual Studio на языке C# (Windows Forms Application).
Алгоритм взаимодействия будет такой:
- Пользователь пишет боту сообщение.
- Бот предлагает ему авторизоваться, указав email, через который пользователь зарегистрирован в продукте Comindware Business Application Platform.
- Пользователь указывает боту свой email.
- Бот отправляет GET-запрос в продукт Comindware Business Application Platform для получения данных аккаунтов в продукте.
- Бот получает JSON-ответ с данными аккаунтов и ищет среди них аккаунт с указанным email адресом.
- В случае нахождения аккаунта происходят следующие действия:
- Бот генерирует 4-х значный код и отправляет его Telegram-боту.
- Этот же код он записывает через POST-запрос в атрибут в карточке аккаунта (в шаблоне аккаунта).
- Через второй POST-запрос бот запускает процесс отправки email-сообщения пользователю с кодом.
- Пользователь указывает Telegram-боту код, полученный из email-сообщения.
- Если код, записанный в продукте Comindware Business Application Platform и полученный последним сообщением совпадают, авторизация проходит успешно.
Предварительная настройка со стороны Comindware Business Application Platform
1. Создайте шаблон аккаунта — Сотрудники (в нашем примере системное имя — Sotrudniki). В этом шаблоне уже есть системные атрибуты, такие как имя, почта и т.д.
2. Добавьте атрибут с типом данных «Текст» — ChatID (в нашем примере ИД — op.13).
3. Добавьте атрибут с типом данных «Текст» — Proverochnyykod (в нашем примере ИД — op.14).
4. Создайте шаблон процесса для отправки email (в нашем примере ИД — pa.3), в связанном шаблоне записи создайте два атрибута с типом данных «Текст»: Код (в нашем примере ИД — op.23) и Кому (в нашем примере ИД — op.24).
Настройка интеграции
1. Создайте новый проект WPF в Visual Studio, и подключите библиотеки через Manage NuGet packages: Newtonsoft.Json, RestSharp, Telegram.Bot и Telegram.bot.Extensions.Polling.
2. В Telegram найдите BotFather и запросите у него создание бота. Больше информации по ссылке.
3. Создайте графическую форму для запуска приложения и замените элемент Grid приведенным ниже кодом. У элементов <TextBox> измените значения атрибутов Text на соответствующие.
<Grid> <Grid.RowDefinitions > <RowDefinition Height ="0.5*"/> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions > <Button Width ="150" Height="30" Click ="Button_Click">Старт</ Button >
<StackPanel Grid.Row ="1"> <Label Height ="25" Margin="10,5,0,5"> Api-token для бота </Label> <TextBox x :Name="apitoken" Text ="yourtoken" Width="240" Height ="25"></TextBox> </StackPanel > <StackPanel Grid.Row ="2"> <Label Height ="25" Margin="10,5,0,5"> Путь к APi платформы </Label> <TextBox x :Name="Apipath" Text ="http://yourinstance/api/public/" Width="240" Height ="25" ></TextBox> </StackPanel > <StackPanel Grid.Row ="3"> <Label Height ="25" Margin="10,5,0,5"> Логин </Label> <TextBox x :Name="login" Text ="yourlogin" Width="240" Height ="25" ></TextBox> </StackPanel > <StackPanel Grid.Row ="4"> <Label Height ="25" Margin="10,5,0,5"> Пароль </Label> <PasswordBox x :Name="password" Password ="yourpassword" Width="240" Height ="25" ></PasswordBox> </StackPanel > </Grid> |
4. Скопируйте код ниже и вставьте его в файл с кодом проекта.
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); } }} |
5. Сохраните настройки и запустите программу. После этого бот должен стать доступен.
Запуск бота
6. Для взаимодействия с Comindware Business Application Platform воспользуемся Solution API. Допишите "Docs/SolutionApi/" в адресной строке браузера после названия вашего инстанса, чтобы увидеть доступные действия:
Переход в область SolutionApi
7. Добавьте в код проекта две функции, одна из них будет делать GET-запрос для получения данных из шаблона аккаунта «Сотрудники». Результатом будет JSON-ответ. Вторая функция будет извлекать из этого ответа нужный атрибут. После сохранения данной настройки при запуске бота будет запрошена авторизация.
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 ""; } |
8. Реализуем процесс авторизации следующим образом: если пользователь по ChatID не найден, то будем рассматривать 3 варианта:
- сообщение содержит символ '@', следовательно в сообщении email-адрес (запуск процесса отправки 4-х значного кода);
- длина сообщения — 4 символа (проверка отправленного кода на соответствие);
- во всех остальных случаях ответом будет: «Укажите email-адрес для авторизации».
Добавьте в код проекта функцию ниже для обработки сообщений от пользователя и сохраните настройки. Файл с целостным кодом будет во вложении к данной статье.
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, "Укажите email-адрес для авторизации"); } } 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); } |
9. Протестируйте работу Telegram-бота.
Авторизация через бот