Чат-бот для Вконтакте на ASP.NET Core C# +31


В данной статье представлен пошаговый пример создания простого чат-бота в социальной сети VK на ASP.NET Core C#.


Глава 1. Подготовка


Начнем с создания и настройки сообщества.




Выбираем любой тип сообщества



Заполняем поля любыми данными и готово! Группа создана.



Приступим к настройке API



Создаем API ключ (Разрешаем все)



Чтобы реагировать на какие-либо события, наш скрипт должен о них узнать. Для этого существуют два подхода — Callback API и Long Poll. Мы будем реализовывать Callback API.


Немного теории

Callback API — это инструмент для отслеживания активности пользователей в сообществе ВКонтакте. С его помощью можно реализовать, например:


  • Бота для отправки мгновенных ответов на поступающие сообщения.
  • Систему автоматической модерации контента.
  • Сервис для сбора и обработки показателей вовлеченности аудитории.

Long Polling — это технология, которая позволяет получать данные о новых событиях с помощью «длинных запросов». Сервер получает запрос, но отправляет ответ на него не сразу, а лишь тогда, когда произойдет какое-либо событие (например, придёт новое сообщение), либо истечет заданное время ожидания.


Используя Callback API, нам не потребуется регулярно повторять запросы, чтобы отслеживать обновления — мы будем получать их мгновенно.


Настройка Callback API


Выбираем последнюю версию API



Выбираем тип события "входящее сообщение".



Полезная информация:


  1. Знакомство с API ВКонтакте
  2. Callback API VK
  3. JSON-схема

Глава 2. Реализация Callback API


Запускаем любимую IDE, создаем ASP.NET Core Web Application.


Тип проекта: Web Api
Framework: netcoreapp 2.2



Для подтверждения адреса сервера нам потребуется вернуть строку с уникальным значением.
Берем ее в настройках Callback API.



Расширим конфигурацию нашего ASP.NET Core приложения.


Здесь мы будем хранить все ключи, которые будут задействованы в разработке.



