[Python] Program a bot for IRC

Today I am going to teach you how to program a muzzle for IRC. First of all, for those who do not know, a bot is a program that connects to an IRC channel and interacts with it, which allows us, for example, to moderate the channel without that we are connected and thus avoid spam, or that it recognizes a series of orders and executes the corresponding code.
Although there are already bots ready, I am honestly one of those who like to make their own programs to learn and the great satisfaction it gives us after seeing that it works ^^

With that said, let's move on to the tutorial.

To program the bot we will need a plain text editor any (nano, gedit, medit, etc) and python interpreter (2.6 or 2.7 will be necessary, does not work with python 3.x).

First we import the required modules, in this case we will only need two:

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

import socket
importstring
[/ Code]

Now we proceed to set up the bot:

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

I will explain each variable:

  • HOST: The URL of the server to which we will connect
  • PORT: The server port. By default it is 6667.
  • NICK, IDENT and REALNAME: They correspond to the nickname of the bot, its identification and the real name.
  • CHAN: The channel the bot will enter
  • readbuffer: In this variable the data sent by the server will be saved.

Once our bot is configured we proceed to the connection

[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]

The first line does not have much mystery, the second creates the server connection and the last three send the bot's data to the server to proceed with the login.

Once connected we will create a Infinite loop in which we will go receiving and sending data from / to the server:

[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]

Of all the lines written above, I will only comment on the important ones.
With line = line.split (CHAN + ':') what we do is divide what the server sends us when let's get something from the channel.
For example the following line indicates that someone wrote something on the channel:

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

The first is the nickname of the user and his connection data (separated by!), The command (in this case it indicates that he wrote), the channel and finally, after the colon, the message sent. I will not explain many more commands since that does not fall within this tutorial.

The other important lines are the ones are after the if. The server every so often sends the PING command to check if the user is still connected. In that case, the bot sends the PONG command with an ID that PING sent to indicate to the server that it is still connected.

With this we already have the base of the bot. Now I will proceed to explain how to make the bot respond according to what we want to certain commands, whether they are from IRC itself or from users.

Responding to IRC commands:

PING and PRIVMSG are examples of IRC commands. There are many commands, but as I said before, it is something that I will not go into detail about.
For example, we can make the bot say hello to users who connect:

[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: Welcome @% s ^^ \ n"% (CHAN, name))
[/ Code]

First we check if the server sends the command JOIN which indicates that someone connected to the server. Then we extract the nick, we check that the nick is not the IRC url (if not as soon as we run the bot it will greet the url) and finally we send the greeting message.

Bot commands:

Now how do I make my bot respond to my own commands? Let's better look at an example:

[code] if line [1] == '$ version':
s.send («PRIVMSG% s: CalicoBot 0.1.2 (c) 2012 Son Link \ n»% CHAN)
[/ Code]

In this example if someone writes $version the bot will show the message indicating its name, version and author. The complete code of the example is this:

[code] import socket
importstring

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:
printing 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: Welcome @% 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]

I hope you liked this tutorial, and of course, I leave you the link to the code of my bot so that you can see its code in full and you can see better how it works (although I have removed some commands for personal use).

CalicoBot


Leave a Comment

Your email address will not be published. Required fields are marked with *

*

*

  1. Responsible for the data: Miguel Ángel Gatón
  2. Purpose of the data: Control SPAM, comment management.
  3. Legitimation: Your consent
  4. Communication of the data: The data will not be communicated to third parties except by legal obligation.
  5. Data storage: Database hosted by Occentus Networks (EU)
  6. Rights: At any time you can limit, recover and delete your information.

  1.   auroszx said

    Heh, I could not miss the Bot of the bullshit you ride on IRC 😛 Very interesting article.

  2.   Caesar Salad said

    Very simple and clear explanation.
    What if, the python code is missing all the indentation.

  3.   rafa said

    Excellent article and how easy it is to connect to an IRC to program a bot:)…

    It reminds me of those times when we felt like programmers writing scripts for mIRC in MSN or MSNGroups chats

  4.   truko22 said

    Interesting I keep it 😀

  5.   Genesis Vargas J. (@elprincipiodeto) said

    excellent!

  6.   elynx said

    Very useful, thanks Son_Link!

    Regards!

  7.   dbillyx said

    regards…

    following your lines and testing the only thing that works is
    import socket
    importstring

    HOST = »localhost»
    PORT = 6667
    NICK = »CalicoBot»
    IDENT = »CalicoBot»
    REALNAME = »CalicoBot»
    CHAN = »# Home»
    readbuffer = »»
    s = socket.socket ()
    s.connect ((HOST, PORT))
    s.send ("NICK% srn"% NICK)
    s.send ("USER% s% s bla:% srn"% (IDENT, HOST, REALNAME))
    s.send ("JOIN:% srn"% CHAN)

    changing the channel and nick now the below throws me error syntax

    I asked other acquaintances and they tell me that that doesn't look like python

    I don't know what I'm doing wrong or why I copy everything and paste it into python and give it enter and it connects to the channel but after 250 seconds the channel removes it because there was no response from pong ...

  8.   pinfry said

    The complete code does not work for me, the last paragraph is what fails and I cannot find the error. If I delete that part, it connects and works perfectly. Tested with Python 2.7.3 on Windows 7.

    PS: In my case I connect to a server with a password and add these lines:
    PASS = »Passdelbot»
    s.send ("PASS% s \ r \ n"% PASS)

  9.   Dolphin said

    Hi Son Link, thank you very much for the article, it is very interesting, I just can't respond to the commands sent. The program doesn't go into the last if and I can't figure out why: "if len (line)> 1:"
    I wait your answer.
    Thank you