user@linuxtrack:~ $ python -c 'print("Soyez les bienvenus !")'

Vous n'êtes pas identifié(e).

#1 29-10-2019 07:25:37

petitegirafe
Membre

Tuto Socket Bot IRC python2

Bon voila j'ai eu besoin de me faire un bot IRC , malheuresement plus beaucoup de lib disponible ....
Parce ce que c'est en partagent nos connaissances que l'on évolue .... ( je prépare le même pour python3)

Tuto créer son bot IRC avec python

Je vais détailler mon code étape par étape , je laisserai la source complet  à la fin . botSocket_IRC.py
Commençons par le commencement , déclaration des imports et des variables global ( port, nom , serveur , ......)

#!/usr/bin/env python 
# -*- coding: utf-8 -*-
import socket, time, sys, string
PORT =     6667
server = "irc.root-me.org" # Ou autres 
channel = "#testBot" #cyber-nux 
botnick = "hackuza" # nom donné au bot 
# pseudo des administrateurs pour pouvoir controler le bot 
adminBot = ["petitegirafe", "AUtreAdmin", "admin"] 

On Initialise maintenant notre Class :

class IrcBot:
    
    def __init__(self):
        # creation du socket
        self.ircsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #connection du socket
        self.ircsocket.connect((server, PORT))        
        # Renseignement nom du bot  
        self.ircsocket.send(bytes("USER "+ botnick +" "+ botnick +" "+ botnick + " bot\n"))
        self.ircsocket.send(bytes("NICK " + botnick + "\n"))
        self.mainBot() #on lance notre fonction principal main bot elle contient notre boucle principal d'événements

Notre fonction qui sert à joindre le channel , appellée dés le debut de main bot.

    def jointChannel(self):
        # fonction pour joindre le channel IRC
        ircmsg = ""
        time.sleep(1) # Time sleep 1 seconde sinon bug à la connection 
        # On joint notre channel
        self.ircsocket.send(bytes("JOIN "+ channel +"\n"))
        print "Connection on {}  ".format(channel)
        # On créer une boucle pour récuperer la liste de toute les perconnes connectés sur le channel 
        while ircmsg.find("End of /NAMES list.") == -1:
            ircmsg = self.ircsocket.recv(2048)
            print(ircmsg).strip('\n\r')# affichage pseudo 

Notre fonction principal , elle contiendra notre boucle principal d'événements . C'est de là que l'on recevra tout les messages du serveur IRC .
Les messages reçus sont sous cette forme :" :nom_de_l'envoyeur!petitegiraf@hzv-alm.8of.lb2mnu.IP PRIVMSG #root-me :le message"
En vert : le nom de l'envoyeur du message. En jaune: le nom de l'administrateur et du serveur . En rouge :le type  de message (PRIVMSG, PING, ...). En Bleu :le nom du canal si c'est un message public ou le nom de la personne qui doit recevoire le message en privé . Puis le message ....  Le point d'exclamation sert de délimitateur .
C'est donc d'ici que nous allons découper notre message pour savoir quoi en faire  par la suite.
Notre main :

    def mainBot(self):
        self.jointChannel() # On joint le channel 
        # On lance notre boucle d'événements
        while 1 :
            # récuperation message par le socket
            ircmsg = self.ircsocket.recv(2048)
            
            # Si le message comporte PRIVMSG (message privée ou public sur le channel)
            if "PRIVMSG" in ircmsg :
                # On coupe le message pour récuperer le nom de celui qui l'envoi 
                name = ircmsg.split('!')[0][1:].rstrip()#on coupe point d'exclamation et on garde la premiére partie moins le premier caractère(:)
                message = ircmsg.split('PRIVMSG')[1]#on récupère toute la partie aprés le type du message (privée ou pas plus le message)
                # Appel de la fonction qui définie si c'est un message public ou privé
                self.mode_message(name, message.rstrip('\n'), channel)# on lui envoie le name ,le message et le channel
            # Si le message contient PING On appelle la fonction ping pour ne pas être déconnecté      
            if ircmsg.find("PING :") != -1:
                self.ping()

Notre simple fonction ping qui renvoie simplement pong au serveur :

    def ping(self):
        self.ircsocket.send(bytes("PONG :pong\n"))

