2010-06-03 18 views
19

Necesito ayuda para escribir un bot de IRC básico que solo se conecta a un canal ... ¿alguien me puede explicar esto? Logré hacer que se conectara al servidor IRC, pero no puedo unirme a un canal e iniciar sesión. El código que tengo hasta ahora es:¿Cómo programo un simple bot de IRC en python?

import sockethost = 'irc.freenode.org' 
port = 6667 
join_sock = socket.socket() 
join_sock.connect((host, port)) 
<code here> 

Cualquier ayuda sería muy apreciada.

+3

¿Por qué reinventar la rueda? Ya hay muchos bots de IRC escritos en Python. – jamessan

+34

@jamessan Para aprender, por supuesto :) –

+7

@eric Me encanta esa respuesta: D –

Respuesta

11

Probablemente sería más fácil basarlo en la implementación twisted del protocolo IRC. Eche un vistazo a: http://github.com/brosner/bosnobot para inspirarse.

+2

http://www.habnabit.org/twistedex.html es un tutorial básico IRC bot utilizando t.w.p –

45

para conectarse a un canal de IRC, debe enviar ciertos comandos específicos del protocolo IRC al servidor IRC antes de poder hacerlo.

Cuando se conecta al servidor, debe esperar hasta que el servidor haya enviado todos los datos (MOTD y otras cosas), luego debe enviar el comando PASS.

PASS <some_secret_password> 

Lo que sigue es el comando NICK.

NICK <username> 

Luego debe enviar el comando USUARIO.

USER <username> <hostname> <servername> :<realname> 

Ambos son obligatorios.

Luego es probable que vea el mensaje PING del servidor, debe responder al servidor con el comando PONG cada vez que el servidor le envíe un mensaje PING. El servidor también puede pedir PONG entre los comandos NICK y USER.

PING :12345678 

Responder con exactamente el mismo texto después de "ping" con el comando PONG:

PONG :12345678 

¿Qué hay después de ping es única para cada servidor Creo que sí asegurarse de que responde con el valor que el servidor envía tú.

Ahora usted puede unirse a un canal con JOIN comando:

JOIN <#channel> 

Ahora puede enviar mensajes a canales y usuarios con el comando PRIVMSG:

PRIVMSG <#channel>|<nick> :<message> 

Cierre con

QUIT :<optional_quit_msg> 

¡Experimenta con Telnet! Comience con

telnet irc.example.com 6667 

Vea el IRC RFC para más comandos y opciones.

Espero que esto ayude!

+2

Gracias, esto es genial! Especialmente el consejo sobre telnet ... Ni siquiera lo pensé :) Gracias ... Podría tener algunas preguntas más ... ¡Déjame probar el telnet y luego volveré! – Jake

+0

Esta es mi sesión: AVISO AUTH: *** conexión Procesamiento de irc.mzima.net AVISO AUTH: *** Mirando hacia arriba su nombre de host ... AVISO AUTH: *** Comprobación Ident AUTH AVISO: * ** Se encuentra su nombre de host AUTH AVISO: *** No hay respuesta Ident NICK PYIRC \ r \ n USUARIO PYIRC PYIRC PYIRC: Python \ r \ n JOIN #pytest \ r \ n : irc.mzima.net 451 * : No se ha registrado Parece que es el registro .. ¿Cómo me registro? ¿O conoces un servidor IRC que no lo requiera? estoy perdido ................ – Jake

+0

No creo que pueda enviar los comandos al mismo tiempo de esa manera. Intente enviarlos por separado, ya que el servidor podría enviarle algo entre los comandos, por lo que recibirá el aviso en el registro, que en realidad se refiere al registro de la conexión. Aparentemente hay un comando PASS que también debes enviar antes de NICK/USER, nunca antes tuve que usar ese comando, así que inténtalo, actualicé mi publicación. – TheMagician

15

he usado esto como el código IRC PRINCIPAL:

