VK, обработка сообщения

493
29 января 2017, 12:01

Пишу простой бот ВК на С#, отвечающий в конфе от моего имени на фразу "Евгений, погода". Не пойму немного, как отлавливать прием сообщения? Не подскажите логику?

Есть метод messages.GetHistory,возвращающий N сообщений. Может мне каждый тик таймера брать 20 сообщений послених и там искать это сообщение, и удалять после того, как нашел? Звучит очень неоптимально, но я не вижу альтернативы

Answer 1

Самый эффективный способ отлавливания новых личных сообщений пользователя — это Long Poll.

Но вообще, если у вас есть возможность поднять скрипт на бэкэнде, то тогда писать ботов следует с использованием сообществ и их личных сообщений. Для них предоставляется дополнительный функционал в виде Callback API — эдакий аналог вэбхуков в Телеграме. То есть ВК сам будет POST-запросами сообщать вам, когда и что вашему сообществу написали в ЛС.

Answer 2

Вот пример на коленке с использованием VkApi

  internal class Program
  {
    private static VkApi _api;
    private static void Main()
    {
      const string email = "email";
      const string pass = "password";
      _api = new VkApi();
      _api.Authorize(new ApiAuthParams
      {
        Login = email,
        Password = pass,
        Settings = Settings.Messages,
        ApplicationId = 0000 // vkAppId
      });
      Thread pollMessagesThread = new Thread(PollUnread)
      {
        IsBackground = true,
        Name = nameof(pollMessagesThread)
      };
      pollMessagesThread.Start();
      pollMessagesThread.Join(); // для теста.
    }
    private static void PollUnread()
    {
      HashSet<string> messages = new HashSet<string>(); 
      // желательно сделать expirableSet или время от времени чистить эту коллекцию
      while (true /*_shouldStop конечно же*/)
      {
        var msgs = _api?.Messages.GetHistory(new MessagesGetHistoryParams
        {
          UserId = 00000000 // Id пользователя c которым ведете диалог.
        });
        foreach (var msgsMessage in msgs.Messages)
        {
          if (!messages.Contains(msgsMessage.Body))
          {
            messages.Add(msgsMessage.Body);
            Console.WriteLine(msgsMessage.Body);
          }
        }
        Thread.Sleep(3000);
      }
    }
  }

UPD: ещё метод PollUnread можно переделать так что бы что то делать только в случае если есть не прочитаны сообщения:

private static void PollUnread()
{
  while (true /*_shouldStop конечно же*/)
  {
    var msgs = _api?.Messages.GetHistory(new MessagesGetHistoryParams
    {
      UserId = 00000000 // Id пользователя c которым ведете диалог.
    });
    if (msgs.Unread > 0)
    {
      Console.WriteLine(msgs.Messages);
      // Unreaded messages.
    }
    Thread.Sleep(3000);
  }
}
READ ALSO
Prism DelegateCommand

Prism DelegateCommand

Добрый день, возникла внезапная проблема, может кто сталкивался

317
Не могу понять, в чем проблема с mysql? [требует правки]

Не могу понять, в чем проблема с mysql? [требует правки]

Есть класс SQLHelper, но ничего неработаетне могу понять в чем дело

333
Редактирование WooCommerce Product таблицу?

Редактирование WooCommerce Product таблицу?

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

704
помогите составить запрос выборки из mysql

помогите составить запрос выборки из mysql

Всем доброго настроения! Я учусь, не пинайте ) Помогите составить запрос mysql

344