Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep a python 3 script (Bot) running

Tags:

python

bots

api

(Not native English, sorry for probably broken English. I'm also a newbie at programming).
Hello, I'm trying to connect to a TeamSpeak server using the QueryServer to make a bot. After days of struggling with it... it works, with only 1 problem, and I'm stuck with that one.

If you need to check, this is the TeamSpeak API that I'm using: http://py-ts3.readthedocs.org/en/latest/api/query.html

And this is the summary of what actually happens in my script:

  1. It connects.
  2. It checks for channel ID (and it's own client ID)
  3. It joins the channel
  4. Script ends so it disconnects.

My question is: How can I make it doesn't disconnects? How can I make the script stay in a "waiting" state so it can read if someone types "hi bot" in the channel? All the code needed to read texts and answer to them seems easy to program, however I'm facing a problem where I can't keep the bot "running" since it closes the file as soon as it ends running the script.

More info:
I am using Python 3.4.1.
I tried learning Threading http://www.tutorialspoint.com/python/python_multithreading.htm but either M'm dumb or it doesn't work the way I though it would.
In the API there's a function named on_event that I would like to keep running all the time. The bot code should only be run once and then stay "waiting" until an event happens. How should i do that? No clue.

Code:

import ts3
import telnetlib
import time

class BotPrincipal:
    def Conectar(ts3conn):
        MiID = [i["client_id"] for i in ts3conn.whoami()]
        ChannelToJoin = "[Pruebas] Bots"
        ts3conn.on_event = BotPrincipal.EventHappened()
        try: 
            BuscandoIDCanal = ts3conn.channelfind(pattern=ChannelToJoin) 
            IDCanal = [i["cid"] for i in BuscandoIDCanal]
            if not IDCanal: 
                print("No channel found with that name")
                return None
            else:
                MiID = str(MiID).replace("'", "")
                MiID = str(MiID).replace("]", "")
                MiID = str(MiID).replace("[", "")
                IDCanal = str(IDCanal).replace("'", "")
                IDCanal = str(IDCanal).replace("]", "")
                IDCanal = str(IDCanal).replace("[", "")                
                print("ID de canal " + ChannelToJoin + ": " + IDCanal)
                print("ID de cliente " + Nickname + ": " + MiID)
            try:
                print("Moving you into: " + ChannelToJoin)
                ts3conn.clientmove(cid=IDCanal, clid=MiID) #entra al canal
                try:
                    print("Asking for notifications from: " + ChannelToJoin)
                    ts3conn.servernotifyregister(event="channel", id_=IDCanal)
                    ts3conn.servernotifyregister(event="textchannel", id_=IDCanal)
                except ts3.query.TS3QueryError:
                    print("You have no permission to use the telnet command: servernotifyregister")
                print("------- Bot Listo -------")
            except ts3.query.TS3QueryError:
                print("You have no permission to use the telnet command: clientmove")
        except ts3.query.TS3QueryError:
            print("Error finding ID for " + ChannelToJoin + ". telnet: channelfind")

    def EventHappened():
        print("Doesn't work")

# Data needed #
USER = "thisisafakename"
PASS = "something"
HOST = "111.111.111.111"
PORT = 10011
SID = 1

if __name__ == "__main__":    
    with ts3.query.TS3Connection(HOST, PORT) as ts3conn:
        ts3conn.login(client_login_name=USER, client_login_password=PASS)
        ts3conn.use(sid=SID)
        print("Connected to "+HOST)
        BotPrincipal.Conectar(ts3conn)
like image 474
Saelyth Avatar asked Oct 20 '22 00:10

Saelyth


1 Answers

From a quick glimpse at the API, it looks like you need to explicitly tell the ts3conn object to wait for events. There seem to be a few ways to do it, but ts3conn.recv(True) seems like the most obvious:

Blocks untill all unfetched responses have been received or forever, if recv_forever is true.

Presumably as each command comes in, it will call your on_event handler, then when you return from that it will go back to waiting forever for the next command.

I don't know if you need threads here or not, but the docs for recv_in_thread make it sound like you might:

Calls recv() in a thread. This is useful, if you used servernotifyregister and you expect to receive events.

You presumably want to get both servernotify events and also commands, and I guess the way this library is written you need threads for that? If so, just call ts3conn.recv_in_thread() instead of ts3conn.recv(True). (If you look at the source, all that does is start a background thread and call self.recv(True) on that thread.)

like image 57
abarnert Avatar answered Oct 23 '22 18:10

abarnert