import socket 
import sys 

server = "server"  #settings 
channel = "#channel" 
botnick = "botname" 

irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #defines the socket 
print "connecting to:"+server 
irc.connect((server, 6667))               #connects to the server 
irc.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :This is a fun bot!\n") #user authentication 
irc.send("NICK "+ botnick +"\n")       #sets nick 
irc.send("PRIVMSG nickserv :iNOOPE\r\n") #auth 
irc.send("JOIN "+ channel +"\n")  #join the chan 

while 1: #puts it in a loop 
    text=irc.recv(2040) #receive the text 
    print text #print text to console 

    if text.find('PING') != -1:       #check if 'PING' is found 
     irc.send('PONG ' + text.split() [1] + '\r\n') #returnes 'PONG' back to the server (prevents pinging out!) 

A continuación, puede comenzar a configurar comandos como: !hi <nick>

if text.find(':!hi') !=-1: #you can change !hi to whatever you want 
    t = text.split(':!hi') #you can change t and to :) 
    to = t[1].strip() #this code is for getting the first word after !hi 
    irc.send('PRIVMSG '+channel+' :Hello '+str(to)+'! \r\n') 

Tenga en cuenta que todos los irc.send textos deben comenzar con PRIVMSG o NOTICE+channel/user y el texto debería comenzar con :!

+0

Esto es genial, pero solo puedo obtener el ciclo while para desencadenar si irc.recv (2040) devuelve algo. – earthmeLon

+0

Puede establecer irc.setblocking (False) después de irc.connect(), pero asegúrese de agregar un time.sleep() a su ciclo while a menos que desee usar su procesador para calentar su hogar. – earthmeLon

+0

¿De todos modos para enviar el apodo que usó el comando? –

2

Esta es una extensión de MichaelvdNet's Post, que apoya algunas cosas adicionales:

  • Usos envoltorio SSL para el zócalo
  • utiliza la autenticación de contraseña del servidor
  • utiliza la autenticación de contraseña nickserv
  • utiliza sockets no bloqueantes, para permitir que se activen otros eventos
  • Registra los cambios en los archivos de texto en el canal

    #!/usr/local/bin/python 
    
    import socket 
    import ssl 
    import time 
    
    ## Settings 
    ### IRC 
    server = "chat.freenode.net" 
    port = 6697 
    channel = "#meLon" 
    botnick = "meLon-Test" 
    password = "YOURPASSWORD" 
    
    ### Tail 
    tail_files = [ 
        '/tmp/file-to-tail.txt' 
    ] 
    
    irc_C = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #defines the socket 
    irc = ssl.wrap_socket(irc_C) 
    
    print "Establishing connection to [%s]" % (server) 
    # Connect 
    irc.connect((server, port)) 
    irc.setblocking(False) 
    irc.send("PASS %s\n" % (password)) 
    irc.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :meLon-Test\n") 
    irc.send("NICK "+ botnick +"\n") 
    irc.send("PRIVMSG nickserv :identify %s %s\r\n" % (botnick, password)) 
    irc.send("JOIN "+ channel +"\n") 
    
    
    tail_line = [] 
    for i, tail in enumerate(tail_files): 
        tail_line.append('') 
    
    
    while True: 
        time.sleep(2) 
    
        # Tail Files 
        for i, tail in enumerate(tail_files): 
         try: 
          f = open(tail, 'r') 
          line = f.readlines()[-1] 
          f.close() 
          if tail_line[i] != line: 
           tail_line[i] = line 
           irc.send("PRIVMSG %s :%s" % (channel, line)) 
         except Exception as e: 
          print "Error with file %s" % (tail) 
          print e 
    
        try: 
         text=irc.recv(2040) 
         print text 
    
         # Prevent Timeout 
         if text.find('PING') != -1: 
          irc.send('PONG ' + text.split() [1] + '\r\n') 
        except Exception: 
         continue