nicolabs / nicobot

🤟 A collection of *cool* chat bots 🤟
MIT License
1 stars 0 forks source link

nicobot

GitHub repo Build Status on 'master' branch PyPi Build and publish to Docker Hub Docker debian Docker signal-debian Docker alpine Buy us a tree

About

A collection of 🤟 cool 🤟 chat bots :

⚠️ My bots are cool, but they are absolutely EXPERIMENTAL use them at your own risk !

This project features :

This document is about how to use the bots. To get more details on how to build / develop with this project, see Develop.md.

Requirements & installation

The bots can be installed and run at your choice from :

Python package installation

A classic (Python package) installation requires :

To install, simply do :

pip3 install nicobot

Then, you can run the bots by their name :

# Runs the 'transbot' bot
transbot [options...]

# Runs the 'askbot' bot
askbot [options...]

Installation from source

To install from source you need to fulfill the requirements for a package installation (see above), then download the code and build it :

git clone https://github.com/nicolabs/nicobot.git
cd nicobot
python3 setup.py build
pip3 install -c constraints.txt -r requirements-runtime.txt .

NOTE Depending on your platform, pip install may trigger a compilation for some or all of the dependencies (i.e. when Python wheels are not available). In this case you may need to install more requirements for the build to succeed : looking at the Dockerfiles in this project may help you gather the exact list.

Now you can run the bots by their name as if they were installed via the package :

# Runs the 'transbot' bot
transbot [options...]

# Runs the 'askbot' bot
askbot [options...]

Docker usage

At the present time there are several Docker images available, with the following tags :

Please have a look at the status shields at the top of this document to get more details like status and size.

ADVICE The current state of those images is such that I suggest you use the signal-debian image if you need Signal, otherwise the alpine one.

The container is invoked this way :

docker ... [--signal-register <device name>] [--qrcode-options <qr options] <bot name> [<bot arguments>]

You can run the image without any argument to print the inline help statement.

Noteworthy directories :

Develop.md contains a thorough description of the inner filesystem of the Docker images.

Sample command to start a container :

docker run --rm -it -v "$(pwd)/myconfdir:/etc/nicobot" nicolabs/nicobot transbot -C /etc/nicobot

In this example myconfdir is a local directory with configuration files for the bot (-C option), but you could also set most parameters on the command line.

You can also use docker volumes to persist signal, XMPP and other configuration :

docker run --rm -it -v "$(pwd)/myconfdir:/usr/src/app" -v "$HOME/.local/share/signal-cli:/root/.local/share/signal-cli" -v "$HOME/.omemo:/usr/src/app/.omemo" nicolabs/nicobot transbot

All options that can be passed to the bots' command line can also be passed to the docker command line.

How to use the bots

Transbot usage

Transbot is a demo chatbot interface to IBM Watson™ Language Translator service.

Again, this is NOT STABLE code, there is absolutely no warranty it will work or not harm butterflies on the other side of the world... Use it at your own risk !

It is triggered by messages :

When triggered, it will answer with a translation of the given text.

It will reply either to direct messages or to a group chat, depending on the given parameters.

The sample configuration in tests/transbot-sample-conf, demoes how to make the bot answer messages given in the form nicobot <text_to_translate> in <language> (or simply nicobot <text_to_translate>, into the current language) with a translation of __.

Transbot can also pick a random language to translate into ; the sample configuration file shows how to make it translate messages containing "Hello" or "Goodbye" into a random language.

Quick start

  1. Install nicobot (see above)
  2. Create a Language Translator service instance on IBM Cloud and get the URL and API key from your console
  3. Make a local copy of files in tests/transbot-sample-conf/ and fill the ibmcloud_url and ibmcloud_apikey values into config.yml
  4. Run transbot -C ./transbot-sample-conf (with docker it will be something like docker run -it "$(pwd)/transbot-sample-conf:/etc/nicobot" nicolabs/nicobot transbot -C /etc/nicobot)
  5. Type Hello world in the console : the bot will print a random translation of "Hello World"
  6. Type Bye nicobot : the bot will terminate

You may now explore the dedicated chapters below for more options, including sending & receiving messages through XMPP or Signal instead of keyboard & console.

Main configuration options and files

This paragraph introduces the most important parameters to make this bot work. Please also check the generic options below ; finally run transbot -h to get an exact list of all options.

The bot needs several configuration files that will be generated / downloaded the first time if not provided :

The patterns and custom texts the bot speaks & recognizes can be defined in the i18n.\.yml file :

A sample configuration is available in the tests/transbot-sample-conf/ directory.

Askbot usage

Askbot is a one-shot chatbot that will typically ask for something and wait for an answer.

It is primarily meant to integrate with other programs in a more large process, like for instance : asking for a user to authenticate via chat.

Again, this is NOT STABLE code, there is absolutely no warranty it will work or not harm butterflies on the other side of the world... Use it at your own risk !

You configure the string to send and the rules that make it exit, depending on the received messages (see options below). Once the conditions are met, the bot will terminate and print the result in JSON format. This JSON structure will have to be parsed in order to retrieve the answer and determine what were the exit(s) condition(s).

Main configuration options

Run askbot -h to get a description of all options.

Below are the most important configuration options for this bot (please also check the generic options below) :

Sample configuration can be found in tests/askbot-sample-conf.

Examples

Simple example (with Jabber)
askbot -b jabber -U mybot@myserver.im -r me@myserver.im --jabber-password 'Myb0tp@SSword' -m "Hello You !" -p bye 'bye'

