📜 ⬆️ ⬇️

Creating a simple chat bot in VK in Python 3

Creating a basis for the bot will consist of the following steps:


  1. Creating a bot in VK
  2. API key generation
  3. Creating a bot program via LongPoolVK

Who is this article for?


The article is designed for novice programmers. The method of the program is very simple and anyone who knows how to understand the syntax of Python and a little knowledge of the PLO will be able to implement it for their needs. But in principle, even without knowing any principles of OOP, I think you can learn how to add simple functions or at least in the extreme case use ready source codes from GitHub.

What is in this article?


Creating the basis of the bot. After that, it can be programmed as you like. Automate some routine or use as a source.

Improved (slightly complicated version of the bot). I decided to first present a simple procedural code of the bot, and then slightly complicate it by adding features that greatly improve the work of the bot.
')
Adding weather transmission function. Let's teach the bot to tell us the weather.

Creating a bot in VK


We begin with the creation of a bot, namely a group in the VC.

For this you need to go to "groups" → "create a community."

Select any type of community and enter the name, subject of the group.

On the settings page that opens, select "Work with API"

Next, you need to create an API key.

Then select the parameters you need with access for your API key.

Most likely, you will have to confirm the action in the VC using a mobile phone. Then copy the resulting API key somewhere in the file. We still need it.

Then you need to enable messages. To do this, go to the "message" and turn them on.

Let's start the program part of the bot


We will not implement it through requests to the VC, and to be more precise, we simply use the VkLongPool library, which will do it for us.

This requires the library vk_api. Install it via pip:

python -m pip install vk_api

But personally, I work with the Anaconda virtual environment. With this, problems often arise during the first job. Usually the problem is that the system does not recognize the python command. And this problem is solved by adding it to the PATH.

Let's get to the code itself:

We import the necessary modules:

import vk_api from vk_api.longpoll import VkLongPoll, VkEventType 

Then the code:

 def write_msg(user_id, message): vk.method('messages.send', {'user_id': user_id, 'message': message}) # API-   token = "6a9c267cd469388709a9e9acaddbe0aa81a0abbf12239b3e597a31729ffbddb9c88e80a443554c918b8f7" #    vk = vk_api.VkApi(token=token) #    longpoll = VkLongPoll(vk) #   for event in longpoll.listen(): #     if event.type == VkEventType.MESSAGE_NEW: #      (   ) if event.to_me: #    request = event.text #    if request == "": write_msg(event.user_id, "") elif request == "": write_msg(event.user_id, "((") else: write_msg(event.user_id, "   ...") 

The write_msg function gets the user ID of the VC <user_id> to which it will send the message and the message itself.

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

Log in as a community and configure longpool:

 # API-   token = "6a9c267cd469388709a9e9acaddbe0aa81a0abbf12239b3e597a31729ffbddb9c88e80a443554c918b8f7" #    vk = vk_api.VkApi(token=token) #    longpoll = VkLongPoll(vk)    : #   for event in longpoll.listen(): 

In it, we will cyclically check for the presence of event-s. And we can get the event type using event.type.

After receiving the message from the user, we will be able to send him a corresponding letter using the already created write_msg function.

So, we have created a very simple bot in VK with the same simple implementation. And the logic of the bot can be programmed as you please.

Code listing in gh

Now we will start more real programming.


Let's create the VkBot class in the vk_bot.py file that will serve as a bot.

 class VkBot: def __init__(self, user_id): print("  !") self._USER_ID = user_id self._USERNAME = self._get_user_name_from_vk_id(user_id) self._COMMANDS = ["", "", "", ""] 

And add there a method with which you can get the user name through vk id.

 def _get_user_name_from_vk_id(self, user_id): request = requests.get("https://vk.com/id"+str(user_id)) bs = bs4.BeautifulSoup(request.text, "html.parser") user_name = self._clean_all_tag_from_str(bs.findAll("title")[0]) return user_name.split()[0] 

This is done using beatifulsoup4.

Install if it is not:
python -m pip install bs4
It has a sufficient number of articles that are worth studying. By means of it we will create some more methods:

 #  : def _get_time(self): request = requests.get("https://my-calend.ru/date-and-time-today") b = bs4.BeautifulSoup(request.text, "html.parser") return self._clean_all_tag_from_str(str(b.select(".page")[0].findAll("h2")[1])).split()[1] #   def _get_weather(city: str = "-") -> list: request = requests.get("https://sinoptik.com.ru/-" + city) b = bs4.BeautifulSoup(request.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 #       @staticmethod def _clean_all_tag_from_str(string_line): """   stringLine      :param string_line:   :return:   """ result = "" not_skip = True for i in list(string_line): if not_skip: if i == "<": not_skip = False else: result += i else: if i == ">": not_skip = True return result 

Change the _get_weather parameter to the desired city, later this method can be called with the indication of the city, and the default will be your specified value.

With these methods we can get the time and weather. These methods are cut from my main bot project. They should be organized in separate packages and classes, applying inheritance. But for the sake of the example of work, I decided to fit it all into one bot class, which of course is bad.

Let's create the main method new_message, which will process the user's message and return the answer:

 def new_message(self, message): #  if message.upper() == self._COMMANDS[0]: return f"-, {self._USERNAME}!" #  elif message.upper() == self._COMMANDS[1]: return self._get_weather() #  elif message.upper() == self._COMMANDS[2]: return self._get_time() #  elif message.upper() == self._COMMANDS[3]: return f"-, {self._USERNAME}!" else: return "    ..." 

Now back to the file being run:

We import the class of our bot:

 from vk_bot import VkBot 

Let's change our main cycle:

 print("Server started") for event in longpoll.listen(): if event.type == VkEventType.MESSAGE_NEW: if event.to_me: print('New message:') print(f'For me by: {event.user_id}', end='') bot = VkBot(event.user_id) write_msg(event.user_id, bot.new_message(event.text)) print('Text: ', event.text) 

That is, now we will transmit the received message to the bot object, which will return the desired answer to us.

This complication of the program is necessary if you want to further improve the functionality of the bot:

Create separate packages and classes for each _get_time and _get_weather functions. Organize inheritance from the general class. And define each new function in separate classes, the best, of course, also divided into packages.

Add a dictionary with the user ID key and the bot object value. Thus, it is not necessary to create a bot object every time in the loop. In addition, it will ensure the use of several users at once in complex structures.

Thus, choosing a good code architecture, you can create a multifunctional bot.

For example, I taught my bot to play music on a computer, open sites while sitting on the phone. Send recipes for breakfast, lunch, dinner.

You can edit the bot for yourself.

Boat from the article

The main project of the bot (improved) on GH

I will be glad to your ideas. For any questions please write.

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


All Articles