• Главная

Чат-бот для ВКонтакте на Python на Callback API. Хостинг для бота вк


Чат-бот для ВКонтакте на Python на Callback API / Хабр

Чат-боты стали уже очень распространенным явлением, и появляются во всех мессенджерах ежедневно.

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

Для создания бота я использовал Python 3.5 (вероятно, подойдут и другие версии 3-го питона) и дополнительные библиотеки Flask и VK. Их надо будет установить. По установке Flask есть много статей на русском. Если у вас стоит Pycharm, то он, скорее всего, установился вместе с ним.

Начнем с самого API. Для нашего бота будем использовать Callback API, доступный для сообщений групп. Прежде всего, нам нужно создать или уже иметь группу ВКонтакте с подключенными сообщениями.

В разделе управление сообществом → работа с API необходимо создать ключ с доступом к сообщениям сообщества.

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

Поскольку пишем на питоне, самое простое, что можно использовать, — это хостинг для питона. Я пользовался бесплатным хостингом для Python. Там нужно зарегистрироваться, а затем создать приложение для питона 3.5 на Flask (создать можно в разделе Web). Будет создан начальный файл:

# A very simple Flask Hello World app for you to get started with... from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello from Flask!' Единственная функция, которая сейчас есть в файле, отвечает за наполнение страницы по адресу, выданному при регистрации. Если перейти в браузере по адресу username.pythonanywhere.com (со своим ником), то можно увидеть только текст «Hello from Flask!».

В дальнейшем код будет изложен блоками и после завершения целого блока можно будет проверить, а в процессе код может быть помечен средой как ошибочный. Не стоит этого пугаться, лучше просто доделать блок до конца.

Итак, БЛОК 1. Для обработки запросов, посылаемых сайту, добавим в конце документа следующий код:

@app.route('/', methods=['POST']) def processing(): return 'xxxxxxxx' Где вместо иксов подставляем «строку, которую должен вернуть сервер». Она указана в управлении группой в разделе Callback API.

Эта функция позволит нам подключить наш сайт для уведомлений к группе.

Теперь можем проверить работу. Только необходимо перезагрузить приложение. На хостинге после того, как файлы были изменены и сохранены, чтобы сайт стал работать с новыми данными, нужно его перезагрузить во вкладке Web. После добавления этого кода можем ввести соответствующий адрес username.pythonanywhere.com в строку адреса сервера в группе ВКонтакте и нажать «Подтвердить».

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

При нажатии «Подтвердить» ВКонтакте пытается связаться с нашим сервером и убедиться, что он действительно принадлежит владельцу группы, и «ждет», что сервер вернет код подтверждения в ответ на запрос.

БЛОК 2 Можем переходить к следующему шагу. Добавим возможность писать сообщения от имени сообщества. Пришло время установить на хостинге библиотеку VK. В разделе Consoles запускаем bash-консоль и исполняем команду (или соответствующую для выбранной версии питона):

pip3.5 install --user vk Как устанавливать модули описано здесь.

Изменим код нашей функции по обработке входящих запросов:

@app.route('/', methods=['POST']) def processing(): #Распаковываем json из пришедшего POST-запроса data = json.loads(request.data) #Вконтакте в своих запросах всегда отправляет поле типа if 'type' not in data.keys(): return 'not vk' if data['type'] == 'confirmation': return confirmation_token elif data['type'] == 'message_new': session = vk.Session() api = vk.API(session, v=5.0) user_id = data['object']['user_id'] api.messages.send(access_token=token, user_id=str(user_id), message='Привет, я новый бот!') # Сообщение о том, что обработка прошла успешно return 'ok' Сообщение о том, что обработка прошла успешно, нужно серверу ВКонтакте. Если произойдет ошибка, или придет какой-то иной ответ, сервер будет с некоторыми промежутками продолжать посылать уведомление о входящем сообщении (пока мы его не обработаем).

Структура входящего запроса, оповещающего о новом сообщении, такова:

{"type":"message_new","object":{"id":43, "date":1492522323, "out":0, "user_id":xxxxxxxx, "read_state":0, "title":" ... ", "body":"помощь"}, "group_id":xxxxxxxxxxx} Вконтакте передает нашему сайту три объекта: «type», «object», «group_id», а внутри «object» хранится информация о самом сообщении.

Все запросы можно посмотреть в документации ВКонтакте.

Также добавляем новые «import» в начало файла:

