xbotlib/xbotlib.py

114 lines
3.1 KiB
Python
Raw Normal View History

2021-01-10 13:10:39 +00:00
"""XMPP bots for humans."""
from configparser import ConfigParser
from getpass import getpass
from os.path import exists
from pathlib import Path
from slixmpp import ClientXMPP
2021-01-10 13:49:22 +00:00
class EasyMessage:
"""A simple message interface."""
def __init__(self, message):
self.message = message
@property
def body(self):
return self.message["body"]
@property
def sender(self):
return self.message["from"]
@property
def receiver(self):
return self.message["to"]
2021-01-10 13:10:39 +00:00
class Bot(ClientXMPP):
CONFIG_FILE = "bot.conf"
def __init__(self):
self.read_config()
self.init_bot()
self.register_xmpp_event_handlers()
self.register_xmpp_plugins()
self.run()
def read_config(self):
"""Read configuration for running bot."""
config_file_path = Path(self.CONFIG_FILE).absolute()
if not exists(config_file_path):
self.generate_config()
self.config = ConfigParser()
self.config.read(config_file_path)
def generate_config(self):
"""Generate bot configuration."""
2021-01-10 14:45:12 +00:00
jid = input("XMPP address (e.g. foo@bar.com): ") or "foo@bar.com"
2021-01-10 13:10:39 +00:00
password = (
2021-01-10 14:45:12 +00:00
getpass("Password (e.g. my-cool-password): ") or "my-cool-password"
2021-01-10 13:10:39 +00:00
)
2021-01-10 14:45:12 +00:00
room = input("XMPP room (e.g. foo@bar.com): ")
nick = input("Nickname (e.g. lurkbot): ")
2021-01-10 13:10:39 +00:00
config = ConfigParser()
config["bot"] = {"jid": jid, "password": password}
2021-01-10 14:45:12 +00:00
if room:
config["bot"]["room"] = room
if nick:
config["bot"]["nick"] = nick
2021-01-10 13:10:39 +00:00
with open("bot.conf", "w") as file_handle:
config.write(file_handle)
def init_bot(self):
"""Initialise bot with connection details."""
jid = self.config["bot"]["jid"]
passwd = self.config["bot"]["password"]
ClientXMPP.__init__(self, jid, passwd)
def register_xmpp_event_handlers(self):
"""Register functions against specific XMPP event handlers."""
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message)
self.add_event_handler("groupchat_message", self.groupchat_message)
def message(self, message):
"""Handle message event."""
if message["type"] in ("chat", "normal"):
2021-01-10 13:49:22 +00:00
self.react(EasyMessage(message))
2021-01-10 13:10:39 +00:00
def session_start(self, event):
"""Handle session_start event."""
self.send_presence()
self.get_roster()
def groupchat_message(self, message):
"""Handle groupchat_message event."""
pass
def register_xmpp_plugins(self):
"""Register XMPP plugins that the bot supports."""
self.register_plugin("xep_0030") # Service Discovery
self.register_plugin("xep_0045") # Multi-User Chat
self.register_plugin("xep_0199") # XMPP Ping
def run(self):
"""Run the bot."""
self.connect()
2021-01-10 14:37:10 +00:00
try:
self.process()
except KeyboardInterrupt:
pass
2021-01-10 13:49:22 +00:00
def reply(self, to, body, type="chat"):
"""Send a message."""
self.send_message(mto=to, mbody=body, mtype=type)