Internet Technologies & News

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.

  1. W dowolnym kliencie sieci Jabber tworzymy konto, dodajemy transporty itd.

  2. Zakładam, że moduł xmpp już jest wgrany do pythona.

  3. Otwieramy nasz ulubiony edytor

  4. 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)

  1. 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.

  1. 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.

  1. 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

Napisz komentarz

Musisz być zalogowany aby napisać komentarz.