from flask import Flask, request, json from settings import * import vk Мы создали новый файл в этой же папке settings.py, в котором сохранены необходимые данные для входа:token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' confirmation_token = 'xxxxxxxx' Их надо заменить на ваши токены. Первый мы создали в начале статьи, второй – код подтверждения, чтобы соединить группу с сервером.

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

Можем его проверить и написать ему какое-нибудь сообщение, только надо подключить в настройках группы в разделе Callback API уведомления о входящих сообщениях.

Чтобы бот стал слать сообщения, нужно перезагрузить приложение. После этого снова пишем боту и, если все в порядке, переходим к следующему шагу.

БЛОК 3 Если все прошло хорошо, и бот с вами поздоровался в ответ на ваше сообщение, переходим к следующему шагу. Вынесем все взаимодействие с библиотекой vk в другой файл, я назвал его vkapi:

import vk session = vk.Session() api = vk.API(session, v=5.0) def send_message(user_id, token, message, attachment=""): api.messages.send(access_token=token, user_id=str(user_id), message=message, attachment=attachment) Пока там только одна функция и инициализация сессии ВКонтакте, потом добавим другие. Потенциально функция может также отправлять и вложения. Позже мы воспользуемся этой возможностью.

Дальше заведем файл — обработчик сообщений. Он будет обрабатывать входящие сообщения, определять соответствующие команды, когда они появятся, и выдавать нужные ответы.

Файл «messageHandler.py»:

import vkapi def get_answer(body): message = "Привет, я новый бот!" return message def create_answer(data, token): user_id = data['user_id'] message = get_answer(data['body'].lower()) vkapi.send_message(user_id, token, message) Осталось подключить наши новые файлы к основному. Изменяем функцию обработки запросов в главном файле:@app.route('/', methods=['POST']) def processing(): data = json.loads(request.data) if 'type' not in data.keys(): return 'not vk' if data['type'] == 'confirmation': return confirmation_token elif data['type'] == 'message_new': messageHandler.create_answer(data['object'], token) return 'ok' И добавляем соответствующий импорт в начало файла:import messageHandler Можем проверить, что у нас получилось, перезагрузив приложение.

БЛОК 4 Приступим к созданию команд. Создадим класс команд.

Файл «command_system.py»:

command_list = [] class Command: def __init__(self): self.__keys = [] self.description = '' command_list.append(self) @property def keys(self): return self.__keys @keys.setter def keys(self, mas): for k in mas: self.__keys.append(k.lower()) def process(self): pass У класса есть свойство keys, где будут храниться ключи, по которым можно обратиться к данной команде. Все ключи сохраняются в строчных буквах при задании свойства, и сравнивать их нужно с переведенными в строчную форму сообщениями пользователя, чтобы регистр не влиял на успех вызова команды.

Поле description будем использовать для выдачи информации по командам бота. Функция process будет исполняться для формирования ответного сообщения.

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

Теперь создадим несколько команд для нашего бота. Для удобства загрузки будем помещать файлы, в которых инициализируем команды, в папку «commands».

Я создам несколько файлов, но можно и разместить команды и в одном файле

«hello.py»

import command_system def hello(): message = 'Привет, друг!\nЯ новый чат-бот.' return message, '' hello_command = command_system.Command() hello_command.keys = ['привет', 'hello', 'дратути', 'здравствуй', 'здравствуйте'] hello_command.description = 'Поприветствую тебя' hello_command.process = hello «cat.py»import command_system import vkapi def cat(): # Получаем случайную картинку из паблика attachment = vkapi.get_random_wall_picture(-32015300) message = 'Вот тебе котик :)\nВ следующий раз я пришлю другого котика.' return message, attachment cat_command = command_system.Command() cat_command.keys = ['котик', 'кошка', 'кот', 'котенок', 'котяра', 'cat'] cat_command.description = 'Пришлю картинку с котиком' cat_command.process = cat Для команды, отправляющей котика, используем новую функцию, которую написали в файле «vkapi», она возвращает случайную картинку со стены группы или пользователя. В данном случае получаем случайную фотографию со стены паблика с котами. Здесь немного расширяем спектр используемых методов API.

Этот метод выглядит так:

def get_random_wall_picture(group_id): max_num = api.photos.get(owner_id=group_id, album_id='wall', count=0)['count'] num = random.randint(1, max_num) photo = api.photos.get(owner_id=str(group_id), album_id='wall', count=1, offset=num)['items'][0]['id'] attachment = 'photo' + str(group_id) + '_' + str(photo) return attachment Дописываем его в файл «vkapi». Также в начало файла «vkapi» надо добавить необходимый импорт:import random И последняя команда

