Загрузка...

Простой бот для группы VK на C#

Тема в разделе C# создана пользователем bbsys 9 сен 2020. 1101 просмотр

Опрос

Вторую часть делать?

  1. Да

    17
    89,5%
  2. Нет

    2
    10,5%
  1. bbsys
    bbsys Автор темы 9 сен 2020 3 9 фев 2019
    Бот будет очень простым, и работать будет на longpoll api.
    Немного теории:
    Что же такое, этот ваш Long Poll?
    • В документации сказано: Long Polling — это технология, которая позволяет получать информацию о новых событиях с помощью «длинных запросов». Сервер получает запрос, но отправляет ответ на него не сразу, а лишь тогда, когда произойдет какое-либо событие (например, поступит новое входящее сообщение), либо истечет заданное время ожидания.
    Говоря иначе - сервер ждет, либо когда произойдет событие (при этом неважно, печатает ли человек, или отправил сообщение, сервер в любом случае отправит ответ), либо когда истекает время ожидания (в этом случае сервер отправит ответ с "пустым" сообщением, то есть если, к примеру, за 25 секунд на сервере не произойдет никаких событий, то он отправит "пустой" ответ), и мы получим от него сообщение с информацией о событии.

    Чтобы начать получать ответы от Long Poll сервера, необходимо получить три обязательных параметра, необходимых для отправки запроса к Long Poll серверу: server, key и ts. Их нужно вызвать всего 1 раз, посредством метода messages.getLongPollServer.
    key - секретный ключ сессии;
    server - адрес сервера;
    ts - номер последнего события, начиная с которого нужно получать данные.

    Параметр ts нужен не просто так, так как этот параметр представляет номер события. Номер события нужен, чтобы сервер знал, начиная с какого события ему отправлять обновления. С каждым ответом сервера приходит параметр ts, который будет использоваться при следующем вызове Long Poll.

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

    Рассмотрим один из ответов сервера:
    В теге ts мы получаем значение следующего события (в моем случае - это 30), в теге updates мы получаем дополнительные данные события:
    Это далеко не все теги, с которыми можно оперировать.
    Естественно, для ответов на текстовые сообщения нам надо будет обрабатывать тег type на наличие значения message_new.
    Продолжим на создании консольного приложения.
    [IMG]

    Далее кликаем ПКМ по проекту и выбираем управление пакетами NuGet:

    [IMG]

    Ищем во вкладке обзора пакет VkNet и устанавливаем версию 1.52.0 (более стабильная на данный момент версия, можете попробовать выбрать версию выше этой)

    [IMG]

    Принимаем все соглашения и закрываем менеджер пакетов.

    • Примечание: Некоторые пакеты загрузятся сами.
    Настройка сообщества ВК.
    На главной странице переходим в пункт "Управление":
    [IMG]
    Первым делом надо запомнить id сообщества.
    Потом переходим во вкладку работы с API и создаем ключ:


    [IMG]

    Даем разрешения на действия в сообществе:


    [IMG]

    я выбрал все, но можно и оставить доступ только к сообщениям
    Делаем то, что от нас требуют и запоминаем ключ.


    [IMG]


    [IMG]

    Далее включаем все галочки во вкладке long poll API, непосредственно включив сам long poll:


    [IMG]



    [IMG]

    Далее включаем сообщения сообщества:


    [IMG]


    [IMG]
    Переходим к коду:
    В коде подключаем пространства имен:
    Код
    using Newtonsoft.Json.Linq;
    using System;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading;
    using VkNet;
    using VkNet.Enums.Filters;
    using VkNet.Model;
    using VkNet.Model.RequestParams;
    using VkNet.Utils;
    Будем делать все без применения ООП, максимально просто, в одном методе Main.
    Код
    static void Main(string[] args)
    {
    //cоздаем экземпляры классов и переменные
    VkApi vkapi = new VkApi();
    Random rnd = new Random();
    WebClient webclient = new WebClient() { Encoding = Encoding.UTF8 };
    string json = string.Empty;
    string URI = string.Empty;
    while (true) //цикл авторизации
    {
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine("Попытка авторизации...");
    try
    {
    vkapi.Authorize(new ApiAuthParams()
    {
    AccessToken = "токен группы", //вставляем сюда ключ для работы с API
    Settings = Settings.All //разрешаем все настройки
    });
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine("Авторизация успешно завершена");
    break; //если авторизация будет успешной, закрываем цикл
    }
    catch
    {
    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine("Ошибка авторизации, попробуйте снова"); // если авторизация не будет выполнена успешно - пробуем снова.
    }
    }
    //Создаем параметры для передачи методу
    //groups.getLongPollServer.
    //Множество других методов можно найти в официальной документации VK API
    var param = new VkParameters();
    param.Add<string>("group_id", "ID группы");
    dynamic lpresponce = JObject.Parse(vkapi.Call("groups.getLongPollServer", param).RawJson);//отправляем запрос на Long Poll и получаем данные key server ts.
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine("Запрос значений");
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine($"server: {lpresponce?.response?.server?.ToString()}\nkey: {lpresponce?.response?.key?.ToString()}\nts: {lpresponce?.response?.ts?.ToString()}");
    while (true)//цикл обработки событий
    {
    //для получения событий с сервера нужно выполнить запрос по адресу https://{$server}?act=a_check&key={$key}&ts={$ts}&wait=25, составим его:
    URI = string.Format("{0}?act=a_check&key={1}&ts={2}&wait=25",
    lpresponce?.response?.server?.ToString(),//адрес сервера
    lpresponce?.response?.key?.ToString(), //секретный ключ сессии
    json != string.Empty ? JObject.Parse(json)["ts"].ToString() : lpresponce?.response?.ts?.ToString()//номер последнего события, начиная с которого нужно получать данные,
    //именно поэтому мы вызываем тернарный оператор.
    );
    Console.ForegroundColor = ConsoleColor.Cyan;
    Console.WriteLine($"\nСобранная ссылка: {URI}\n");
    json = webclient.DownloadString(URI);//загружаем запрошенный ресурс в переменную json.
    Console.ForegroundColor = ConsoleColor.Gray;
    Console.WriteLine($"\nПолученный JSON: {json}\n");
    var msgcol = JObject.Parse(json)["updates"].ToList();//парсим json, а именно тег updates, и приводим в коллекцию List.
    foreach (var item in msgcol)//проходимся по коллекции.
    {
    if (item["type"].ToString() == "message_new")//если получили событие, содержащее message_new в теге type, то парсим json дальше (помимо этого могут приходить разные собития, например, когда боту печатают).
    {
    string message = item["object"]["body"].ToString();
    long? userid = Convert.ToInt64(item["object"]["user_id"].ToString());
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine($"\n\nВходящее сообщение:{message}\nID пользователя{userid}\n\n");
    //отправляем сообщение
    vkapi.Messages.Send(new MessagesSendParams
    {
    RandomId = rnd.Next(100000, 1000000000),//рандомный идентификатор сообщения (не знаю, зачем это сделали, но пишут: "уникальный (в привязке к API_ID и ID отправителя) идентификатор, предназначенный для предотвращения повторной отправки одинакового сообщения").
    UserId = userid, //идентификатор пользователя, которому отправляется ответ
    Message = "Вы сказали: " + message //ответ
    });
    }
    }
    Thread.Sleep(200);
    }
    }
    Получаем результат:
    [IMG]
    Конец))
     
  2. MADMAXIM08
    MADMAXIM08 21 янв 2022 1 14 июл 2020
    артем да я смотрю вы жесткий программист)
     
    1. bbsys Автор темы
      MADMAXIM08, пост 2 года назад вышел) сейчас свои либы юзаю, более легкие и стабильные
  3. aluminum343
    Артём, слушай а ты не мог бы подсказать как отправить через бота фото в беседу или в лс бота, хоть как то?
     
Загрузка...
Top