Cara membuat bot obrolan untuk VKontakte menggunakan Python, Django dan webhook

Mengapa artikel lain tentang membuat bot obrolan?


Mungkin saya mencari dengan buruk, tetapi saya tidak dapat menemukan panduan terperinci tentang cara membuat bot python menggunakan kerangka kerja Django dan pendekatan webhook, yang diselenggarakan oleh perusahaan Rusia. Sebagian besar materi berbicara tentang menggunakan kerangka kerja Flask dan menggunakan hosting gratis Heroku dan PythonAnywhere. Pengalaman komunitas Habr membantu saya keluar, jadi saya memutuskan, sebagai tanda terima kasih, untuk menghabiskan waktu menulis artikel ini. Saya akan menjelaskan pengalaman praktis yang diperoleh untuk memungkinkan semua orang yang tertarik pada ini untuk menghemat waktu dan lebih memahami cara membuat bot di Python menggunakan kerangka Django di hosting mereka menggunakan pendekatan webhook.

Kenapa hosting berbayar?


Menurut pendapat saya, versi yang layak dari bot adalah ketika independen dari komputer lokal Anda dan tersedia 24/7. Untuk melakukan ini, Anda memerlukan hosting yang ada: server web, sistem manajemen basis data (untuk mengembangkan kemampuan bot), pendaftaran nama domain, memperoleh sertifikat SSL untuknya dan dukungan teknis untuk semua ekonomi ini. Layanan semacam itu membutuhkan biaya. Saya membayar hosting 138 rubel sebulan untuk menjaga infrastruktur agar bot berfungsi: dukungan untuk Python + Django, MySQL DBMS 25 GB, dukungan untuk SSH.
Dalam sebagian besar pelajaran, saya melihat bahwa komputer pribadi digunakan sebagai server atau hosting gratis dengan waktu terbatas, dll. Dalam contoh ini, bot secara berkala melakukan polling pada server messenger untuk pesan baru dari pengguna. Ini adalah beban tambahan pada server messenger, sehingga bot dapat "diblokir" untuk sementara waktu. Semua ini, menurut saya, tidak penting untuk penggunaan produktif. Namun untuk ujian dan pelatihan sangat memungkinkan.

Apa itu webhook dan mengapa?


Untuk produk, saya menganggap solusi yang tepat untuk menggunakan webhook, yaitu, pendekatan di mana bot kami mengharapkan pesan dari server messenger dan tidak "memalu" dengan permintaan berkala: apakah ada pesan baru atau tidak. Dengan webhook, akan seperti ini: pengguna menulis pesan, server messenger mengirimnya ke bot Anda, ia menerima pesan, memprosesnya dan menjawab.

Kenapa Django?


Saya memutuskan untuk membuat bot dengan python, jadi saya menghubungkan dukungan python di hosting. Tapi saya tidak punya pilihan kerangka kerja - hosting hanya memiliki Django. Mereka mengatakan itu berfungsi Instagram, Pinterest, Bitbucket dan Mozilla. Mungkin itu sebabnya hosting menawarkannya.

Kenapa VKontakte, bukan Telegram atau Viber?


Untuk beralih dari yang sederhana ke rumit, penting bagi saya untuk menemukan cara termudah dan paling intuitif untuk membuat webhook. VKontakte ternyata menjadi yang paling dimengerti bagi saya karena bantuan yang jelas dan kemudahan menghubungkan webhook di panel kontrol komunitas di bagian "Manajemen - Bekerja dengan API". Penjelasan tentang bagaimana saya mengkonfigurasi dan menghubungkan semuanya akan lebih jauh. Di masa depan saya ingin membuat bot saya tersedia di Viber. Tetapi dengan Telegram, itu belum dalam perjalanan, karena hosting saya di Rusia, dan Telegram diblokir dari Rusia. Untuk menghindari masalah dengan Telegram, Anda dapat membeli hosting di luar negeri.

Bagaimana cara menginstal webhook untuk VK bot?


Nama domain https: // . Pertama, Anda perlu mendaftarkan nama domain situs dan mendapatkan sertifikat ssl untuk itu.

Saya tidak ingin menggunakan domain root untuk chatbot, jadi setelah mendaftarkan domain, saya membuat subdomain dan menerima sertifikat ssl untuk itu.

Saya melakukan semua manipulasi ini di situs hosting di akun pribadi saya.
Akibatnya, saya menerima alamat situs mybot.mysite.ru dan sertifikat ssl untuk itu.

Kami mendapatkan kunci VK (token) untuk bot. Pertama saya membuat grup tertutup, lalu masuk ke "manajemen" grup, di bagian "Bekerja dengan API". Di tab "Akses Kunci" adalah token, dan di tab "Panggil Balik API" pengaturan webhook.



Instal dan konfigurasikan Django . Mungkin Anda tidak perlu Django untuk menjalankan skrip python Anda, tetapi saya tidak tahu bagaimana cara sebaliknya.