«info.py»

import command_system def info(): message = '' for c in command_system.command_list: message += c.keys[0] + ' - ' + c.description + '\n' return message, '' info_command = command_system.Command() info_command.keys = ['помощь', 'помоги', 'help'] info_command.desciption = 'Покажу список команд' info_command.process = info Окончательная иерархия файлов:

botFlask — главный файл, который принимает входящие запросы.

Теперь, когда мы описали команды, нужно позаботиться о том, чтобы наш лист команд был наполнен, и мы могли понять, к какой из команд обращался пользователь, так как список “command_list” заполняется только в момент запуска файлов с конкретными командами.

Мы будем автоматически запускать на исполнение все файлы из папки «commands» при запуске нашего бота.

Для этого в файле «messageHandler.py» дописываем функцию:

def load_modules(): # путь от рабочей директории, ее можно изменить в настройках приложения files = os.listdir("mysite/commands") modules = filter(lambda x: x.endswith('.py'), files) for m in modules: importlib.import_module("commands." + m[0:-3]) В этой функции мы загружаем список файлов из директории с командами, отфильтровываем только файлы питона и импортируем их в нашу программу, что обеспечивает заполнение списка командами.

Вызов этой функции добавляем в «create_answer». Теперь изменим функцию «get_answer» так, чтобы она вызывала соответствующий ответ.

Итоговый вид файла:

import vkapi import os import importlib from command_system import command_list def load_modules(): # путь от рабочей директории, ее можно изменить в настройках приложения files = os.listdir("mysite/commands") modules = filter(lambda x: x.endswith('.py'), files) for m in modules: importlib.import_module("commands." + m[0:-3]) def get_answer(body): # Сообщение по умолчанию если распознать не удастся message = "Прости, не понимаю тебя. Напиши 'помощь', чтобы узнать мои команды" attachment = '' for c in command_list: if body in c.keys: message, attachment = c.process() return message, attachment def create_answer(data, token): load_modules() user_id = data['user_id'] message, attachment = get_answer(data['body'].lower()) vkapi.send_message(user_id, token, message, attachment) Все, наш бот готов! Теперь вы знаете, как создать основу для бота и добавить для него новые команды.

БЛОК 5 Дальнейшая часть статьи будет про одно улучшение, которое я считаю необходимым. Однако бот будет работать и без этого улучшения.

Приблизительное распознавание команд

Если пользователь допустил ошибку в одном символе, скорее всего, он имел в виду максимально похожую команду. Поэтому было бы хорошо, если бы наш бот все равно давал ответ, а не говорил «не понимаю тебя».

Для приблизительного распознавания будем использовать расстояние Дамерау-Левенштейна. Оно показывает, за сколько операций удаления, вставки, замены и перемещения символов можно перейти от одной строки к другой.

Алгоритм нахождения этого расстояния изложен, например, в Википедии.

Добавляем в файл “messageHandler.py” функцию:

