Pada artikel ini, kita akan membuat bot dan mengintegrasikannya ke dalam grup VK di Python 3.x
Untuk siapa artikel ini?
Bagi mereka yang ingin menulis bot sederhana untuk komunitas mereka, dapat mengidentifikasi tim dan menampilkan jawaban yang sesuai
Tahap utama
Membuat grup bot
Kami akan mulai dengan membuat bot, yaitu grup di VK.
Untuk melakukan ini, buka "grup" โ "buat komunitas."
Pilih semua jenis komunitas dan masukkan nama, tema grup.
Pada halaman pengaturan yang terbuka, pilih "Bekerja dengan API."
Selanjutnya, Anda perlu membuat kunci API.
Kemudian pilih parameter yang Anda butuhkan dengan akses untuk kunci API Anda.
Kemungkinan besar, Anda harus mengkonfirmasi tindakan dalam VK menggunakan ponsel Anda. Kemudian salin kunci API yang dihasilkan di suatu tempat ke file. Kami masih membutuhkannya.
Maka Anda perlu mengizinkan pesan. Untuk melakukan ini, buka "pesan" dan nyalakan. Aktifkan juga "Fitur Bot" di "Pesan" -> "Pengaturan untuk bot."
Di sana kami akan mengizinkan menambahkan komunitas ke grup jika kami ingin bot dapat menerima pesan dari grup.
Menyiapkan Poll Panjang
Untuk bekerja dengan Long Poll API, kami menggunakan pustaka
vk_api . Anda dapat menginstalnya melalui pip.
Sebelum bekerja, kami akan menyimpan token API kami di file config.py, dari sana kami akan memuat kunci kami.
Mari kita buat skrip pertama kami. Beri nama server.py, yang akan menjadi skrip server utama.
Kami mengimpor modul yang kami butuhkan:
import vk_api.vk_api from vk_api.bot_longpoll import VkBotLongPoll from vk_api.bot_longpoll import VkBotEventType
Buat kelas server:
class Server: def __init__(self, api_token, group_id, server_name: str="Empty"):
Sekarang buat file server_manager.py, di mana ia akan mengelola server yang berbeda. Untuk saat ini, untuk pengujian, kami hanya menulis panggilan ke kelas Server:
Penting!
Bot hanya dapat menulis pesan kepada pengguna yang telah mengizinkan bot mengirim pesan. Anda dapat melakukan ini di halaman komunitas atau menulis bot terlebih dahulu
Jika semuanya dilakukan dengan benar, bot akan mengirimkan kami pesan pribadi.
Sekarang tambahkan bot ke grup dan ajari dia cara memproses pesan.
Untuk menambahkan bot ke grup, klik "Undang ke percakapan" di menu kanan komunitas.
Tambahkan fungsi mulai ke bot, setelah itu akan mulai "mendengarkan" pesan melalui Long Poll (jangan lupa untuk menambahkan izin ke jenis acara di bagian "Bekerja dengan API" -> "Long Poll API" dan meletakkan versi terbaru):
def start(self): for event in self.long_poll.listen(): print(event)
Jalankan melalui server_manager.py:
server1.start()
Sekarang, jika kita menulis pesan ke grup, kita dapat melihat objek acara:
<< class 'vk_api.bot_longpoll.VkBotMessageEvent'> ({'type': 'message_new', 'object': {'date': 1541273151, 'from_id': 25599999999, 'id': 0, 'out': 0, 'peer_id': 2000000001, 'text': '[club172998024 | bot di da Vk] ini adalah teks!', 'conversation_message_id': 187, 'fwd_messages': [], 'penting': Salah, 'random_id': 0 , 'lampiran': [], 'is_hidden': False}, 'group_id': 172998024})>
Juga, jika kita menulis dalam pesan pribadi:
<< class 'vk_api.bot_longpoll.VkBotMessageEvent'> ({'type': 'message_new', 'object': {'date': 1541273238, 'from_id': 25599999999, 'id': 47, 'out': 0, 'peer_id': 255396611, 'text': 'ini adalah pesan pribadi', 'conversation_message_id': 47, 'fwd_messages': [], 'penting': Salah, 'random_id': 0, 'lampiran': [], 'is_hidden ': False},' group_id ': 172998024})>
Dari data ini, kita harus memperhatikan
jenis, object.from_id, object.id, object.peer_id, object.text . Data yang diterima dari pesan dan dari grup tidak berbeda jauh kecuali
object.peer_id dan
object.id .
Jika Anda perhatikan dengan seksama, object.id untuk semua pesan dari grup adalah 0, tetapi tidak ada pesan dari pesan pribadi. Dengan demikian, dimungkinkan untuk memisahkan pesan yang diterima dari grup dan dari pesan pribadi.
Kami memproses data yang diterima di dalam kelas Server:
def start(self): for event in self.long_poll.listen():
Kami akan menulis dua pesan ke bot: satu dari grup, satu di PM. Lalu kita dapatkan:
Nama pengguna: Arthur
Dari: Saint Petersburg
Teks: [club172998024 | @ club172998024] ini adalah pesan dari grup
Ketik: pesan grup
-
Nama pengguna: Arthur
Dari: Saint Petersburg
Teks: ini adalah pesan pribadi
Ketik: pesan pribadi
-
Catatan
Seperti yang dapat Anda lihat sebelum pesan dalam grup ada [club172998024 | @ club172998024], agar tim dapat memproses dengan benar, Anda harus menyingkirkan semua konten dalam tanda kurung siku, atau mengizinkan bot mengakses semua korespondensi
Seperti yang bisa kita lihat, vk_api memungkinkan kita untuk dengan mudah menggunakan metode VK API. Misalnya, sekarang kami menggunakan metode
users.getDaftar semua metode tersedia di:
vk.com/dev/methodsSaya menyarankan Anda untuk belajar dan bereksperimen dengan metode yang menarik minat Anda. Untungnya VK memberi kami dokumentasi yang sangat bagus, juga dalam bahasa Rusia.
Untuk mengkonsolidasikan materi, mari tambahkan fungsi untuk mengirim pesan melalui metode
messages.send :
def send_message(self, peer_id, message): self.vk_api.messages.send(peer_id=peer_id, message=message)
<peer_id> adalah pengidentifikasi tujuan. Untuk menanggapi pesan seseorang, kami akan menentukan
event.object.peer_id sebagai parameter
peer_id . Artinya, kami akan mengirim pesan ke tempat asal permintaan itu.
Ubah metode mulai:
def start(self): for event in self.long_poll.listen():
Sekarang, jika bot menerima pesan, maka bot akan menanggapi kami dengan gaya ini:
Arthur, saya mendapat pesan Anda!
Seluruh kodeserver.py
import vk_api.vk_api from vk_api.bot_longpoll import VkBotLongPoll from vk_api.bot_longpoll import VkBotEventType class Server: def __init__(self, api_token, group_id, server_name: str="Empty"):
server_manager.py
Tugas untuk memperbaiki materi:
Buat fungsi yang mengambil parameter peer_id dan mengirim pengguna foto yang diunggah ke komunitas. Dock yang Berguna:
vk.com/dev/messages.sendSolusiPertama, unggah foto ke grup dan buka di VK, pertimbangkan tautannya:
vkcom / club172998024? z = foto-172998024_456239017 % 2Falbum-172998024_256250731
Kami hanya tertarik pada bagian yang disorot:
foto-172998024_456239017 . Lulus sebagai argumen ke metode messages.send:
def send_img(self, peer_id): self.vk_api.messages.send(peer_id=peer_id, attachment="photo-172998024_456239017")
Tambahkan ke metode mulai dan dapatkan:

Itu semua dasar-dasarnya. Hal utama adalah mempelajari cara menggunakan vk_api menggunakan berbagai metode, seluruh daftar mereka adalah:
vk.com/dev/methods . Jika Anda belajar cara bekerja dengan dokumentasi VK API, Anda dapat membuat bot dengan berbagai kompleksitas dan tujuan. Contoh bot saya untuk grup studi:
github.com/AppLoidx/GroupAssistant/tree/masterSekarang mari kita mulai membuat logika bot.
Buat commander.py, yang akan menerima perintah dan mengembalikan respons yang diteruskan ke pengguna Vk:
class Commander: def __init__(self, vk_api, user_id): self.vk_api = vk_api self.user_id = user_id def input(self, msg): """ :param msg: :return: , """ pass
Mari kita bangun arsitektur program kami:
Kami "mendengarkan" ke server Polling Panjang dan menerima pesan pengguna ->
Kami meneruskan pesan ke Commander.input () -> Tentukan mode -> Tentukan perintah ->
Kami mengembalikan jawabannya -> Kami mentransfer ke pengguna
Untuk mendefinisikan mode dan perintah, kita membuat dua file command_enum.py dan mode_enum.py. Dengan menggunakannya, kita akan mendefinisikan mode dan perintah melalui metode kelas Enum:
command_enum.py:
from enum import Enum class Command(Enum): """ weather """ weather = ["weather", ""] """ myanimelist """ anime_top = ["top anime", " "]
mode_enum.py:
from enum import Enum class Mode(Enum): default = [" ", "default"] translate = [" ", "translate"] get_ans = 0
Untuk mengubah mode, gunakan [slash ("/") + <mode_name>], dan kami akan menerima semua perintah lain sebagai perintah.
Kami menerapkan ini di Commander.py:
weather.py import requests from bs4 import BeautifulSoup class Weather: @staticmethod def get_weather_today(city: str = "-") -> list: http = "https://sinoptik.com.ru/-" + city b = BeautifulSoup(requests.get(http).text, "html.parser") p3 = b.select('.temperature .p3') weather1 = p3[0].getText() p4 = b.select('.temperature .p4') weather2 = p4[0].getText() p5 = b.select('.temperature .p5') weather3 = p5[0].getText() p6 = b.select('.temperature .p6') weather4 = p6[0].getText() result = '' result = result + (' :' + weather1 + ' ' + weather2) + '\n' result = result + (' :' + weather3 + ' ' + weather4) + '\n' temp = b.select('.rSide .description') weather = temp[0].getText() result = result + weather.strip() return result
myanimelist.py import requests import bs4 class Myanimelist: @staticmethod def get_top(count: int=5, by: str="") -> dict: types = ["", "airing", "upcoming", "tv", "movie", "ova", "special", "bypopularity", "favorite"] if by not in types: return {"error: ": " !"} html = requests.get("https://myanimelist.net/topanime.php?type="+by) soup = bs4.BeautifulSoup(html.text, "html.parser") res = {} for anime in soup.select(".ranking-list", limit=count): url = anime.select(".hoverinfo_trigger")[0]['href'] anime = anime.select(".hoverinfo_trigger")[0].findAll("img")[0] name = anime['alt'].split(":")[1].strip(" ") res[name] = url return res
yandex_translate.py import requests from config import yandex_translate_api class Translator: """ - API Yandex Translate : _key -- API Yandex.Translate _yandex_comment -- API Yandex.Translate """ def __init__(self, key, comment=None): """ :param key: API Yandex.Translate :param comment: """ self._key = key if comment is None: self._yandex_comment = "\n ยซ.ยป http://translate.yandex.ru/" else: self._yandex_comment = comment def translate(self, text, lang, to_lang=None): """ :param text: , :param lang: :param to_lang: :return: """ if to_lang is not None: lang = f"{lang}-{to_lang}" main_url = "https://translate.yandex.net/api/v1.5/tr.json/translate" response = requests.get(f"{main_url}?" f"key={self._key}&" f"lang={lang}&" f"text={text}") return response.json()['text'][0] + self._yandex_comment def lang_identify(self, text, hint="ru,en"): """ :param text: :param hint: :return: """ main_url = "https://translate.yandex.net/api/v1.5/tr.json/detect" response = requests.get(f"{main_url}?" f"key={self._key}&" f"hint={hint}&" f"text={text}") return response.json()['lang'] def translate_ru_en(self, text): """ :param text: , :return: """ if self.lang_identify(text) == "ru": to_lang = "en" from_lang = "ru" else: to_lang = "ru" from_lang = "en" return self.translate(text, from_lang, to_lang) def translate_to_ru(self, text, hint=None): """ :param text: , :param hint: :return: """ if hint is None: hint = "ru,en" from_lang = self.lang_identify(text, hint) return self.translate(text, from_lang, "ru") def translate_to(self, text, to_lang, hint=None): """ :param text: , :param to_lang: :param hint: :return: """ if hint is None: hint = "ru,en" from_lang = self.lang_identify(text, hint) return self.translate(text, from_lang, to_lang)
Semua kode tersedia di github:
github.com/AppLoidx/VkLongPollBotTambahkan keyboard:
Ini adalah proses yang sangat mudah, komplikasi dapat disebabkan ketika kita mengubah keyboard ke tanda tangan perintah tertentu, yang berbeda untuk setiap mode.
Untuk menambahkan keyboard ke kotak dialog, Anda harus menentukan parameter keyboard yang menerima json di metode messages.send. Ini terlihat seperti ini:
vk_api.messages.send(...,keyboard=keyboard_json,...)
Atau Anda dapat melewatkan keyboard langsung dari file .json:
vk_api.messages.send(...,keyboard=open(filename,"r",encoding="UTF-8").read()
Dokumentasi:
vk.com/dev/bots_docs_3?f=4.%2BKeyboard%2Bfor%2BworksPertimbangkan contoh program kami dengan menambahkan keyboard.
Pertama, buat file keyboard.json:
{ "one_time": false, "buttons": [ [{ "action": { "type": "text", "label": "top anime" }, "color": "positive" }, { "action": { "type": "text", "label": "weather" }, "color": "positive" }], [{ "action": { "type": "text", "label": "translate" }, "color": "default" }] ] }
Untuk menghapus keyboard, Anda harus memberikan json dengan tombol kosong:
{"buttons":[],"one_time":true}
Abaikan send_message di server.py:
def send_msg(self, send_id, message): """ messages.send :param send_id: vk id , :param message: :return: None """ return self.vk_api.messages.send(peer_id=send_id, message=message, keyboard=open("keyboards/default.json", "r", encoding="UTF-8").read())
Dan juga dalam metode awal:
def start(self): for event in self.long_poll.listen():
Sebagai hasilnya, kita mendapatkan:

Kata terakhir
Anda tidak boleh menggunakan daftar
telanjang kode sumber yang disajikan di sini, mereka hanya digunakan sehingga Anda lebih memahami apa yang terjadi di bawah tenda. Tentu saja, semuanya dapat digunakan dan Anda dapat menggunakannya di bagian-bagian.
Secara pribadi, saya menggunakan bot seperti itu untuk asisten grup yang tahu caranya:
- buat antrian dari anggota grup, termasuk banyak tim yang mengedit antrian, seperti menambah, menghapus, membuat, dll.
- mengirim pesan ke semua peserta
- pertanyaan yang diajukan (misalnya, di Jawa)
- memungkinkan untuk membuat aplikasi untuk pertukaran tempat, dll.
Proyek GithubSumber disajikan di sini