Menggunakan Putty, saya terhubung ke server melalui SSH, mengkonfigurasi dan mengaktifkan lingkungan virtual.

SSH:
virtualenv-2.7 virtualenv/myEnv . virtualenv/myEnv/bin/activate 

perintah di baris pertama menciptakan lingkungan virtual, dan perintah di baris kedua mengaktifkannya (perhatikan spasi setelah periode). Versi 2.7 ditentukan oleh hosting dan mungkin berbeda dalam kasus Anda. Karena itu, baca bantuan hosting.

Selanjutnya dipasang Django
SSH:
 pip install 'django<2' 

Saya menginstal versi Django tidak lebih awal dari yang kedua, karena python 2.7 digunakan pada hosting, dan hanya versi Django yang kurang dari 2 yang bekerja dengannya.

Dan memasang modul python untuk bekerja dengan VKontakte API
SSH:
 pip install vk 


FTP:
Membuat folder untuk proyek-proyek Django di direktori root di hosting. Dia memanggilnya Django.

SSH:
Membuat proyek baru.
 cd django/ django-admin.py startproject mybot 

sebagai hasilnya, folder dengan nama proyek akan dibuat (dalam kasus kami ini adalah "mybot") di folder / django. Ini akan berisi file proyek awal yang dibuat secara otomatis:
/ Django
/ mybot - folder proyek
/ mybot - modul dengan pengaturan proyek kami
__init__.py
settings.py
urls.py
wsgi.py
manage.py

Sebuah proyek di Django adalah sekelompok aplikasi. Aplikasi di Django adalah program yang melakukan tindakan yang ditetapkan oleh pengembang.

SSH:
Membuat aplikasi.
 cd mybot python manage.py startapp vk_bot 

Saya pergi ke folder / django / mybot dan membuat aplikasi baru yang disebut "vk_bot".
Folder dengan nama aplikasi dibuat di folder proyek yang berisi file aplikasi yang dibuat secara otomatis:

/ Django
/ mybot - folder proyek
/ mybot - modul dengan pengaturan proyek kami
__init__.py
settings.py
urls.py
wsgi.py
manage.py
/ vk_bot - folder aplikasi
__init__.py
admin.py
apps.py
models.py
tests.py
views.py

FTP:
Saya mengunduh semua file proyek ke laptop saya untuk bekerja dengan kode.
Untuk bekerja dengan file proyek dan pemrograman, saya menggunakan aplikasi Atom.

Atom:
Mengedit pengaturan proyek dalam file /django/mybot/mybot/settings.py
 ... DEBUG = False ... ALLOWED_HOSTS = [ u'mybot.mysite.ru', ] ... 

Atom:
Pengaturan routing url yang diedit di file /django/mybot/mybot/urls.py
 ... urlpatterns = [ url(r'^vk_bot/', include('vk_bot.urls')), ] ... 

FTP:
Membuat file /django/mybot/vk_bot/urls.py dengan konten berikut :
 from django.conf.urls import url from . import views app_name = 'vk_bot' urlpatterns = [ url(r'^$', views.index, name='index'), ] 

Atom:
Mengedit file /django/mybot/vk_bot/views.py - menambahkan fungsi yang disebut indeks untuk itu yang akan dieksekusi ketika alamat diminta di browser
  https://mybot.mysite.ru/vk_bot/ 


views.py
 # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.views.decorators.csrf import csrf_exempt from django.shortcuts import render from django.http import HttpResponse from bot_config import * # import token, confirmation_token and over constants from bot_config.py import json, vk # vk is library from VK """ Using VK Callback API version 5.5 For more ditalies visit https://vk.com/dev/callback_api """ """ From Django documentation (https://docs.djangoproject.com/en/1.11/ref/request-response/) When a page is requested, Django automatically creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function. This argiment is <request> in def index(request): Decorator <@csrf_exempt> marks a view as being exempt from the protection ensured by the Django middleware. For cross site request protection will be used secret key from VK """ @csrf_exempt #exempt index() function from built-in Django protection def index(request): #url: https://mybot.mysite.ru/vk_bot/ if (request.method == "POST"): data = json.loads(request.body)# take POST request from auto-generated variable <request.body> in json format if (data['secret'] == secret_key):# if json request contain secret key and it's equal my secret key if (data['type'] == 'confirmation'):# if VK server request confirmation """ For confirmation my server (webhook) it must return confirmation token, whitch issuing in administration web-panel your public group in vk.com. Using <content_type="text/plain"> in HttpResponse function allows you response only plain text, without any format symbols. Parametr <status=200> response to VK server as VK want. """ # confirmation_token from bot_config.py return HttpResponse(confirmation_token, content_type="text/plain", status=200) if (data['type'] == 'message_new'):# if VK server send a message session = vk.Session() api = vk.API(session, v=5.5) user_id = data['object']['user_id'] # token from bot_config.py api.messages.send(access_token = token, user_id = str(user_id), message = "Hello, I'm bot!") return HttpResponse('ok', content_type="text/plain", status=200) else: return HttpResponse('see you :)') 

