为什么还要再写一篇有关创建聊天机器人的文章?
也许我搜索不力,但是找不到关于使用Django框架和由俄罗斯公司托管的webhook方法创建python机器人的详细指南。 大多数材料都谈论使用Flask框架以及使用Heroku和PythonAnywhere的免费托管。 Habr社区的经验帮了我大忙,所以我决定抽出宝贵的时间写这篇文章。 我将描述获得的实践经验,以使对此感兴趣的每个人都可以节省时间,并更好地了解如何在使用webhook方法的主机上使用Django框架在Python中制作机器人。
为什么要付费托管?
我认为,可行的bot版本是它独立于您的本地计算机并且24/7可用。 为此,您需要一个主机,上面有一个主机:Web服务器,数据库管理系统(用于开发Bot的功能),域名注册,为此获取SSL证书以及对所有上述经济情况的技术支持。 这种服务要花钱。 我每月为托管138卢布支付托管费用,以维护该机器人的工作基础:支持Python + Django,25 GB的MySQL DBMS,支持SSH。
在大多数课程中,我看到个人计算机被用作服务器或免费主机,但工作时间受到限制等。在示例中,该机器人会定期轮询Messenger服务器,以查找来自用户的新消息。 这是Messenger服务器上的额外负载,因此可以在一段时间内“禁止”该漫游器。 我认为,所有这些对于生产性使用都不是至关重要的。 但是对于测试和培训是完全可能的。
什么是网络挂钩,为什么?
对于产品,我认为正确的决定是使用Webhook,即我们的机器人在这种方法中,期望机器人从Messenger服务器获取消息,而不用定期请求“锤击”消息:是否有新消息。 有了一个Webhook,将是这样的:用户编写了一条消息,Messenger服务器将其发送到您的机器人,他收到了该消息,对其进行了处理并进行了回答。
为什么是Django
我决定用python做一个机器人,所以我在主机上连接了python支持。 但是我没有一个选择的框架-托管只有Django。 他们说它适用于Instagram,Pinterest,Bitbucket和Mozilla。 也许这就是为什么托管提供它的原因。
为什么选择VKontakte,而不是Telegram或Viber?
从简单到复杂,对我来说,找到一种最简单,最直观的方式来建立一个Webhook至关重要。 事实证明,对于我来说,VKontakte是最可理解的,因为在“管理-使用API”部分的社区控制面板中,连接Webhook的明确帮助和便捷性。 我将如何进一步配置和连接所有内容的描述。 将来,我想让我的机器人在Viber中可用。 而且Telegram不在路上,因为我的托管地点在俄罗斯,而Telegram被俄罗斯封锁了。 为避免Telegram出现问题,您可以在国外购买托管服务。
如何为VK bot安装webhook?
域名https:// 。 首先,您需要注册该站点的域名并为其获取ssl证书。
我不想使用聊天机器人的根域,因此在注册该域之后,我创建了一个子域并收到了ssl证书。
我用我的个人帐户在托管站点上进行了所有这些操作。
结果,我收到了网站mybot.mysite.ru的地址及其ssl证书。
我们获得了机器人的VK密钥(令牌)。 首先,我创建了一个封闭的组,然后在“使用API”部分中进入该组的“管理”。 在“访问密钥”选项卡中是令牌,在“回调API”选项卡中是Webhook设置。
安装和配置Django 。 也许您不需要Django来运行python脚本,但是我不知道如何做。
使用PuTTY,我通过SSH连接到服务器,配置并激活了虚拟环境。
SSH:
virtualenv-2.7 virtualenv/myEnv . virtualenv/myEnv/bin/activate
第一行中的命令创建一个虚拟环境,第二行中的命令将其激活(注意句点后的空格)。 2.7版由托管服务商决定,您的情况可能有所不同。 因此,请阅读托管帮助。
接下来安装Django
SSH:
pip install 'django<2'
我安装的Django版本不早于第二个版本,因为在主机上使用了python 2.7,并且只有小于2的Django版本可以使用。
并安装了python模块以与VKontakte API配合使用
SSH:
pip install vk
FTP:
在主机的根目录中为django-projects创建了一个文件夹。 他称她为django。
SSH:
创建了一个新项目。
cd django/ django-admin.py startproject mybot
结果,将在/ django文件夹中创建一个带有项目名称的文件夹(在我们的示例中为“ mybot”)。 它将包含自动创建的初始项目文件:
/ django
/ mybot-项目文件夹
/ mybot-具有我们项目设置的模块
__init__.py
settings.py
urls.py
wsgi.py
manage.py
Django中的一个项目是一组应用程序。 Django中的应用程序是执行开发人员规定的操作的程序。
SSH:
创建一个应用程序。
cd mybot python manage.py startapp vk_bot
我转到
/ django / mybot文件夹,并创建了一个名为“ vk_bot”的新应用程序。
在项目文件夹中创建了一个包含应用程序名称的文件夹,其中包含自动创建的应用程序文件:
/ django
/ mybot-项目文件夹
/ mybot-具有我们项目设置的模块
__init__.py
settings.py
urls.py
wsgi.py
manage.py
/ vk_bot-应用程序文件夹
__init__.py
管理员
apps.py
models.py
tests.py
views.py
FTP:
我将所有项目文件下载到笔记本电脑上以使用代码。
为了处理项目文件和编程,我使用了Atom应用程序。
原子:
在文件
/django/mybot/mybot/settings.py中编辑了项目设置
... DEBUG = False ... ALLOWED_HOSTS = [ u'mybot.mysite.ru', ] ...
原子:
在
/django/mybot/mybot/urls.py文件中编辑的URL路由设置
... urlpatterns = [ url(r'^vk_bot/', include('vk_bot.urls')), ] ...
FTP:
创建了一个文件
/django/mybot/vk_bot/urls.py,内容
如下 :
from django.conf.urls import url from . import views app_name = 'vk_bot' urlpatterns = [ url(r'^$', views.index, name='index'), ]
原子:
编辑文件
/django/mybot/vk_bot/views.py-向其中添加了一个名为index的函数,该函数将在浏览器中请求地址时执行
https://mybot.mysite.ru/vk_bot/
views.py
在
views.py脚本的
index(request)函数中,我必须禁用Django CSRF内置的保护,因为 我收到“ 403 Forbidden”错误。 CSRF-跨站点请求伪造保护-防止跨站点请求伪造。 您可以在
本文中阅读CSRF的工作方式。
要禁用保护,我使用了
@csrf_exempt装饰器。 但是为了提供相同的保护,但以一种更简单的方式,我使用了一个秘密密钥,该密钥已在VKontakte网站上的组管理部分中注册。
这段代码负责处理来自服务器的请求,服务器将发送该请求以连接我们的Webhook进行事件处理。 我们只是说一下“确认”。
if (data['type'] == 'confirmation'):
请注意,我将所有配置设置都保存在单独的bot配置文件
bot_config.py中 ,因此在脚本开头将其连接:
from bot_config import *
bot_config.py
在这段代码中,它处理用户消息:
if (data['type'] == 'message_new'):
如果您似乎无法理解,则可以阅读
有关第一个Django设置的
文章 。
Web服务器的魔力 。 为了配置对Web服务器的请求的寻址,我通过FTP客户端FileZilla进入具有域的文件夹中的服务器,并在其中创建了文件夹“
mybot.mysite.ru ”,在其中放置了三个文件,这些文件的内容来自托管服务商的帮助:
.htaccess
AddHandler wsgi-script .wsgi RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /django.wsgi/$1 [QSA,PT,L] RewriteCond %{HTTP:X-Forwarded-Protocol} !=https RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
django.wsgi
import os, sys virtual_env = os.path.expanduser('~/virtualenv/myEnv') activate_this = os.path.join(virtual_env, 'bin/activate_this.py') execfile(activate_this, dict(__file__=activate_this)) sys.path.insert(0, os.path.join(os.path.expanduser('~'), 'django/mybot')) os.environ['DJANGO_SETTINGS_MODULE'] = 'mybot.settings' from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
这里的“ myEnv”是您创建的虚拟环境的名称,“ django”是主机上文件系统的根部分中的文件夹,“ mybot”是我们使用Django创建的项目的名称。
index.html
将我们的Webhook“绑定”到创建的VKontakte组中的消息处理。为此,我们将返回到VKontakte网站上用于管理组的部分(请参见上面的屏幕截图)。 我们将在“地址”字段中输入Webhook地址
https://mybot.mysite.ru/vk_bot/
然后点击“确认”按钮。 如果我们在文件
/django/mybot/vk_bot/views.py中编写的
索引(请求)功能可以正常工作,也就是说,它不包含错别字和错误,则会出现一个绿色的选中标记,表示一切正常。
为了使我们的Webhook接收来自VKontakte服务器的有关新用户消息的消息,请在VKontakte网站上“管理我们的组”部分的“事件类型”选项卡中,选中“传入消息”框。
结果,我们的脚本将以
json格式接收以下消息:
{"type":"message_new","object":{"id":891,"date":1541599508,"out":0,"user_id":1...1,"read_state":0,"title":"","body":" "},"group_id":1...4,"secret":"uxSBw"}
请注意,
json消息中有一个“秘密”字段。 这是我在VKontakte网站的组管理部分中注册的同一密钥,而不是我必须禁用的Django CSRF中内置的保护。
如何使机器人更聪明更好?
您可以创建一个包含用户答案的数据库,并让漫游器选择含义最接近用户问题的答案。 我将在另一篇文章中对此进行讨论。
可以这么说,对用户交互方案进行编程以保持对话是可能且必要的。
祝您创作愉快!