[Python] Programar un bot para IRC

En el día de hoy os voy a enseñar a programar un bot para IRC. Antes de nada, para los que no lo sepan, un bot es un programa que se conecta a un canal de IRC e interactuar con el, lo que nos permite, por ejemplo, moderar el canal sin que nosotros estemos conectados y así evitar el spam, o que reconozca una serie de ordenes y ejecute el código correspondiente.
Si bien ya existen bots listos, sinceramente soy de a los que les gustan hacer sus propios programas por aprender y la gran satisfacción que nos da tras ver que funciona ^^

Dicho esto, pasemos al tutorial.

Para programar el bot necesitaremos un editor de texto plano cualquiera (nano, gedit, medit, etc) y el interprete de Python (sera necesario el 2.6 o 2.7, no funciona con python 3.x).

Primero importamos los módulos necesarios, en este caso solamente necesitaremos de dos:

[code] #!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import string
[/code]

Ahora procedemos a configurar el bot:

[code] HOST=”irc.desdelinux.net”
PORT=6667
NICK=”CalicoBot”
IDENT=”CalicoBot”
REALNAME=”CalicoBot”
CHAN=”#Home”
readbuffer=””
[/code]

Paso a explicar cada variable:

  • HOST: La URL del servidor al que nos conectaremos
  • PORT: El puerto del servidor. Por defecto es el 6667.
  • NICK, IDENT y REALNAME: Corresponden al nick del bot, su identificación y el nombre real.
  • CHAN: El canal al que entrara el bot
  • readbuffer: En esta variable se ira guardando los datos enviados por el servidor.

Una vez configurado nuestro bot procedemos a la conexión

[code] s=socket.socket( )
s.connect((HOST, PORT))
s.send(“NICK %s\r\n” % NICK)
s.send(“USER %s %s bla :%s\r\n” % (IDENT, HOST, REALNAME))
s.send(“JOIN :%s\r\n” % CHAN)
[/code]

La primera linea no tiene mucho misterio, la segunda crea la conexión con el servidor y las tres ultimas envían al servidor los datos del bot para proceder al inicio de sesión.

Una vez conectados crearemos un bucle infinito en el cual iremos recibiendo y enviando los datos del/al servidor:

[code] while 1:
readbuffer=readbuffer+s.recv(1024)
temp=string.split(readbuffer, “\n”)
readbuffer=temp.pop( )
for line in temp:
line=string.rstrip(line)
line=line.split(CHAN + ‘ :’)

if line[0].find(“PING”) != -1:
pingid = line[0].split()[1] s.send(“PONG %s\r\n” % pingid)
[/code]

De todas las lineas arriba escritas solo comentare las importantes.
Con line=line.split(CHAN + ‘ :’) lo que hacemos es dividir lo que nos enviá el servidor cuando recibamos algo desde el canal.
Por ejemplo la siguiente linea indica que alguien escribió algo en el canal:

:son_link!sonlink@127.0.0.1 PRIVMSG #Home :Hola ^^

Lo primero es el nick del usuario y datos de su conexión (separados por ! ), el comando (en este caso indica que escribió), el canal y por ultimo, tras los dos puntos el mensaje enviado. No explicare muchos mas comandos ya que eso no entra dentro de este tutorial.

Las otras lineas importantes son las que están tras el if. El servidor cada cierto tiempo envia el comando PING para comprobar si el usuario aun esta conectado. En ese caso el bot enviá el comando PONG con una ID que le mando PING para indicar al servidor que sigue conectado.

Con esto ya tenemos la base del bot. Ahora procederé a explicar como hacer que el bot responda según queramos a ciertos comandos, sean del propio IRC o de los usuarios.

Respondiendo a comandos de IRC:

PING y PRIVMSG son ejemplos de comandos de IRC. Hay muchos comando, pero como dije anteriormente, es algo de lo que no entrare en detalle.
Por ejemplo, podemos hacer que el bot salude a los usuarios que se conecten:

[code] if line[0].find(‘JOIN’) != -1:
name = line[0].split(‘!’)[0].split(‘:’)[1] if name != NICK and name.find(HOST) == -1:
s.send(“PRIVMSG %s :Bienvenid@ %s ^^\n” % (CHAN, name))
[/code]

Primero comprobamos si el servidor envia el comando JOIN que indica que se conecto alguien al servidor. Luego extraemos el nick, comprobamos que el nick no sea la url del IRC (si no en cuanto ejecutemos el bot saludara a la url) y por ultimo enviamos el mensaje de saludo.