Dalam skrip views.py , dalam fungsi indeks (permintaan) , saya harus menonaktifkan perlindungan yang dibangun ke dalam Django CSRF, karena Saya mendapatkan kesalahan "403 Terlarang". CSRF - Perlindungan Pemalsuan Permintaan Situs Lintas - perlindungan terhadap pemalsuan permintaan lintas situs. Cara kerja CSRF dapat Anda baca di artikel ini.
Untuk menonaktifkan perlindungan, saya menggunakan dekorator @csrf_exempt . Tetapi untuk memberikan perlindungan ini sama saja, tetapi dengan cara yang lebih sederhana, saya menggunakan kunci rahasia, yang terdaftar di bagian manajemen grup di situs web VKontakte.

Bagian kode ini bertanggung jawab untuk memproses permintaan dari server yang akan dikirim untuk menghubungkan webhook kami untuk pemrosesan acara. Anggap saja "konfirmasi" dari webhook kami.
 if (data['type'] == 'confirmation'):# if VK server request confirmation """ For confirmation my server (webhook) it must return confirmation token, whitch issuing in administration web-panel your public group in vk.com. Using <content_type="text/plain"> in HttpResponse function allows you response only plain text, without any format symbols. Parametr <status=200> response to VK server as VK want. """ # confirmation_token from bot_config.py return HttpResponse(confirmation_token, content_type="text/plain", status=200) 

Harap dicatat bahwa saya menyimpan semua pengaturan konfigurasi di file konfigurasi bot yang terpisah bot_config.py dan karena itu hubungkan di awal skrip:
 from bot_config import * # import token, confirmation_token and over constants from bot_config.py 

bot_config.py
 # -*- coding: utf-8 -*- """ Configuration file for VK bot """ # token issued on the VK group web-administration page token = '...' # confirmation token issued on the VK group web-administration page in "Callback API" section confirmation_token = '...' # secret key for cross site request forgery protection. It will be in each VK server request secret_key = '...' 

Dan dalam bagian kode ini ia memproses pesan pengguna:
 if (data['type'] == 'message_new'):# if VK server send a message session = vk.Session() api = vk.API(session, v=5.5) user_id = data['object']['user_id'] # token from bot_config.py api.messages.send(access_token = token, user_id = str(user_id), message = "Hello, I'm bot!") return HttpResponse('ok', content_type="text/plain", status=200) 

Jika sesuatu tampak tidak dapat dipahami, Anda juga dapat membaca artikel tentang pengaturan Django pertama .

Keajaiban untuk server web . Untuk mengonfigurasi pengalamatan permintaan ke server web, saya pergi ke server dalam folder dengan domain melalui klien FTP FileZilla dan membuat folder " mybot.mysite.ru " di sana, memasukkan tiga file di dalamnya, yang isinya diambil dari bantuan hosting:

.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() 

Di sini "myEnv" adalah nama lingkungan virtual yang Anda buat, "django" adalah folder di bagian root dari sistem file di hosting, "mybot" adalah nama proyek yang kami buat menggunakan Django.

index.html
    

"Bind" webhook kami ke pemrosesan pesan di grup VKontakte yang dibuat.
Untuk melakukan ini, kami akan kembali ke bagian untuk mengelola grup kami di situs web VKontakte (lihat tangkapan layar di atas). Kami akan memasukkan alamat webhook kami di bidang "Alamat"
  https://mybot.mysite.ru/vk_bot/ 
dan klik tombol "Konfirmasi". Jika fungsi indeks (permintaan) kami , ditulis dalam file /django/mybot/vk_bot/views.py, berfungsi dengan benar, yaitu, tidak mengandung kesalahan ketik dan kesalahan, tanda centang hijau akan muncul, menyimbolkan bahwa semuanya baik-baik saja.

Agar webhook kami menerima pesan dari server VKontakte tentang pesan pengguna baru, di bagian untuk mengelola grup kami di situs web VKontakte, di tab "Jenis Acara", centang kotak "pesan masuk".

Akibatnya, skrip kami akan menerima pesan-pesan ini dalam format 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"} 

Harap dicatat bahwa ada bidang "rahasia" di pesan json . Ini adalah kunci rahasia yang sama dengan yang saya daftarkan di bagian manajemen grup situs web VKontakte, alih-alih perlindungan yang dibangun ke dalam Django CSRF, yang harus saya nonaktifkan.

Bagaimana cara membuat bot lebih pintar dan lebih baik?


Anda dapat membuat database dengan jawaban kepada pengguna dan mengajarkan bot untuk memilih jawaban yang paling dekat dengan makna pertanyaan pengguna. Saya akan membicarakan ini di artikel terpisah.
Dimungkinkan dan perlu untuk memprogram skenario interaksi pengguna, sehingga untuk berbicara, untuk mempertahankan percakapan.

Semoga sukses dalam karya kreatif Anda!

Source: https://habr.com/ru/post/id429628/


All Articles