How do i program a simple IRC bot in python?

2019-03-07 23:01发布

问题:

I need help writing a basic IRC bot that just connects to a channel.. is anyone able to explain me this? I have managed to get it to connect to the IRC server but i am unable to join a channel and log on. The code i have thus far is:

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

Any help would be greatly appreciated.

回答1:

It'd probably be easiest to base it on twisted's implementation of the IRC protocol. Take a look at : http://github.com/brosner/bosnobot for inspiration.



回答2:

To connect to an IRC channel, you must send certain IRC protocol specific commands to the IRC server before you can do it.

When you connect to the server you must wait until the server has sent all data (MOTD and whatnot), then you must send the PASS command.

PASS <some_secret_password>

What follows is the NICK command.

NICK <username>

Then you must send the USER command.

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

Both are mandatory.

Then you're likely to see the PING message from server, you must reply to the server with PONG command every time the server sends PING message to you. The server might ask for PONG between NICK and USER commands too.

PING :12345678

Reply with the exact same text after "PING" with PONG command:

PONG :12345678

What's after PING is unique to every server I believe so make sure you reply with the value that the server sent you.

Now you can join a channel with JOIN command:

JOIN <#channel>

Now you can send messages to channels and users with PRIVMSG command:

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

Quit with

QUIT :<optional_quit_msg>

Experiment with Telnet! Start with

telnet irc.example.com 6667

See the IRC RFC for more commands and options.

Hope this helps!



回答3:

I used this as the MAIN IRC code:

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!)

Then, you can start setting commands like: !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')

Note that all irc.send texts must start with PRIVMSG or NOTICE + channel/user and the text should start with a : !



回答4:

This is an extension of MichaelvdNet's Post, which supports a few additional things:

  • Uses SSL wrapper for socket
  • Uses server password authentication
  • Uses nickserv password authentication
  • Uses nonblocking sockets, to allow other events to trigger
  • Logs changes to text files to channel

    #!/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
    


回答5:

That will open a socket, but you also need to tell the IRCd who you are. I've done something similar in perl ages ago, and I found the IRC RFCs to be very helpful.

Main RFC: http://irchelp.org/irchelp/rfc/rfc.html

Other RFCs: http://irchelp.org/irchelp/rfc/index.html