Comandos del bot:

Ahora ¿como hago que mi bot responda a mis propios comandos? Mejor miremos un ejemplo:

[code] if line[1] == ‘$ version’:
s.send(“PRIVMSG %s :CalicoBot 0.1.2 (c) 2012 Son Link\n” % CHAN)
[/code]

En este ejemplo si alguien escribe $ version el bot mostrara el mensaje indicando su nombre, versión y autor. El código completo del ejemplo es este:

[code] import socket
import string

HOST=”localhost”
PORT=6667
NICK=”CalicoBot”
IDENT=”CalicoBot”
REALNAME=”CalicoBot”
CHAN=”#Home”
readbuffer=””
s=socket.socket( )
s.connect((HOST, PORT))
s.send(“NICK %s\r\n” % NICK)
s.send(“USER %s %s bla :%s\r\n” % (IDENT, HOST, REALNAME))
s.send(“JOIN :%s\r\n” % CHAN)

while 1:

readbuffer=readbuffer+s.recv(1024)
temp=string.split(readbuffer, “\n”)
readbuffer=temp.pop( )
for line in temp:
print line
line=string.rstrip(line)
line=line.split(CHAN + ‘ :’)

if line[0].find(“PING”) != -1:
pingid = line[0].split()[1] s.send(“PONG %s\r\n” % pingid)

if line[0].find(‘JOIN’) != -1:
name = line[0].split(‘!’)[0].split(‘:’)[1] if name != NICK and name.find(HOST) == -1:
s.send(“PRIVMSG %s :Bienvenid@ %s ^^\n” % (CHAN, name))

if len(line) < 1:
if line[1] == ‘$ version’:
s.send(“PRIVMSG %s :CalicoBot 0.1.2 (c) 2012 Son Link\n” % CHAN)
[/code]

Espero que este tutorial os halla gustado, y como no, os dejo el enlace al código de mi bot para que veáis su código al completo y podáis ver mejor como trabaja (si bien he quitado algunos comandos de uso personal).

CalicoBot


12 comentarios

  1.   AurosZx dijo

    Je, no podía faltar el Bot de las chorradas que montas en el IRC 😛 Muy interesante el artículo.

  2.   Cesar dijo

    Muy simple y clara la expicación.
    Lo que si, al código python le falta toda la indentación.

  3.   rafa dijo

    Excelente articulo y lo facil que es conectarse a un IRC para programar un bot :)…

    Me recuerda aquellos tiempos en los que nos sentiamos programadores al escribir scripts para mIRC en los chats de MSN o MSNGroups

  4.   truko22 dijo

    Interesante me lo guardo 😀

  5.   Elynx dijo

    Muy util, gracias Son_Link!

    Saludos!

  6.   dbillyx dijo

    saludos…

    siguiendo tus lineas y probando lo unico que funciona es
    import socket
    import string

    HOST=”localhost”
    PORT=6667
    NICK=”CalicoBot”
    IDENT=”CalicoBot”
    REALNAME=”CalicoBot”
    CHAN=”#Home”
    readbuffer=””
    s=socket.socket( )
    s.connect((HOST, PORT))
    s.send(“NICK %s\r\n” % NICK)
    s.send(“USER %s %s bla :%s\r\n” % (IDENT, HOST, REALNAME))
    s.send(“JOIN :%s\r\n” % CHAN)

    cambiando el canal y el nick ahora lo de abajo me tira sintaxis de error

    le pregunte a otros conocidos y me dicen que eso no parece python

    no se que andare haciendo mal o que porque copio todo y lo pego en python y le doy enter y se conecta al canal pero luego de 250 segundos el canal lo saca por que no hubo respuesta de pong…

  7.   pinfry dijo

    No me funciona el código completo, el ultimo parágrafo es lo que falla y no consigo encontrar el error. Si esa parte la borro se conecta y funciona perfectamente. Probado con Python 2.7.3 en Windows 7.

    PD: En mi caso me conecto a un servidor con contraseña y añado estas lineas:
    PASS=”Passdelbot”
    s.send(“PASS %s\r\n” % PASS)

  8.   DoLpHiN dijo

    Hola Son Link, muchas gracias por el artículo, está muy interesante, sólo que no consigo responder a los comandos enviados. El programa no entra en el último if y no consigo averiguar el por qué: “if len(line) > 1:”
    Espero tu respuesta.
    Gracias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.