def damerau_levenshtein_distance(s1, s2): d = {} lenstr1 = len(s1) lenstr2 = len(s2) for i in range(-1, lenstr1 + 1): d[(i, -1)] = i + 1 for j in range(-1, lenstr2 + 1): d[(-1, j)] = j + 1 for i in range(lenstr1): for j in range(lenstr2): if s1[i] == s2[j]: cost = 0 else: cost = 1 d[(i, j)] = min( d[(i - 1, j)] + 1, # deletion d[(i, j - 1)] + 1, # insertion d[(i - 1, j - 1)] + cost, # substitution ) if i and j and s1[i] == s2[j - 1] and s1[i - 1] == s2[j]: d[(i, j)] = min(d[(i, j)], d[i - 2, j - 2] + cost) # transposition return d[lenstr1 - 1, lenstr2 - 1] Она реализует алгоритм нахождения этого расстояния, при желании вы можете его изменить или улучшить.

По данным строкам она будет выдавать количество операций для преобразования одной в другую. Теперь изменим метод «get_answer»:

def get_answer(body): message = "Прости, не понимаю тебя. Напиши 'помощь', чтобы узнать мои команды" attachment = '' distance = len(body) command = None key = '' for c in command_list: for k in c.keys: d = damerau_levenshtein_distance(body, k) if d < distance: distance = d command = c key = k if distance == 0: message, attachment = c.process() return message, attachment if distance < len(body)*0.4: message, attachment = command.process() message = 'Я понял ваш запрос как "%s"\n\n' % key + message return message, attachment В этой функции мы вычисляем расстояние для сообщения и каждого из ключей. Если совпадение неточное, пишем, как бот распознал каждую из тех команд, которые ему отправили. В случае, если расстояние превысило 40% от длины поданного сообщения, считаем, что пользователь ошибся слишком сильно и возвращаем сообщение по умолчанию, где предлагаем обратиться к помощи.

На этом все, рабочий (на момент написания статьи) код выложен на гитхабе.

Надеюсь, эта статья немного облегчит вам жизнь, если вы решили создать своего бота для VK.

habr.com

Как написать чат-бота для vk.com за 3 минуты / Хабр

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

Статья написана для новичков, чтобы показать, что ничего сложного в написании ботов на Python нет.

Авторизация

Нам понадобится библиотека vk_api. Авторизоваться в вк можно двумя способами: — Как пользователь — Как сообщество

В первом случае надо будет ввести логин и пароль. Во втором случае в группе надо включить "Сообщения сообщества" и создать ключ доступа к API:

Авторизация в две строчки:

import time import vk_api vk = vk_api.VkApi(login = 'login', password = 'password') #vk_api.VkApi(token = 'a02d...e83fd') #Авторизоваться как сообщество vk.auth()
Отправка сообщений

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

P.S. Сообщество может отправлять сообщения только ранее писавшим пользователям.

def write_msg(user_id, s): vk.method('messages.send', {'user_id':user_id,'message':s})

В vk.method мы можем вызывать любой метод из VK API и передавать параметры в виде словаря.

В данном случае мы вызываем метод messages.send и в качестве параметров передаем id пользователя и текст сообщения.

Прием сообщений

Отлично! Отправлять сообщения мы научились, осталось научиться их принимать. Для этого нам нужен метод messages.get.

Несколько параметров, на которые стоит обратить внимание:

1) out — если этот параметр равен 1, сервер вернет исходящие сообщения. 2) count — количество сообщений, которое необходимо получить. 3) time_offset — максимальное время, прошедшее с момента отправки сообщения до текущего момента в секундах. 4) last_message_id — идентификатор сообщения, полученного перед тем, которое нужно вернуть последним (при условии, что после него было получено не более count сообщений)

values = {'out': 0,'count': 100,'time_offset': 60} vk.method('messages.get', values)

В нашем случае этот метод вернет все полученные сообщения за последние 60 сек, если их конечно было меньше 100, а если больше, то последние 100.

В итоге мы получаем список items:

{u'count': 3441, u'items': [{u'body': u'\u041f\u0438\u0448\u0435\u043c \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0432\u043a!', u'date': 1491934484, u'id': 7387, u'out': 0, u'read_state': 0, u'title': u' ... ', u'user_id': 23107592}, {u'body': u'\u041f\u0440\u0438\u0432\u0435\u0442 \u0425\u0430\u0431\u0440!', u'date': 1491934479, u'id': 7386, u'out': 0, u'read_state': 0, u'title': u' ... ', u'user_id': 23107592}]}

Если объяснять простыми словами, то items — это то, что можно выделить в диалоге.

Финальный аккорд, делаем вечный цикл, где на каждое сообщение будем отвечать "Привет, Хабр!".

while True: response = vk.method('messages.get', values) if response['items']: values['last_message_id'] = response['items'][0]['id'] for item in response['items']: write_msg(item[u'user_id'],u'Привет, Хабр!') time.sleep(1)

Чат-бот готов.

P.S. Мы запоминаем параметр last_message_id, чтобы в следующий раз обрабатывать только новые сообщения.

Полный код# -*- coding: utf-8 -*- import time import vk_api vk = vk_api.VkApi(login = 'login', password = 'password') #vk_api.VkApi(token = 'a02d...e83fd') #Авторизоваться как сообщество vk.auth() values = {'out': 0,'count': 100,'time_offset': 60} def write_msg(user_id, s): vk.method('messages.send', {'user_id':user_id,'message':s}) while True: response = vk.method('messages.get', values) if response['items']: values['last_message_id'] = response['items'][0]['id'] for item in response['items']: write_msg(item[u'user_id'],u'Привет, Хабр!') time.sleep(1)

Получилось 17 строк кода. Успехов!

habr.com

Чат-бот для ВКонтакте на Python на Callback API

Чат-боты стали уже очень распространенным явлением, и появляются во всех мессенджерах ежедневно.