{
  "Config": {
    "AccessToken": "0bd8573ea40badd694b4da0bbc7d54f52996",
    "Confirmation" : "b23557a3"
  },
  "Logging": {
    "LogLevel": {
    "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Когда в сообществе произойдет событие, ВКонтакте отправит на сервер запрос с данными в формате JSON с основной информацией об объекте, вызвавшем данное событие.


Структура входящего JSON.
{  
   "type":<тип события>,
   "object":<объект, инициировавший событие>,
   "group_id":<ID сообщества, в котором произошло событие>
}

Например:


{  
   "type":"group_join",
   "object":{  
      "user_id":1,
      "join_type":"approved"
   },
   "group_id":1
}

Для удобства десериализации входящего JSON воспользуемся паттерном Data Transfer Object (DTO).


using System;
using Newtonsoft.Json;

namespace Cookie.Controllers
{
    [Serializable]
    public class Updates
    {
        /// <summary>
        /// Тип события
        /// </summary>
        [JsonProperty("type")]
        public string Type { get; set; }

        /// <summary>
        /// Объект, инициировавший событие
        /// Структура объекта зависит от типа уведомления
        /// </summary>
        [JsonProperty("object")]
        public JObject Object { get; set; }

        /// <summary>
        /// ID сообщества, в котором произошло событие
        /// </summary>
        [JsonProperty("group_id")]
        public long GroupId { get; set; }
    }
}

Для обработки входящих запросом создадим CallbackController.cs.


using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace Cookie.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CallbackController : ControllerBase
    {
        /// <summary>
        /// Конфигурация приложения
        /// </summary>
        private readonly IConfiguration _configuration;

        public CallbackController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpPost]
        public IActionResult Callback([FromBody] Updates updates)
        {
            // Проверяем, что находится в поле "type" 
            switch (updates.Type)
            {
                // Если это уведомление для подтверждения адреса
                case "confirmation":
                        // Отправляем строку для подтверждения 
                    return Ok(_configuration["Config:Confirmation"]);
            }
                // Возвращаем "ok" серверу Callback API
            return Ok("ok");
        }
    }
}

Обратите внимание: после получения уведомления Ваш сервер должен возвращать строку "ok" и статус HTTP 200. Если сервер несколько раз подряд вернет ошибку, Callback API временно перестанет отправлять на него уведомления

Callback API готов!


Полезная информация:


  1. Пример на github
  2. Сериализация и десериализация данных JSON
  3. DI IoC
  4. SDK для .NET Core 2.2

Глава 3. Вк?


Для взаимодействия с VK API на C# воспользуемся библиотекой VkNET


Установка через Nuget:
Package manager:
PM> Install-Package VkNet


.NET CLI:
> dotnet add package VkNet


UI:



Полезная информация:


  1. Документация VkNET

Глава 4. Больше функционала!


Перед расширением логики бота, авторизуем группу в нашем веб-приложении.
Для этого регистрируем IVkApi в IoC-контейнере.


using VkNet;
using VkNet.Abstractions;
using VkNet.Model;

services.AddSingleton<IVkApi>(sp => {
     var api = new VkApi();
     api.Authorize(new ApiAuthParams{ AccessToken = Configuration["Config:AccessToken"] });
     return api;
});

Теперь расширим наш контроллер, добавив обработку входящих сообщений.


Внедряем IVkApi


using VkNet.Abstractions;

private readonly IConfiguration _configuration;

private readonly IVkApi _vkApi;

public CallbackController(IVkApi vkApi, IConfiguration configuration){
     _vkApi = vkApi;
     _configuration = configuration;
}

И сам кейс, который будет ловить новые сообщения. В нем мы добавить немного логики.


Немного документации

RandomId — уникальный (в привязке к API_ID и ID отправителя) идентификатор, предназначенный для предотвращения повторной отправки одинакового сообщения. Сохраняется вместе с сообщением и доступен в истории сообщений.


Заданный RandomId используется для проверки уникальности за всю историю сообщений, поэтому используйте большой диапазон(до int32).


PeerId — идентификатор назначения.


Text — текст личного сообщения. Обязательный параметр, если не задан параметр attachment.


using VkNet.Model;
using VkNet.Model.RequestParams;
using VkNet.Utils;

case "message_new":{
    // Десериализация
    var msg = Message.FromJson(new VkResponse(updates.Object));

    // Отправим в ответ полученный от пользователя текст
   _vkApi.Messages.Send(new MessagesSendParams{ 
       RandomId = new DateTime().Millisecond,
       PeerId = msg.PeerId.Value,
       Message = msg.Text
    });
    break;
}

Глава 5. Деплой


Теперь нам потребуется сервер, куда будут направлены все запросы. Один из бесплатных вариантов это Heroku.


После регистрации на сайте, нам предложат создать новое приложение.



Вводим название проекта.



После создания проекта будет перенаправление на страницу Deploy



Для Heroku CLI требуется Git. Если у вас еще не установлен Git, то скачайте его перед установкой CLI.

Для начала скачаем Heroku CLI.


Авторизуем Heroku аккаунт.
$ heroku login


Переходим в проектный каталог.
$ cd (путь до проекта)


Создаём текущем каталоге новый подкаталог с именем .git содержащий все необходимые файлы репозитория — основу Git-репозитория.
$ git init


Подключаемся к удалённому репозиторию (нашему проекту)
$ heroku git:remote -a (название проекта)


Buildpacks отвечают за преобразование развернутого кода в slug, который затем может быть выполнен на dyno.
$ heroku buildpacks:set https://github.com/jincod/dotnetcore-buildpack.git -a (название проекта)


Для того чтобы начать отслеживать (добавить под версионный контроль) наши файлы.
$ git add .


$ git commit -am "cookie"


$ git push heroku master


И идем делать чаёк.


Когда наше приложение будет загружено на Heroku, то мы сможем открыть его по следующей ссылке https://**PROJECT_NAME**.herokuapp.com/


Возвращаемся в нашу группу, и в настройках Callback API указываем ссылку,
обращаясь к Callback контроллеру.
https://**PROJECT_NAME**.herokuapp.com/api/callback



Вк отправит JSON запрос на наш сервер, чтобы подтвердить адрес. После ответа будет выведено следующее уведомление: Адрес сервера успешно сохранён


Теперь напишем нашему боту в личные сообщения.



Удачного кодинга!




К сожалению, не доступен сервер mySQL