Welcome, guest | Sign In | My Account | Store | Cart

You want to connect to an IRC server, join a channel and store private message into a file on your hard disk for future reading. I haven't tried but I think you can execute this code from an hosting always connected to the internet and read the message through a web browser.

Python, 43 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import socket, string

#some user data, change as per your taste
SERVER = '2night.azzurra.org'
PORT = 6667
NICKNAME = 'test_py'
CHANNEL = '#test_py'

#open a socket to handle the connection
IRC = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#open a connection with the server
def irc_conn():
    IRC.connect((SERVER, PORT))

#simple function to send data through the socket
def send_data(command):
    IRC.send(command + '\n')

#join the channel
def join(channel):
    send_data("JOIN %s" % channel)

#send login data (customizable)
def login(nickname, username='user', password = None, realname='Pythonist', hostname='Helena', servername='Server'):
    send_data("USER %s %s %s %s" % (username, hostname, servername, realname))
    send_data("NICK " + nickname)

irc_conn()
login(NICKNAME)
join(CHANNEL)

while (1):
    buffer = IRC.recv(1024)
    msg = string.split(buffer)
    if msg[0] == "PING": #check if server have sent ping command
        send_data("PONG %s" % msg[1]) #answer with pong as per RFC 1459
    if msg [1] == 'PRIVMSG' and msg[2] == NICKNAME:
        filetxt = open('/tmp/msg.txt', 'a+') #open an arbitrary file to store the messages
        nick_name = msg[0][:string.find(msg[0],"!")] #if a private message is sent to you catch it
        message = ' '.join(msg[3:])
        filetxt.write(string.lstrip(nick_name, ':') + ' -> ' + string.lstrip(message, ':') + '\n') #write to the file
        filetxt.flush() #don't wait for next message, write it now!

This recipe show how simple is the use of sockets to handle connection with every Internet protocol, just know the RFC for that protocol. A lot of improvements can be done, for example you can send a confirmation to who wrote you every time you store their message.

The tricky part is this one:

if msg[0] == "PING": send_data("PONG %s" % msg[1])

As per RFC, the server will check if you connection is alive sending you a PING command, if you don't answer with a PONG your connection will die with a timeout error, you have to send back the data contained in msg[1]. If you are curious to see which kind of information the server has sent you can add a simple print statement:

if msg[0] == "PING": sys.stdout.write(msg) send_data("PONG %s" % msg[1])

3 comments

exarkun 19 years, 7 months ago  # | flag

Shorter, more featureful example.

from twisted.internet import reactor, protocol
from twisted.protocols import irc

class LoggingIRCClient(irc.IRCClient):
    logfile = file('/tmp/msg.txt', 'a+')

    nickname = 'logging_bot'

    def signedOn(self):
        self.join('#test_py')

    def privmsg(self, user, channel, message):
        self.logfile.write(user.split('!')[0] + ' -> ' + message + '\n')
        self.logfile.flush()

def main():
    f = protocol.ReconnectingClientFactory()
    f.protocol = LoggingIRCClient
    reactor.connectTCP('irc.freenode.net', 6667, f)
    reactor.run()

if __name__ == '__main__':
    main()
Gian Mario Tagliaretti (author) 19 years, 7 months ago  # | flag

twisted is not part of std python. Thank's for you comment but the great twisted package is not part of the standard distribution, the meaning of this recipe is how to use sockets to connect an IRC server using only std python code.

Anon Anony 7 years, 11 months ago  # | flag

Sorry for asking, but i dont understand how you filter the private messages. and what if i want only to save messages sent in channel?