Will say 'Hello You !' to me@myserver.im, and for a message containing 'bye' to quit. If the recipient handles it, the communication will be end-to-end encrypted with OMEMO.

More complex example (and with Signal)
askbot -m "Do you like me ?" -p yes '(?i)\b(yes|ok)\b' -p no '(?i)\bno\b' -p cancel '(?i)\b(cancel|abort)\b' --max-count 3 -b signal -U '+33123456789' --recipient '+34987654321'

The previous command will :

  1. Send the message "Do you like me" to +34987654321 on Signal
  2. Wait for a maximum of 3 messages in answer and return
  3. Or return immediately if a message matches one of the given patterns labeled 'yes', 'no' or 'cancel'

If the user +34987654321 replies with 2 messages :

  1. I don't know
  2. Ok then : NO !

    Then the output would be :

{
    "max_responses": false,
    "messages": [{
        "message": "I don't know...",
        "patterns": [{
            "name": "yes",
            "pattern": "(?i)\\b(yes|ok)\\b",
            "matched": false
        }, {
            "name": "no",
            "pattern": "(?i)\\bno\\b",
            "matched": false
        }, {
            "name": "cancel",
            "pattern": "(?i)\\b(cancel|abort)\\b",
            "matched": false
        }]
    }, {
        "message": "Ok then : NO !",
        "patterns": [{
            "name": "yes",
            "pattern": "(?i)\\b(yes|ok)\\b",
            "matched": true
        }, {
            "name": "no",
            "pattern": "(?i)\\bno\\b",
            "matched": true
        }, {
            "name": "cancel",
            "pattern": "(?i)\\b(cancel|abort)\\b",
            "matched": false
        }]
    }]
}

A few notes about the regex usage in this example : in -p yes '(?i)\b(yes|ok)\b' :

You may also have noticed the importance of defining patterns that don't overlap (here the message matched both 'yes' and 'no') or being ready to handle unknown states.

To make use of the bot, you could parse its output with a script, or with a command-line client like jq :

# tail -1 will skip the messages printed to the console and only pipe the final line to jq
askbot -m Hello -p ok ok | tail -1 | jq

Here's an example snippet for a Python program to extract the name of the matched patterns :

# loads the JSON output
output = json.loads('{ "max_responses": false, "messages": [...] }')
# 'matched' is the list of the names of the patterns that matched against the last message
matched = [ p['name'] for p in output['messages'][-1]['patterns'] if p['matched'] ]
# e.g. matched = `['yes','no']`

Generic instructions

Common options

The following options are common to both bots :

Configuration file : config.yml

Options can also be taken from a configuration file. By default it reads the config.yml file in the current directory but can be changed with the --config-file and --config-dirs options.

This file is in YAML format with all options at root level. Keys are named after the command line options, with middle dashes - replaced with underscores _ and a s appended for lists (option --ibmcloud-url https://api... will become ibmcloud_url: https://api... and --keywords-file 1.json --keywords-file 2.json will become :

keywords_files:
    - 1.json
    - 2.json

See also sample configurations in the tests/ directory.

If unsure, please first review YAML syntax as it has a few traps.

Using the Jabber/XMPP backend

By specifying --backend jabber you can make the bot chat with XMPP (a.k.a. Jabber) users.

Jabber-specific options

A .omemo directory inside the configuration directory will be created or reused if existing to store OMEMO authentication data.

Example
transbot -C tests/transbot-sample-conf -b jabber -U mybot@myserver.im -r me@myserver.im`

With :

Using the Signal backend

By specifying --backend signal you can make the bot chat with Signal users.

Prerequistes

For package and source installations, you must first install and configure signal-cli.

For all installations, you must register or link the computer where the bot will run ; e.g. :

signal-cli link --name MyComputer

With docker images you can do this registration by using the --signal-register option. This will save the registration files into /root/.local/share/signal-cli/ inside the container. If this location is bound to a persistent volume, it can be reused on next launch.

Please see signal-cli's man page for more details about the registration process.

Signal-specific options

Example :

transbot -b signal -U +33612345678 -g "mABCDNVoEFGz0YeZM1234Q==" --ibmcloud-url https://api.eu-de.language-translator.watson.cloud.ibm.com/instances/a234567f-4321-abcd-efgh-1234abcd7890 --ibmcloud-apikey "f5sAznhrKQyvBFFaZbtF60m5tzLbqWhyALQawBg5TjRI"

Common issues

Couldn't load the OMEMO object

The following error is XMPP/Jabber related :

ERROR   Couldn't load the OMEMO object; ¯\_(ツ)_/¯
ERROR   And error occured when loading the omemo plugin.
omemo.exceptions.inconsistentinfoexception.InconsistentInfoException: Given storage is only usable for jid mybot@myserver.im on device 1234567890.

This may be because you previously registered another device at the same place : move or delete the .omemo directory and retry.

ERROR No appropriate login method

This message may mean that your XMPP/Jabber account or password is incorrect.

Authorization failed!

Sample error stack :

nicobot_1  | Failed to resolve uuids from server: Authorization failed!
nicobot_1  | Failed to get sender certificate: org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException: Authorization failed!
nicobot_1  | Failed to send message: Authorization failed!

This error is probably triggered by a misconfiguration or absence of Signal credentials. Make sure to link the bot with a device (see instructions above, including the --signal-register option for the Docker images).

External resources

Licence

This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.