19 listopada 2009
Bot SMS pod Linuksem
Ostatnio w firmie pojawił się temat stworzenia SMS bota. Zacząłem więc szukać rozwiązań. Jeden z pomysłów, to postawienienie komputera z Linuksem na pokładzie, podłączenie do niego telefonu z ofertą, w której jest miliard darmowych SMS-ów i uruchomienie czegoś magicznego, co zajmie się odbieraniem i wysyłaniem wiadomości. I to magiczne coś właśnie zamierzam opisać.
Rozwiązanie które można zastosować, okazało się prostsze niż myślałem. Można użyć do tego świetnego programu, który jest dostępny zarówno pod Linuksem jak i Windowsem - mowa o Gammu. Jest to program, który komunikuje się z telefonem, lub modemem i służy do różnego rodzaju cznności, takich jak odbieranie/wysyłanie SMS-ów, zarządzanie kontaktami, zadaniami, kalenarzem itp. Ja oczywiście skupię się na odbieraniu i wysyłaniu SMS-ów.
Tak więc do komunikacji użytkownika z botem posłużę się Gammu - to już ustaliliśmy. Żeby było ciekawiej, Gammu posiada demona do wysyłania i odbierania SMS-ów - gammu-smsd. Jako backend do przechowywania danych można użyć zwykłych plików lub bazy danych (obsługiwany jest MySQL, PostgreSQL i SQLite). Pliki odradzam, bo to nieco ogranicza funkcjonalność - przykładowo nie jest możliwe wysyłanie wiadomości przy użyciu polecenia gammu-smsd-inject lub nie można przekazać żadnego id wiadomości do skryptu, który można uruchomić po otrzymaniu wiadomości (o tym w dalszej części). Lepiej zatem skorzystać z bazy danych. Ja wybrałem PostgreSQL.
Konfiguracja Gammu oraz SMSD
Najpierw trzeba zacząć od komunikacji Gammu z telefonem. Mój telefon to Sony Ericsson k800i. Pomijam fakt, że trzeba podłączyć telefon do komputera przez kabel USB ;) Poniżej zamieszczam źródła plików konfiguracyjnych:
~/.gammurc
[gammu] port = /dev/ttyACM0 model = connection = at19200 synchronizetime = no logfile = logformat = errorsdate use_locking = gammuloc =
/etc/gammu_smsdrc
[gammu] port = /dev/ttyACM0 model = connection = at19200 synchronizetime = no logfile = logformat = errorsdate use_locking = gammuloc = [smsd] Service = pgsql LogFile = syslog DebugLevel = 255 DeliveryReport = log RunOnReceive = /home/jaro/bin/sms_trigger.py User = uzytkownik_bazy Password = haslo_bazy PC = localhost Database = gammu
Poprawność konfiguracji połączenia z telefonem można sprawdzić przez polecenie gammu identify. U mnie wyjście wyglądało tak:
# gammu identify Manufacturer : Sony Ericsson Model : K800i (AAD-3022031-BV) Firmware : R8BF003 080130 2133 CXC1250212_ORANGE_WI IMEI : WOLE_NIE_POKAZYWAĆ Kod produktu : AAD-3022031-BV SIM IMSI : WOLE_NIE_POKAZYWAĆ
Przed uruchomieniem demona smsd, trzeba utworzyć odpowiednie tabele w bazie danych. W dokumentacji znajduje się przykładowy plik ze skryptem SQL, który tworzy te tabele. U mnie znajduje się on w lokalizacji: /usr/share/doc/gammu/examples/sql/pgsql.sql Wystarczy uruchomić skrypt i voila!
Skrypt (bot)
W pliku gammu_smsdrc jest opcja RunOnReceive, która, jak się można domyślić, wskazuje skrypt uruchamiany po odebraniu wiadomości. Skrypt jest uruchamiany z parametrem, który zawiera id wiersza w bazie danych w tabeli inbox. Wiersz zawiera dane przesłanej wiadomości. Napisałem w Pythonie przykładowy skrypt, który odczytuje odebraną wiadomość, sprawdza jaki tekst wysłano i na jego podstawie wysyła odpowiedź.
#!/usr/bin/python
import psycopg2 as db, sys, os
db_user = 'nazwa_uzytkownika'
db_password = 'haslo_do_bazy'
db_host = 'localhost'
db_name = 'gammu'
def main(argv=None):
try:
sms_id = sys.argv[1]
except IndexError:
print 'Za malo parametrow'
sys.exit()
try:
conn = db.connect("dbname=%s user=%s password=%s host=%s" % (db_name, db_user, db_password, db_host))
except:
print 'Blad podczas polaczenia z baza'
if not sms_id.isdigit():
print 'Niepoprawny parametr'
sys.exit()
cur = conn.cursor()
cur.execute("SELECT * FROM inbox WHERE id=%s" % sms_id)
row = cur.fetchone()
if not row:
print 'Nie znaleziono wiadomosci sms o podanym id'
sys.exit()
rcp_num = row[3]
command = row[8].strip().lower()
if command == 'jezyk':
response = "Python"
elif command == 'system':
response = "Linux"
else:
response = "Nieznana komenda"
os.system("gammu-smsd-inject TEXT %s -text '%s'" % (rcp_num, response))
if __name__ == '__main__':
main()
Finał - uruchomienie demona
Wreszcie przechodzimy do puenty - uruchomienia demona. Wystarczy krótkie:
gammu-smsd --daemon
I w ten oto sposób, telefon jest gotowy do odbierania i wysyłania wiadomości.
7 komentarzy