В этой статье по шагам разберем создание бота с набором простых команд и узнаем, как в дальнейшем можно расширить его функционал. Статья будет полезна для самых новичков, которые никогда не пробовали создавать чат-ботов.

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

Для создания бота я использовал Python 3.5 (вероятно, подойдут и другие версии 3-го питона) и дополнительные библиотеки

Flask

и

VK

. Их надо будет установить. По установке Flask есть много статей на русском. Если у вас стоит Pycharm, то он, скорее всего, установился вместе с ним.

Начнем с самого API. Для нашего бота будем использовать Callback API, доступный для сообщений групп. Прежде всего, нам нужно создать или уже иметь группу ВКонтакте с подключенными сообщениями.

В разделе

управление сообществом

работа с API

необходимо создать ключ с доступом к сообщениям сообщества.

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

Поскольку пишем на питоне, самое простое, что можно использовать, — это хостинг для питона. Я пользовался бесплатным

хостингом

для Python. Там нужно зарегистрироваться, а затем создать приложение для питона 3.5 на Flask (создать можно в разделе Web). Будет создан начальный файл:

# A very simple Flask Hello World app for you to get started with... from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello from Flask!'

Единственная функция, которая сейчас есть в файле, отвечает за наполнение страницы по адресу, выданному при регистрации. Если перейти в браузере по адресу username.pythonanywhere.com (со своим ником), то можно увидеть только текст «Hello from Flask!».

Для обработки запросов, посылаемых сайту, добавим в конце документа следующий код:

@app.route('/', methods=['POST']) def processing(): return 'xxxxxxxx'

Где вместо иксов подставляем «строку, которую должен вернуть сервер». Она указана в управлении группой в разделе Callback API.

Эта функция позволит нам подключить наш сайт для уведомлений к группе.

Теперь можем проверить работу. Только необходимо перезагрузить приложение. На хостинге после того, как файлы были изменены и сохранены, чтобы сайт стал работать с новыми данными, нужно его перезагрузить во вкладке Web. После добавления этого кода можем ввести соответствующий адрес username.pythonanywhere.com в строку адреса сервера в группе ВКонтакте и нажать «Подтвердить».

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

При нажатии «Подтвердить» ВКонтакте пытается связаться с нашим сервером и убедиться, что он действительно принадлежит владельцу группы, и «ждет», что сервер вернет код подтверждения в ответ на запрос.

Можем переходить к следующему шагу. Добавим возможность писать сообщения от имени сообщества. Пришло время установить на хостинге библиотеку VK. В разделе Consoles запускаем bash-консоль и исполняем команду:

pip3.5 install --user vk

Как устанавливать модули описано

здесь

.

Изменим код нашей функции по обработке входящих запросов:

@app.route('/', methods=['POST']) def processing(): #Распаковываем json из пришедшего GET-запроса data = json.loads(request.data) #Вконтакте в своих запросах всегда отправляет поле типа if 'type' not in data.keys(): return 'not vk' if data['type'] == 'confirmation': return confirmation_token elif data['type'] == 'message_new': session = vk.Session() api = vk.API(session, v=5.0) user_id = data['object']['user_id'] api.messages.send(access_token=token, user_id=str(user_id), message='Привет, я новый бот!') # Сообщение о том, что обработка прошла успешно return 'ok'

Сообщение о том, что обработка прошла успешно, нужно серверу ВКонтакте. Если произойдет ошибка, или придет какой-то иной ответ, сервер будет с некоторыми промежутками продолжать посылать уведомление о входящем сообщении (пока мы его не обработаем).

Структура входящего запроса, оповещающего о новом сообщении, такова:

{"type":"message_new","object":{"id":43, "date":1492522323, "out":0, "user_id":xxxxxxxx, "read_state":0, "title":" ... ", "body":"помощь"}, "group_id":xxxxxxxxxxx}

Вконтакте передает нашему сайту три объекта: «type», «object», «group_id», а внутри «object» хранится информация о самом сообщении.

Все запросы можно посмотреть в

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

ВКонтакте.

Также добавляем новые «import» в начало файла:

from flask import Flask, request, json from settings import * import vk

Мы создали новый файл в этой же папке settings.py, в котором сохранены необходимые данные для входа:

token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' confirmation_token = 'xxxxxxxx'

Их надо заменить на ваши токены. Первый мы создали в начале статьи, второй – код подтверждения, чтобы соединить группу с сервером.

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

Можем его проверить и написать ему какое-нибудь сообщение, только надо подключить в настройках группы в разделе Callback API уведомления о входящих сообщениях.

