2010-06-03 9 views
19

Ich brauche Hilfe beim Schreiben eines grundlegenden IRC-Bot, der nur mit einem Kanal verbindet .. kann mir jemand dies erklären? Ich habe es geschafft, es mit dem IRC-Server zu verbinden, aber ich kann einem Kanal nicht beitreten und mich anmelden. Der Code, den ich bis jetzt habe, ist:Wie programmiere ich einen einfachen IRC-Bot in Python?

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

Jede Hilfe würde sehr geschätzt werden.

+3

Warum das Rad neu erfinden? Es gibt viele IRC-Bots, die bereits in Python geschrieben wurden. – jamessan

+34

@jamessan Um natürlich zu lernen :) –

+7

@eric Ich liebe diese Antwort: D –

Antwort

11

Es wäre wahrscheinlich am einfachsten, es auf twisted Umsetzung des IRC-Protokolls zu basieren. Werfen Sie einen Blick auf: http://github.com/brosner/bosnobot für Inspiration.

+2

http://www.habnabit.org/twistedex.html ist ein Tutorial grundlegende IRC-Bot mit tw.wg –

45

zu einem IRC-Kanal zu verbinden, müssen Sie bestimmen IRC-Protokoll spezifische Befehle an den IRC-Server senden, bevor Sie es tun können.

Wenn Sie eine Verbindung zum Server herstellen, müssen Sie warten, bis der Server alle Daten gesendet hat (MOTD und whatnot), dann müssen Sie den Befehl PASS senden.

Was folgt ist der NICK-Befehl.

NICK <username> 

Dann müssen Sie den USER-Befehl senden.

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

Beide sind obligatorisch.

Dann sehen Sie wahrscheinlich die PING-Nachricht vom Server, Sie müssen den Server mit PONG-Befehl jedes Mal antworten, wenn der Server PING-Nachricht an Sie sendet. Der Server fragt möglicherweise auch nach PONG zwischen NICK- und USER-Befehlen.

PING :12345678 

Antworten mit dem exakt gleichen Text nach „PING“ mit dem Befehl PONG:

PONG :12345678 

Was nach PING ist einzigartig für jeden Server, den ich so sicher, glaube Sie mit dem Wert antworten, dass der Server gesendet Sie.

Jetzt können Sie einen Kanal verbinden mit dem Befehl JOIN:

JOIN <#channel> 

Jetzt können Sie Nachrichten an Kanälen und Benutzern mit PRIVMSG Befehl senden:

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

Quit mit

QUIT :<optional_quit_msg> 

Experimentieren Sie mit Telnet! Beginnen Sie mit

telnet irc.example.com 6667 

die IRC RFC für weitere Befehle und Optionen auswählen.

Hoffe, das hilft!

+2

Danke, das ist toll! Vor allem der Tipp über Telnet .. Hab noch nicht mal dran gedacht :) Danke .. ich könnte noch ein paar Fragen haben .. Lass mich das telnet Ding ausprobieren dann werde ich zurückkommen! – Jake

+0

Das ist meine Sitzung: HINWEIS AUTH: *** Verarbeitung Verbindung irc.mzima.net HINWEIS AUTH: *** Suchen Sie Ihren Hostnamen ... HINWEIS AUTH: *** Ident prüfen HINWEIS AUTH: * ** gefunden Ihren Hostnamen HINWEIS AUTH: *** Keine Ident Antwort NICK PYIRC \ r \ n USER PYIRC PYIRC PYIRC: Python \ r \ n JOIN #pytest \ r \ n : irc.mzima.net 451 * : Sie haben nicht registriert Es scheint die Registrierung zu sein .. Wie registriere ich? Oder kennst du einen IRC-Server, der das nicht benötigt? Ich bin verloren ................ – Jake

+0

Ich glaube nicht, dass Sie die Befehle gleichzeitig so senden können. Versuchen Sie, sie getrennt zu senden, da der Server Ihnen möglicherweise etwas zwischen den Befehlen sendet, so erhalten Sie die Benachrichtigung bei der Registrierung, die sich eigentlich auf die Verbindungsregistrierung bezieht. Anscheinend gibt es einen PASS -Befehl, den Sie auch vor NICK/USER senden müssen. Ich musste diesen Befehl nie zuvor selbst verwenden, also versuchen Sie es, ich habe meinen Beitrag aktualisiert. – TheMagician

15

ich dies als Haupt IRC-Code verwendet:

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

Dann können Sie einstellen Befehle wie Start: !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') 

Beachten Sie, dass alle irc.send Texte mit PRIVMSG oder NOTICEbeginnen müssen +channel/user und der Text sollte mit einem : beginnen! Diese

+0

Das ist großartig, aber ich kann nur die while-Schleife auslösen, wenn irc.recv (2040) etwas zurückgibt. – earthmeLon

+0

Sie können irc.setblocking (False) nach irc.connect() einstellen, aber stellen Sie sicher, dass Sie Ihrer while-Schleife ein time.sleep() hinzufügen, es sei denn, Sie möchten Ihren Prozessor verwenden, um Ihr Zuhause zu erwärmen. – earthmeLon

+0

Wie auch immer, um den Nicknamen mitzuteilen, der den Befehl verwendet hat? –

2

ist eine Erweiterung von MichaelvdNet's Post, die ein paar zusätzliche Dinge unterstützt:

  • Verwendet SSL-Wrapper für die Socket-
  • Verwendet Server Passwort-Authentifizierung
  • Verwendet nickserv Passwort-Authentifizierung
  • Verwendet nonblocking Steckdosen, Damit andere Ereignisse ausgelöst werden können
  • Protokolliert Änderungen an Textdateien auf Kanal

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