Bot Jabbera na przykładzie xmpppy
Jak obiecałem, pomimo dzisiejszych problemów, opiszę krótko jak zrobić własnego prostego bota Jabbera (z transportami włącznie) z pomocą modułu xmpppy.
W dowolnym kliencie sieci Jabber tworzymy konto, dodajemy transporty itd.
Zakładam, że moduł xmpp już jest wgrany do pythona.
Otwieramy nasz ulubiony edytor
Pierwsze linie:
#!/usr/bin/python # -*- coding: iso-8859-2 -*-
Dlaczego tak? Otóż jak wiadomo, żyjemy w Polsce i przydało by się aby móc pisać po polsku. Ten fragment jest niezbędny jeśli chcemy w naszym kodzie używać polskich znaków.
import xmpp import re import codecs
Moduł xmpp wiadomo po co, moduł re służy do pracy z tekstem i jego obrabiania (tak w dużym uproszczeniu)
user_jabbera='user@serwer.jabbera.pl' pass_jabbera='haslo' gg_serwer='adres.transportu.gg' kodow='iso-8859-2'
Zmienna kodow przyda nam się, ponieważ chcemy móc komunikować się po polsku. Bez użycia i ustawienia kodowania moglibyśmy coprawda komunikować się używając znaków polskich, ale np przy zapisie do bazy danych byłby problem (UnicodeDecodeError lub UnicodeEncodeError)
- Następnie:
def GoOn(conn): while StepOn(conn): pass def StepOn(conn): try: conn.Process(1) except KeyboardInterrupt: return 0 return 1 jid=xmpp.JID(user_jabbera) user,server,password=jid.getNode(),jid.getDomain(),pass_jabbera conn=xmpp.Client(server,debug=['socket']) conres=conn.connect() if not conres: print "Nie udało się podłączyć do serwera %s!"%server sys.exit(1) if conres<>'tls': print "UWAGA: Nie udało się ustabilizować szyfrowanego połączenia z serwerem." authres=conn.auth(user,password) if not authres: print "Nie udało się zalogować %s - sprawdź login/hasło."%server sys.exit(1) if authres<>'sasl': print "UWAGA: Nie udało sie uwieżytelnic z SASL %s. STARA wersja autoryzacji użyta.!"%server conn.RegisterHandler('message',messageCB) conn.sendInitPresence() conn.sendPresence(jid=gg_serwer, typ=None, requestRoster=1) print "Bot uruchomiony" GoOn(conn)
Funkcje GoOn i StepOn pozwalają nam utrzymać połączenie. conn.sendPresence(jid=gg_serwer, typ=None, requestRoster=1) sprawia, że jesteśmy podłączeni do transportu GG, jak łatwo się domyślić, pozostałe transporty analogicznie. Cała reszta to ‘kosmetyczne’ zabiegi. except KeyboardInterrupt: zdefiniowanie tego wyjątku spowoduje, iż po wciśnięciu CTRL+C nasz bot prawidłowo się wyłączy.
- Następnie:
def messageCB(conn,mess): sender=mess.getFrom().__str__() sender=re.split('/',str(sender)) uin=sender[0] pis=mess.getBody() if pis: text=mess.getBody() try: text=text.encode(kodow) except (UnicodeDecodeError, UnicodeEncodeError): reply="Prosimy używać POLSKIEJ pisowni oraz znaków kodowania iso-8859-2" conn.send(xmpp.Message(uin,reply.decode(kodow))) return 1 if text=='Witam': reply='Witaj' elif text=="Cześć": reply="Cześć\r\nco u Ciebie?" else: reply="Costam" conn.send(xmpp.Message(uin,reply.decode(kodow))) return 1
Funkcja messageCB jest NIEZBĘDNA i dzięki niej nasz bot komunikuje się z nami.
sender=mess.getFrom().__str__() sender=re.split('/',str(sender)) uin=sender[0]
Linie te pobierają nam informacje o nadawcy wiadomości przychodzącej do nas. Potrzebne jeśli chcemy odpowiedzieć.
pis=mess.getBody() if pis:
Służą do tego aby bot nie odpowiadał “nie pytany” (jabber powiadamia o tym iż nasz rozmówca pisze wiadomość, patrzy na okienko, powoduje to wysyłanie do nas informacji które mogą być mylnie interpretowane jako wiadomość.)
try: text=text.encode(kodow) except (UnicodeDecodeError, UnicodeEncodeError): reply="Prosimy używać POLSKIEJ pisowni oraz znaków kodowania iso-8859-2" conn.send(xmpp.Message(uin,reply.decode(kodow))) return 1
Ponieważ przez jabbera można wysyłać znaki niestandardowe, aby uniknąć problemów związanych z kodowaniem, warto ustawić możliwość nadawania tylko w “polskich” znakach.
conn.send(xmpp.Message(uin,reply.decode(kodow)))
Linie z instrukcjami pominąłem. Linia powyższa odpowiada za wysłanie wiadomości do nadawcy. Warto zwrócić uwagę na decode(kodow) - instrukcja ta powoduje że wysyłane informacje są w kodowaniu iso-8859-2 (takie kodowanie przypisane jest pod zmienną kodow na początku pliku.
- Cały plik przedstawia się następująco:
#!/usr/bin/python # -*- coding: iso-8859-2 -*- import xmpp import urllib import re import codecs user_jabbera='user@serwer.jabbera.pl' pass_jabbera='haslo' gg_serwer='adres.transportu.gg' kodow='iso-8859-2' def messageCB(conn,mess): sender=mess.getFrom().__str__() sender=re.split('/',str(sender)) uin=sender[0] pis=mess.getBody() if pis: text=mess.getBody() try: text=text.encode(kodow) except (UnicodeDecodeError, UnicodeEncodeError): reply="Prosimy używać POLSKIEJ pisowni oraz znaków kodowania iso-8859-2" conn.send(xmpp.Message(uin,reply.decode(kodow))) return 1 if text=='Witam': reply='Witaj' elif text=="Cześć": reply="Cześć\r\nco u Ciebie?" else: reply="Costam" conn.send(xmpp.Message(uin,reply.decode(kodow))) return 1 def GoOn(conn): while StepOn(conn): pass def StepOn(conn): try: conn.Process(1) except KeyboardInterrupt: return 0 return 1 jid=xmpp.JID(user_jabbera) user,server,password=jid.getNode(),jid.getDomain(),pass_jabbera conn=xmpp.Client(server,debug=['socket']) conres=conn.connect() if not conres: print "Nie udało się podłączyć do serwera %s!"%server sys.exit(1) if conres<>‘tls’: print “UWAGA: Nie udało się ustabilizować szyfrowanego połączenia z serwerem.” authres=conn.auth(user,password) if not authres: print “Nie udało się zalogować %s - sprawdź login/hasło.”%server sys.exit(1) if authres<>’sasl’: print “UWAGA: Nie udało sie uwieżytelnic z SASL %s. STARA wersja autoryzacji użyta.!”%server conn.RegisterHandler(’message’,messageCB) conn.sendInitPresence() conn.sendPresence(jid=gg_serwer, typ=None, requestRoster=1) print “Bot uruchomiony” GoOn(conn)
Jeśli ktoś potrzebuje jakiś szerszych informacji to proszę pisać do mnie