«Могу делать сайты, а могу и не делать»
Запись от 1 октября 2017 г.
Простой бот для ВКонтакте за 5 минут

Для начала определим логику работы бота. Для отправки сообщения пользователю, бот должен пройти авторизацию как пользователь, либо как сообщество. Если с первым вариантом все более менее ясно, то для второго варианта необходимо получить токен с правами доступа к сообщениям сообщества. Получить их просто:

  • переходим в панель управления сообществом
  • открываем вкладку "Работа с API"
  • создаем ключ с правами "Разрешить доступ к сообщениям группы"

Ключей в сообществе может быть несколько, с разными правами. Но третьим лицам их лучше не давать, а если произошла утечка - удалить скомпрометированые ключи.

После авторизации боту необходимо послать запрос на сервер на ожидание события. Это LongPoll запрос. Как только произойдет какое-либо событие, сразу придет ответ с событием и его типом. Далее обработать ответ сервера. И так до бесконечности.

С логикой работы все ясно, можно переходить к созданию самого бота. Для работы с ВК я использую библиотеку vk_api. Код написан на python 2.7.

Для установки vk_api воспользуемся командой:

pip install vk_api

Код ядра бота:

import vk_api
from vk_api import VkUpload
from vk_api.longpoll import VkLongPoll, VkEventType
import requests


class VKBot:
    """
    VKBot object
    """
    vk = 0
    vk_session = 0
    session = 0
    upload = 0
    long_poll = 0
    event = 0

    def __init__(self, log=None, passwd=None, token=None):
        """
        Run authorization methods.
        To choose login type enter token or your login and password.
        How to get token: https://vk.com/dev/bots_docs
        :param log: your VK.com login
        :param passwd: your VK.com passsword
        :param token: your community token
        """
        if token:
            self.vk_session = vk_api.VkApi(token=token)
        else:
            self.vk_session = vk_api.VkApi(log, passwd)
            try:
                self.vk_session.auth()
            except vk_api.AuthError as error_msg:
                print(error_msg)
                return
        self.vk = self.vk_session.get_api()
        self.session = requests.session()
        self.upload = VkUpload(self.vk_session)
        self.long_poll = VkLongPoll(self.vk_session)

    def __command_handler__(self, commands, handler):
        """
        Run user function if message contain a commands
        :param commands: list of command. For example ["command1", "command2", ...]
        :param handler: function, that should run if message contain a command
        """
        message_set = self.event.text.split(u' ')
        for command in commands:
            if command in message_set:
                handler(self.event, self.vk)
                break

    def __query_manager__(self, queryset):
        """
        Sets a query of commands and handlers
        :param queryset: list of commands and hanlers. For example [["command", handler], ...]
        """
        for item in queryset:
            self.__command_handler__(item[0], item[1])

    def run(self, query):
        """
        Main bot`s cycle.
        :param query: list of commands and hanlers. For example [["command", handler], ...]
        """
        for event in self.long_poll.listen():
            if event.type == VkEventType.MESSAGE_NEW and event.to_me:
                self.event = event
                self.__query_manager__(query)

Для использования бота необходимо создать функции обработчики и выбрать команды на вкус:

# -*- coding: utf-8 -*-
from VKBot import VKBot
from random import randint


# example function:
# def example(message, vk):
#     """
#     :param message: message container, contains informations about user_id, text, status etc
#     :param vk: API
#     :return: nothing
#     """
#     vk.messages.send(user_id=message.user_id, message="Some text")


def start(message, vk):
    vk.messages.send(user_id=message.user_id, message=u"Начнем, пожалуй")


def random_habrahabr(message, vk):
    vk.messages.send(user_id=message.user_id, message=u'https://habrahabr.ru/post/' + str(randint(100, 200000)) + u'/')


if __name__ == '__main__':
    queryset = [[[u"Погнали", u"погнали", u"лол", u"Лол"], start], [[u"Хабрахабр", ], random_habrahabr]]
    # if you want use bot by community token
    bot = VKBot(token='your_token')
    # if you want use bot by your account
    # bot = VKBot(log='your_login', passwd='your_passwd')
    bot.run(query=queryset)

queryset - список пар "список возможных команд": "обработчик".

Запускать как и любой скрипт на python:

python example.py

Ссылка на github: https://github.com/whspr/VKBot