Чтобы бот стал слать сообщения, нужно перезагрузить приложение. После этого снова пишем боту и, если все в порядке, переходим к следующему шагу.

Если все прошло хорошо, и бот с вами поздоровался в ответ на ваше сообщение, переходим к следующему шагу. Вынесем все взаимодействие с библиотекой vk в другой файл, я назвал его vkapi:

import vk session = vk.Session() api = vk.API(session, v=5.0) def send_message(user_id, token, message, attachment=""): api.messages.send(access_token=token, user_id=str(user_id), message=message, attachment=attachment)

Пока там только одна функция и инициализация сессии ВКонтакте, потом добавим другие. Потенциально функция может также отправлять и вложения. Позже мы воспользуемся этой возможностью.

Дальше заведем файл — обработчик сообщений. Он будет обрабатывать входящие сообщения, определять соответствующие команды, когда они появятся, и выдавать нужные ответы.

Файл «messageHandler.py»:

import vkapi def get_answer(body): message = "Привет, я новый бот!" return message def create_answer(data, token): user_id = data['user_id'] message = get_answer(data['body'].lower()) vkapi.send_message(user_id, token, message)

Осталось подключить наши новые файлы к основному. Изменяем функцию обработки запросов в главном файле:

@app.route('/', methods=['POST']) def processing(): data = json.loads(request.data) if 'type' not in data.keys(): return 'not vk' if data['type'] == 'confirmation': return confirmation_token elif data['type'] == 'message_new': messageHandler.create_answer(data['object'], token) return 'ok'

И добавляем соответствующий импорт в начало файла:

import messageHandler

Можем проверить, что у нас получилось, перезагрузив приложение.

Приступим к созданию команд. Создадим класс команд.

Файл «command_system.py»:

command_list = [] class Command: def __init__(self): self.__keys = [] self.description = '' command_list.append(self) @property def keys(self): return self.__keys @keys.setter def keys(self, mas): for k in mas: self.__keys.append(k.lower()) def process(self): pass

У класса есть свойство keys, где будут храниться ключи, по которым можно обратиться к данной команде. Все ключи сохраняются в строчных буквах при задании свойства, и сравнивать их нужно с переведенными в строчную форму сообщениями пользователя, чтобы регистр не влиял на успех вызова команды.

Поле description будем использовать для выдачи информации по командам бота. Функция process будет исполняться для формирования ответного сообщения.

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

Теперь создадим несколько команд для нашего бота. Для удобства загрузки будем помещать файлы, в которых инициализируем команды, в папку «commands».

Я создам несколько файлов, но можно и разместить команды и в одном файле

«hello.py»

import command_system def hello(): message = 'Привет, друг!\nЯ новый чат-бот.' return message, '' hello_command = command_system.Command() hello_command.keys = ['привет', 'hello', 'дратути', 'здравствуй', 'здравствуйте'] hello_command.description = 'Поприветствую тебя' hello_command.process = hello

«cat.py»

import command_system import vkapi def cat(): # Получаем случайную картинку из паблика attachment = vkapi.get_random_wall_picture(-32015300) message = 'Вот тебе котик :)\nВ следующий раз я пришлю другого котика.' return message, attachment cat_command = command_system.Command() cat_command.keys = ['котик', 'кошка', 'кот', 'котенок', 'котяра', 'cat'] cat_command.description = 'Пришлю картинку с котиком' cat_command.process = cat

Для команды, отправляющей котика, используем новую функцию, которую написали в файле «vkapi», она возвращает случайную картинку со стены группы или пользователя. В данном случае получаем случайную фотографию со стены паблика с котами. Здесь немного расширяем спектр используемых методов API.

Этот метод выглядит так:

def get_random_wall_picture(group_id): max_num = api.photos.get(owner_id=group_id, album_id='wall', count=0)['count'] num = random.randint(1, max_num) photo = api.photos.get(owner_id=str(group_id), album_id='wall', count=1, offset=num)['items'][0]['id'] attachment = 'photo' + str(group_id) + '_' + str(photo) return attachment

Дописываем его в файл «vkapi». Также в начало файла «vkapi» надо добавить необходимый импорт:

import random

И последняя команда

«info.py»

import command_system def info(): message = '' for c in command_system.command_list: message += c.keys[0] + ' - ' + c.description + '\n' return message, '' info_command = command_system.Command() info_command.keys = ['помощь', 'помоги', 'help'] info_command.desciption = 'Покажу список команд' info_command.process = info