Fonction qui va déterminer si le message est privé ou dans le canal public .(Souvenez vous nous avons encore deux parties distinte dans le message (le canal ou le nom de la personne qui doit recevoir le message et le message))

    def mode_message(self, name, message, channel):
        # Si le nom du bot est égale à la premiére partie du message (message privé au bot)
        if botnick == message[1:len(botnick)+1]: # enléve le premier caractére(c'est un espace) donc on rajoute un au nombre de caractère (len(botnick))
            # Appel à la fonction message privé  
            self.on_privmsg(name, message[len(botnick)+2:], channel) #on envoie que la dernière parie du message [len(botnick)+2:]car 2 espaces un au debut l'autre à la fin
        # Si le nom du channel est bien égale à la premiére partie du message)
        if channel == message[1:len(channel)+1].strip():
            # Appel à la fonction message public 
            self.on_pubmsg(name, message[len(channel)+2:], channel)

Fonction appellée quand le bot reçoit un message privé.

    def on_privmsg(self, name, message,channel):
        if name.strip() in adminBot:# Si le nom fait partie de la liste des admin
            # Appel à la fonction admin bot
            self.on_adminBot(name, message, channel)
            pass
        else : # Sinon
            print('[Privé-]: ' + name +": " + message)
            # On envoi le message ho je suis un bot à l'envoyeur
            self.ircsocket.send(bytes("PRIVMSG " + name + " :Ho je suis un bot \n"))

Fonction appellée quand le message est public:
Utilisation des options:
1572410336.png

	# Fonction appellée quand le message est public
	def on_pubmsg(self, name, message, channel):
		r = re.search(r"^:!.+", message)
		if r: # Si la ligne commence bien par :! 
			usr_common = r.group(0).split()[0]
			self.check_common(usr_common, message, channel)
			pass
		else:# Sinon
			print('[Public]: '+ name + ' ' + message.strip())#on affiche seulement le message dans le terminall

Fonction qui check_common:

    # check la commande pour appeller la fonction adéquat        
    def check_common(self, usr_common,  message, channel):
        message = message[len(usr_common.split()[0]):]
        if usr_common == ":!rot13":
            self.on_rot13(message ,channel)    
        if usr_common == ":!rot47":    
            self.on_rot47(message ,channel)

Fonction admin bot pour le faire quitter IRC ou le faire parler à notre place sur le canal public

	def on_adminBot(self, name, message, channel):
		r = re.search(r"^:!.+", message)
		if r:
			adm_common = r.group(0).split()[0]
			message = message[len(adm_common.split()[0]):] 
			if adm_common == ":!print":
				# si print in commande le bot j'envoie ce que l'on lui à ecrie dans le canal public 
				print('[Public]:' + botnick + ": " + message.strip())
				self.ircsocket.send(bytes("PRIVMSG " + channel + " " + message.strip() + '\n'))
			if adm_common == ":!exit":
				# Si la commande est "exit(" le bot dit aurevoir et ce deconnect
				self.ircsocket.send(bytes("PRIVMSG " + channel + " : Bye all !!!\n"))
				self.ircsocket.send(bytes("QUIT \n"))#deconnection
				sys.exit()# fin du programme
		else:# Sinon il recrie se que l'on à écrie dans le terminal
			print('[Privé ]: ' + name +": " + message)

Enfin nos 2 fonction srot13 et rot47:

    def on_rot13(self, message, channel):
        rot13Table = string.maketrans("ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",
                                      "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")
        message =  message.translate(rot13Table)
        self.ircsocket.send(bytes("PRIVMSG " + channel + " : " + message + '\n'))
        print('[Reponse]: ' + botnick + ': ' + message)
        
    def on_rot47(self, message, channel):
        rot47Table = string.maketrans('!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
                                    'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO')
        message =  message.translate(rot47Table)
        self.ircsocket.send(bytes("PRIVMSG " + channel + " : " + message + '\n'))
        print('[Reponse]: ' + botnick + ': ' + message)     

Voila  big_smile une bonne base pour créer votre BOT IRC  big_smile  big_smile

if __name__ == "__main__":
    IrcBot()

Dernière modification par petitegirafe (30-10-2019 11:39:20)

Hors ligne

Pied de page des forums