The Xtensible XMPP Chat Bot¶
XChatBot is a xmpp bot library written in python using the
nbxmpp library from Gajim
git clone https://git.sr.ht/~fabrixxm/xchatbot
then install required packages:
pipenv --site-packages --python 3 pipenv install
on osx you need first to install python3 with brew:
brew install python3 pipenv pygobject3
pacman -S python-gobject python-nbxmpp
apt install python3-gi python3-nbxmpp
The script loads a configuration file called after the bot class name.
For a bot class
EchoBot the script will look for
/etc/echobot.rc in this order, and will load the first it
An example config file is provided as echobot.rc.dist, with comments.
xchatbot.XChatBot class and implement your commands as
method of your class.
A bot class can have public commands and private commands. Is it also possibile to define a default to handle unknown commands.
The bot is started calling the classmethod
The bot will react to specific commands with optionals arguments.
Commands are method of the class named
Each command method must get a
and optionally a number of args.
A docstring should be provided that is used by
help command to build the
If the numbers of args given in the message doesn’t match the function signature, an error message is returned.
By convention, command arguments are listed before description in method docstring
Here an example:
from xchatbot import XChatBot # My custom bot class MyEchoBot(XChatBot): # 'hello' command. Takes no arguments def cmd_hello(self, peer): """Say hello to the bot""" peer.send("Hello to you!") # 'sum' command. Takes exactly two arguments def cmd_sum(self, peer, a, b): """<a number> <another number> - Sum two numbers""" peer.send(str(int(a) + int(b))) # 'echo' command. Takes a variable number of arguments def cmd_echo(self, peer, *args): """Echo back what you typed""" msg = "You said: " + " ".join(args) peer.send(msg) if __name__ == "__main__": MyEchoBot.start()
To test this, create a
myechobot.rc config file and run the bot:
$ python myechobot.py
A command can be marked as private using the
A private command is listed in help and is executed only if the message comes from the admin JID set in config file
from xchatbot import XChatBot, private class MyEchoBot(XChatBot): ... # a private command. Takes a single argument @private dev cmd_lights(self, peer, status): """<status:on or off> - Turn lights on or off""" if status == "on": # turn on the lights peer.send("Lights are now on") elif status == "off": # turn off the lights peer.send("Lights are now off") else: peer.send("please, 'on' or 'off'.")
If no commands match the message received, default() method is called. Your bot class can override this method to return a default response:
class MyEchoBot(XChatBot): ... def default(self, peer, *args): peer.send("I'm sorry, I don't understand you. Write me 'help'")