Окончательная иерархия файлов:

image

botFlask — главный файл, который принимает входящие запросы.

Теперь, когда мы описали команды, нужно позаботиться о том, чтобы наш лист команд был наполнен, и мы могли понять, к какой из команд обращался пользователь, так как список “command_list” заполняется только в момент запуска файлов с конкретными командами.

Мы будем автоматически запускать на исполнение все файлы из папки «commands» при запуске нашего бота.

Для этого в файле «messageHandler.py» дописываем функцию:

def load_modules(): # путь от рабочей директории, ее можно изменить в настройках приложения files = os.listdir("mysite/commands") modules = filter(lambda x: x.endswith('.py'), files) for m in modules: importlib.import_module("commands." + m[0:-3])

В этой функции мы загружаем список файлов из директории с командами, отфильтровываем только файлы питона и импортируем их в нашу программу, что обеспечивает заполнение списка командами.

Вызов этой функции добавляем в «create_answer». Теперь изменим функцию «get_answer» так, чтобы она вызывала соответствующий ответ.

Итоговый вид файла:

import vkapi import os import importlib from command_system import command_list def load_modules(): # путь от рабочей директории, ее можно изменить в настройках приложения files = os.listdir("mysite/commands") modules = filter(lambda x: x.endswith('.py'), files) for m in modules: importlib.import_module("commands." + m[0:-3]) def get_answer(body): # Сообщение по умолчанию если распознать не удастся message = "Прости, не понимаю тебя. Напиши 'помощь', чтобы узнать мои команды" attachment = '' for c in command_list: if body in c.keys: message, attachment = c.process() return message, attachment def create_answer(data, token): load_modules() user_id = data['user_id'] message, attachment = get_answer(data['body'].lower()) vkapi.send_message(user_id, token, message, attachment)

Все, наш бот готов! Теперь вы знаете, как создать основу для бота и добавить для него новые команды.

Дальнейшая часть статьи будет про одно улучшение, которое я считаю необходимым. Однако бот будет работать и без этого улучшения.

Приблизительное распознавание команд

Если пользователь допустил ошибку в одном символе, скорее всего, он имел в виду максимально похожую команду. Поэтому было бы хорошо, если бы наш бот все равно давал ответ, а не говорил «не понимаю тебя».

Для приблизительного распознавания будем использовать расстояние Дамерау-Левенштейна. Оно показывает, за сколько операций удаления, вставки, замены и перемещения символов можно перейти от одной строки к другой.

Алгоритм нахождения этого расстояния изложен, например, в Википедии.

Добавляем в файл “messageHandler.py” функцию:

