The Xtensible XMPP Chat Bot

XChatBot is a xmpp bot library written in python using the nbxmpp library from Gajim


  • python 3
  • pygobject
  • nbxmpp


  • pipenv


With pip

pip install xchatbot

Using git

git clone

then install required packages:

with pipenv:

pipenv --site-packages --python 3
pipenv install

on osx you need first to install python3 with brew:

brew install python3 pipenv pygobject3

on Arch:

pacman -S python-gobject python-nbxmpp

on Debian:

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 ./echobot.rc, ~/.echobot.rc and /etc/echobot.rc in this order, and will load the first it find.

An example config file is provided as echobot.rc.dist, with comments.

See xchatbot.rc

Customize the bot

Subclass 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 start()


The bot will react to specific commands with optionals arguments.

Commands are method of the class named cmd_commandname. Each command method must get a peer (Peer) parameter and optionally a number of args.

A docstring should be provided that is used by help command to build the help message.

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)

if __name__ == "__main__":

To test this, create a myechobot.rc config file and run the bot:

$ python

Private commands

A command can be marked as private using the @private decorator.

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
        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")
                peer.send("please, 'on' or 'off'.")

Default command

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'")


A pre-configured logging.Logger object is available as class attribute logger

class MyEchoBot(XChatBot):
        def cmd_log(self,


Indices and tables