2010-06-03 96 views
19

我需要帮助写一个基本的IRC机器人只是连接到一个频道..是否有人能够解释我呢?我设法让它连接到IRC服务器,但我无法加入频道并登录。我到目前为止的代码是:如何在python中编写简单的IRC bot?

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

任何帮助将不胜感激。

+3

为什么要重新发明轮子?已经有很多用Python编写的IRC机器人。 – jamessan 2010-06-03 18:13:32

+34

@jamessan当然要学习:) – 2010-06-03 19:53:33

+7

@eric我喜欢这个回应:D – 2013-12-11 13:26:21

回答

11

它可能是最容易的基础上扭曲的实施IRC协议。看看:http://github.com/brosner/bosnobot获取灵感。

+2

http://www.habnabit.org/twistedex.html是一个教程基本的IRC机器人使用t.w.p – 2010-06-03 18:59:44

45

要连接到IRC频道,你必须把某些IRC协议的具体命令到IRC服务器,然后才能做到这一点。

当您连接到服务器时,您必须等到服务器发送了所有数据(MOTD和什么),然后您必须发送PASS命令。

PASS <some_secret_password> 

以下是NICK命令。

NICK <username> 

然后您必须发送USER命令。

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

两者都是强制性的。

然后你很可能会看到来自服务器的PING消息,每次服务器向你发送PING消息时,你都必须用PONG命令回复服务器。服务器可能会在NICK和USER命令之间要求PONG。

PING :12345678 

回复完全相同的文字“PING”与PONG命令后:

PONG :12345678 

PING后什么是独一无二的每一个服务器我相信,所以一定要确保你的服务器发送的值回复您。

现在,您可以加入与JOIN命令道:

JOIN <#channel> 

现在你可以发送邮件到渠道和用户PRIVMSG命令:

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

退出与

QUIT :<optional_quit_msg> 

用Telnet进行实验!从

telnet irc.example.com 6667 

有关更多命令和选项,请参阅IRC RFC

希望这会有所帮助!

+2

谢谢,这是伟大的!尤其是关于telnet的提示..没有想到它:)谢谢..我可能还有几个问题。让我试试telnet的东西,然后我会回来! – Jake 2010-06-03 21:20:33

+0

这是我的会议: 注意AUTH:***处理连接irc.mzima.net 注意AUTH:***看你的主机名... 注意AUTH:***检查订货号 注意AUTH:* **找到你的主机名 注意AUTH:***没有身份确认 NICK PYIRC \ r \ n USER PYIRC PYIRC PYIRC:Python的\ r \ n JOIN #pytest \ r \ n :irc.mzima.net 451 * :您还没有注册 它似乎是注册..我如何注册?或者你知道一个不需要的IRC服务器吗? 我迷路了................ – Jake 2010-06-03 22:35:26

+0

我不认为你可以像这样同时发送命令。尝试单独发送它们,因为服务器可能会在命令之间向您发送一些内容,因此您会收到注册通知,这实际上是指连接注册。显然,你必须在NICK/USER之前发送一个PASS 命令,我以前从来没有必须使用这个命令,所以试试看,我更新了我的帖子。 – TheMagician 2010-06-04 04:50:19

15

我用这个作为主要的IRC代码:

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

然后,你就可以开始设置像命令:!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') 

注意,所有irc.send文本必须与PRIVMSGNOTICE启动+channel/user和文本应该以:开头!

+0

这很好,但我只能得到while循环来触发,如果irc.recv(2040)返回的东西。 – earthmeLon 2014-05-12 17:46:02

+0

您可以在irc.connect()之后设置irc.setblocking(False),但一定要在while循环中添加time.sleep(),除非您想使用处理器来加热家中。 – earthmeLon 2014-05-12 18:07:44

+0

无论如何消息使用命令的昵称? – 2015-05-24 03:03:56

2

这是MichaelvdNet's Post的延伸,它支持一些额外的东西:

  • 使用SSL包装器插座
  • 用途服务器的密码验证
  • 用途nickserv密码验证
  • 使用非阻塞插座,允许其他事件触发
  • 将文本文件更改为通道

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