def damerau_levenshtein_distance(s1, s2): d = {} lenstr1 = len(s1) lenstr2 = len(s2) for i in range(-1, lenstr1 + 1): d[(i, -1)] = i + 1 for j in range(-1, lenstr2 + 1): d[(-1, j)] = j + 1 for i in range(lenstr1): for j in range(lenstr2): if s1[i] == s2[j]: cost = 0 else: cost = 1 d[(i, j)] = min( d[(i - 1, j)] + 1, # deletion d[(i, j - 1)] + 1, # insertion d[(i - 1, j - 1)] + cost, # substitution ) if i and j and s1[i] == s2[j - 1] and s1[i - 1] == s2[j]: d[(i, j)] = min(d[(i, j)], d[i - 2, j - 2] + cost) # transposition return d[lenstr1 - 1, lenstr2 - 1]

Она реализует алгоритм нахождения этого расстояния, при желании вы можете его изменить или улучшить.

По данным строкам она будет выдавать количество операций для преобразования одной в другую. Теперь изменим метод «get_answer»:

def get_answer(body): message = "Прости, не понимаю тебя. Напиши 'помощь', чтобы узнать мои команды" attachment = '' distance = len(body) command = None key = '' for c in command_list: for k in c.keys: d = damerau_levenshtein_distance(body, k) if d < distance: distance = d command = c key = k if distance == 0: message, attachment = c.process() return message, attachment if distance < len(body)*0.4: message, attachment = command.process() message = 'Я понял ваш запрос как "%s"\n\n' % key + message return message, attachment

В этой функции мы вычисляем расстояние для сообщения и каждого из ключей. Если совпадение неточное, пишем, как бот распознал каждую из тех команд, которые ему отправили. В случае, если расстояние превысило 40% от длины поданного сообщения, считаем, что пользователь ошибся слишком сильно и возвращаем сообщение по умолчанию, где предлагаем обратиться к помощи.

На этом все, рабочий (на момент написания статьи) код выложен на

гитхабе

.

Надеюсь, эта статья немного облегчит вам жизнь, если вы решили создать своего бота для VK.

pythondigest.ru

Как поставить бота вк на хостинг

как поставить бота вк на хостинг

Где найти место для проживания своего сайта? Конечно, в интернете. Такую возможность предоставляет хостинг, это своеобразная «аренда квартиры» для расположения сайта. Вам выделяется специальное место, позволяющее разместить подробную информацию о своих товарах и услугах, вы сможете привлечь внимание потенциальных потребителей, ваши предложения будут доступны круглосуточно как поставить бота вк на хостинг.

Дорого ли стоит хостинг сайтов? Опытные люди знают, что экономить на размещении сайта нельзя. Имеет смысл обратиться к профессионалам, которые посоветуют место для расположения сайта. Платный hosting обеспечивает бесперебойный доступ к вашей информации, следовательно, он постоянно работает для вашего блага. Вы сможете развить свой бизнес, получить хорошую прибыль.

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

Именно как поставить бота вк на хостинг

Для того, чтобы развиваться и расширяться, потребуется грамотный хостинг сайта. Он обеспечивает постоянный доступ к вашему ресурсу, круглосуточно оповещает посетителей об услугах вашей компании. Следовательно, хостинг с доступом ssh ваш сайт работает в режиме круглосуточного доступа для посетителей. О вас узнают клиенты разного возраста, проживающие в любом городе.

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

Профессиональный хостинг позволяет находиться в постоянном поле зрения клиентов. Они смогут посетить ваш ресурс днем и ночью, в любой день для потенциальных покупателей доступна информация, ваш бизнес не ограничится рамками своего города. Ваши контакты будут доступны жителям любых стран, почему хостинг провайдер блокирует сайт вы сможете оперативно донести информацию о своей деятельности до потребителей.

caumoxocm.tw1.su

Разговорный бот для Вконтакте на PHP / Хабр

Как-то в один прекрасный день меня осенила мысль о том, что было бы неплохо, если бы такие повседневные задачи как постинг и поддержание активности аккаунта в какой-либо социальной сети выполнял не человек, а простой разговорный бот. Тем более при «ботнете» в несколько сотен аккаунтов выполнять задачу с помощью одного человека нецелесообразно и почти невозможно. Поэтому возникла идея написать разговорного бота средствами, которые лучше всего мне были известны. Я решил сделать бота на PHP. Начать, как вы уже догадались, нужно было с поиска баз для ответов бота и элементарного технического задания, которое помогло бы сделать все быстро и с минимальным количеством костылей (у меня без костылей не получилось).

Немного раньше я познакомился с одним интересным проектом от компании «Наносемантика», которая занимается подобными задачами и создает, вроде, комерческих ботов-саппортов и прочее. Этот проект — iii.ru. На сайте проекта можно создать бота и получить его flash-версию для вставки на сайте. API у них не было, пришлось декомпилировать swf.

Первое, что пришло ко мне в голову, когда я открыл декомпилированный код SWF файла — где теперь найти точку вывода ответов и каким образом это все перевернуть в сторону своей задумки. Удивлению не было предела, когда я увидел, что все запросы и ответы шифруются с помощью XOR + Base64, а ключ для расшифровки был в начале кода. Зачем тогда криптовать? Основные задачи, которые должен был выполнять мой бот — получать последние сообщения с «Вконтакте», отсылать их на сервер, получать ответ, отправлять ответ человеку, который общается с ботом.

Было создано следующие файлы: — index.php (работает как клиент, обновляющий с помощью jquery файл с подгрузкой пришедших сообщений и последующим ответом) — autoload.php (собственно, тот файл, который принимает и отвечает) — showmeid.php (файл, который создает новый ID чата, если собеседник впервые общается с ботом) — config.php (коннект к базе данных с клиентами бота) — classes.php (классы для работы с ботом)

1. Импортируйте dump.sql в свою базу данных 2. Получите «долгоиграющий» access token для работы с VK API с помощью ссылки — получить token 3. Переименуйте config.sample.php в config.php предварительно изменив данные для коннекта к базе данных 4. Пользуйтесь запустив index.php

Итак, прошу знакомиться — Лариса Чернышова

А также исходники на GitHub.

UPD: Если бот не отвечает — значит блокируется отправка сообщения просьбой ввести капчу.

За подробностями и вопросами — добро пожаловать ко мне в блог

habr.com