Перейти к содержанию

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

Переход в область 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-бота.

Авторизация через бот

На основе созданного бота и примера настройки взаимодействия бота с Comindware Business Application Platform можно в дальнейшем реализовать различные сценарии: подача заявок, заявлений на отпуск, запрос какой-либо информации из системы и т.д.
  • Вложения
  • TelegramBot.cs (11.15 KB) 25