Quiz bot for VKontakte

Community administrators for "Smeshariki"
, — .



Introduction



About three months ago, my friends on the VKontakte network in a general chat (conversation) played a guessing game - a game based on the cartoon "Smeshariki", which we all love. Rules: the host writes quotes of cartoon characters, players guess from which series this quote is. I decided to make the game more interesting and assign it to the role of the leading bot.



Group creation



In order to create a group or a community for our bot, you need to go to the "Communities" section in VKontakte and click on the "Create a community" button in the upper right corner.



image



We select the type of community "Interest group".



image



Coming up with a name, choosing a topic, leaving the type of group open.



image



Now we need to find out the ID and create a group token.



If the ID can be found in the address bar after the word "club", then you will need to worry a little with the token.



image



Go to group management:



image



Select the "Working with API" section and enable "Long Poll API" there for the bot to work.



image



Next, go to "Access Keys", create an access key with the following settings:



image



The resulting access key is our token:



image



The only thing left is to allow the group to be added to conversations.



Go to the section "Messages -> Settings for the bot", turn on the "Bots capabilities" and click on "Allow to add community to conversations". We save.



image



Installing the vk_api module



In order to install the module for working with Vkontakte API, you need to write the following command in the command line:



pip3 install vk_api


You also need to create a file "points.pickle" in the bot directory.



Basic functions



Moving on to the software part: We

connect the necessary plugins: pickle, random, requests and the vk_api library, thanks to which you can work with VKontakte.



import random
import pickle
import requests
from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType 
#  BotLongpoll -        .


We create a dictionary with quotes and dictionaries for storing information:



series = {"":[" 1", " 2"], "":[" 1", " 2"]}
series_in_chats = {} 
quotes_in_chats = {}
points = {}


The quotes themselves are enclosed in lists in the keys of the "series" dictionary so that there are many quotes per series.



The variable "series_in_chats" is needed to store information about the series in a separate conversation, the variable "quotes_in_chats" is similar, only to store information about the quote.



Now we connect to the group:



vk_session = vk_api.VkApi(token=" ") #  ID 
longpoll = VkBotLongPoll(vk_session, "ID  ") #  
vk = vk_session.get_api()


You can create a function to send messages more conveniently:



def send(ch_id, msg):
    vk.messages.send(chat_id=ch_id, random_id=random.randint(1, 9999999), message=msg)


Arguments:
ch_id # ID ,     
msg #  




vk.messages.send(chat_id, random_id, message)


Method for sending messages.



Required parameters:



chat_id - ID ,    ,
random_id -   ,        ,
message -  .


Read more about the method here.



Processing messages



while True: # 
    try: 
        for event in longpoll.listen():
	    if event.type == VkBotEventType.MESSAGE_NEW and event.from_chat:
		chat_id = int(event.chat_id) #ID ,    
                text = event.object.text.lower() # 
                man = event.obj.from_id #ID   ,  
                if chat_id not in series_in_chats:
                    episode = random.choice(series.keys()) #   
                    #  
                    quote = random.choice(series.get(episode)) #    
                    # 
                    series_in_chats.update({chat_id:episode}) #   
                    quotes_in_chats.update({chat_id:quote}) #   
                    #     ,      
                    #      .
    except:
        continue
        # try except -    - 
        #  ,   


Now we can process messages received by the group, send messages on behalf of the group and much more.



We introduce glasses



This code needs to be inserted after checking "if chat_id not in series_in_chats":




                if points == {}:
                    with open('points.pickle', 'wb') as f:
                        pickle.dump(points, f)
                    with open('points.pickle', 'rb') as f:
                        
                        points = pickle.load(f) 
                if isinstance(points.get(man), int) == False:
                    points.update({man:0})
                    with open('data.pickle', 'wb') as f:
                        pickle.dump(points, f)
                        #     points
                        #   
                       


Guessing



We check: if the message received in the conversation equals the word "guess", the bot will respond with a quote that needs to be guessed (all this after checking "if isinstance"):




if text == "":
    send(chat_id, ",     : "+ quotes_in_chats.get(chat_id))


It remains only to check the correctness of the series - if the message contains the name of the series, the bot will reply that the series was guessed:




if series_in_chats.get(chat_id) in text:
    
    send(chat_id, "  !")
    points.update({man:points.get(man)+1}) # 1 
    
    with open('points.pickle', 'wb') as f:
        pickle.dump(points, f) #     
    send(chat_id, "  !\n   : "+str(points.get(man)))
    #   :
    episode = random.choice(series.keys()) #   
    #  
    quote = random.choice(series.get(episode)) #    
    # 
    series_in_chats.update({chat_id:episode}) #   
    quotes_in_chats.update({chat_id:quote}) #   
    


Conclusion



As a result, the bot will work something like this:







Of course, on this basis, you can create almost any bot - not just a guess.



The created bot can be seen in the VKontakte community " Abode of Quests | Smeshariki ".



By the way, he works not only in chats, but also in private messages.



And it also has a few things that I did not talk about here.



All Articles