Package: nicobot
nicobotPython package :Docker images :AboutA collection of 🤟cool🤟 chat bots :Transbotis a demo chatbot interface to IBM Watson™ Language Translator serviceAskbotis a one-shot chatbot that will send a message and wait for an answer⚠️My bots are cool, but they are absolutelyEXPERIMENTALuse them at your own risk !This project features :Participating inSignalconversationsParticipating inXMPP / JabberconversationsUsingIBM Watson™ Language Translatorcloud APIThis document is about how tousethe bots.
To get more details on how tobuild / developwith this project, seeDevelop.md.Requirements & installationThe bots can be installed and run at your choice from :the Python package (PyPi)the source code (github)the Docker images (Docker Hub)Python package installationA classic (Python package) installation requires :Python 3 (>= 3.5) and pip (should already be bundled with Python) ; e.g. on Debian :sudo apt install python3 python3-pipsignal-clifor theSignalbackend (seeUsing the Signal backendbelow for requirements)Fortransbot: an IBM Cloud account (free account ok)To install,  simply do :pip3 install nicobotThen, you can run the bots by their name :# Runs the 'transbot' bot
transbot [options...]

# Runs the 'askbot' bot
askbot [options...]Installation from sourceTo 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 -r requirements-runtime.txt .NOTEDepending on your platform,pip installmay trigger a compilation for some or all of the dependencies (i.e. whenPython wheelsare not available).
In this case you may need to install more requirements for the build to succeed : looking atthe Dockerfiles in this projectmay 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 usageAt the present time there areseveral Docker images available, with the following tags :debian(orX.Y.Z-debian) : this is the most portable image ; in order to keep it relatively small it does not include theSignalbackend (will throw an error if you try --> use XMPP instead)signal-debian(orX.Y.Z-signal-debian) : this is the most complete image ; it is also the largest one, but allowsSignalmessagingalpine(orX.Y.Z-alpine) : this should be the smallest image, but it's more complex to maintain and therefore might not always meet this expectation. Also, due to the lack/complexity of Alpine support for some Python, Java & native dependencies, images may support less platforms and it currently doesn't provide the Signal backend (you can use XMPP instead).X.Y.Z-<image variant>tags are simply versionX.Y.Zof<image variant>. E.g.1.2.3-alpineis nicobot version 1.2.3 in thealpinevariant (not related with alpine's version).latestpoints to the latest versioned image ofsignal-debian(which offers all features).dev-<image variant>tags are development versions of the master branch.Do not use : they are probably broken !History is currently not preserved : there is only onedev-tag of an image variant at a time.Please have a look at the status shields at the top of this document to get more details like status and size.ADVICEThe current state of those images is such that I suggest you try thealpineimage first and switch to adebian*one if you need Signal or encounter runtime issues.The container is invoked this way :docker ... [--signal-register <device name>] [--qrcode-options <qr options] <bot name> [<bot arguments>]--signal-registeris Signal-specific. It will display a QR code in the console : scan it with the Signal app on the device to link the bot with (it will simply do thesignal-cli linkcommand inside the container ; read more about this later in this document). If this option is not given and thesignalbackend is used, it will use the.local/share/signal-clidirectory from the container (youhaveto mount it) or fail. This option takes a custom device name as its argument.--qrcode-optionsis Signal-specific. It takes as argument a string of options to pass to the QR code generation command (seepython-qrcode).<bot name>is eithertransbotoraskbot<bot arguments>is the list of arguments to pass to the bot (see bots' usage)If any doubt, just invoke the image without argument to print the inline help statement.Sample command to start a container :docker run --rm -it -v "$(pwd)/myconfdir:/etc/nicobot" nicolabs/nicobot transbot -C /etc/nicobotIn this examplemyconfdiris a local directory with configuration files for the bot (-Coption), but you could also set most parameters on the command line.You can also usedocker volumesto persistsignal,XMPPand 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 transbotAll options that can be passed to the bots' command line can also be passed to the docker command line.How to use the botsTransbot usageTransbotis 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 :either matching the configured patternor containing a keyword from a given listWhen 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 intests/transbot-sample-conf, demoes how to make the bot answer messages given in the formnicobot <text_to_translate> in <language>(or simplynicobot  <text_to_translate>, into the current language) with a translation of<text_to_translate>.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 startInstallnicobot(see above)Create aLanguage Translatorservice instance on IBM Cloudandget the URL and API key from your consoleMake a local copy of files intests/transbot-sample-conf/and fill theibmcloud_urlandibmcloud_apikeyvalues intoconfig.ymlRuntransbot -C ./transbot-sample-conf(with docker it will be something likedocker run -it "$(pwd)/transbot-sample-conf:/etc/nicobot" nicolabs/nicobot transbot -C /etc/nicobot)TypeHello worldin the console : the bot will print a random translation of "Hello World"TypeBye nicobot: the bot will terminateYou may now explore the dedicated chapters below for more options, including sending & receiving messages throughXMPPorSignalinstead of keyboard & console.Main configuration options and filesThis paragraph introduces the most important parameters to make this bot work. Please also check the generic options below ; finally runtransbot -hto get an exact list of all options.The bot needs several configuration files that will be generated / downloaded the first time if not provided :--keywordand--keywords-filewill help you generate a list of translations for the given keywords so they will trigger the bot even if written in other languages. To do it, run thisa first time:transbot --keyword <a_keyword> --keyword <another_keyword> ...to download all known translations for these keywords and save them into akeywords.jsonfile. Next time you run the bot,don'tuse the--keywordoption : it will reuse this saved keywords list. You can use--keywords-fileto change the file name.--languages-file: The first time the bot runs it will download the list of supported languages (to translate into) intolanguages.<locale>.jsonand reuse it afterwards. You can edit it, to keep just the set of languages you want for instance. You can also use the--localeoption to indicate the desired locale.--localewill select the locale to use for default translations (with no target language specified) and as the default parsing language for keywords.--ibmcloud-urland--ibmcloud-apikeytake arguments you can obtain from your IBM Cloud account (create a Language Translator instancethen go tothe resource list)The patterns and custom texts the bot speaks & recognizes can be defined in thei18n.<locale>.ymlfile :Transbotwill say "Hello" when started and "Goodbye" before shutting down : you can configure those banners in this file.It also defines the pattern that terminates the bot.A sample configuration is available in thetests/transbot-sample-conf/directory.Askbot usageAskbotis 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 inJSONformat.
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 optionsRunaskbot -hto get a description of all options.Below are the most important configuration options for this bot (please also check the generic options below) :--max-countwill define how many messages to read at maximum before exiting. This allows the recipient to split the answer in several messages for instance. However currently all messages are returned by the bot at once at the end, so they cannot be parsed on the fly by an external program. To givextries to the recipient, runxtimes this bot instead.--patterndefines a pattern that will end the bot when matched. This is the way to detect an answer. It takes 2 arguments : a symbolic name and aregular expression patternthat will be tested against each message. You can define multiple patterns in the same command line, hence the<name>argument, which will allow identifying which pattern(s) matched.Sample configuration can be found intests/askbot-sample-conf.ExamplesSimple 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 !' tome@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 :Send the message "Do you like me" to +34987654321 on SignalWait for a maximum of 3 messages in answer and returnOr return immediately if a message matches one of the given patterns labeled 'yes', 'no' or 'cancel'If the user+34987654321replies with 2 messages :I don't knowOk 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 theregexusage in this example : in-p yes '(?i)\b(yes|ok)\b':(?i)enables case-insensitive match\bmeans "edge of a word" ; it is used to make sure the wanted text will not be part of another word (e.g.tik tokwould matchokotherwise)Note that a regexsearchis done on the messages (not amatch) so it is not required to specify a fullregular expressionwith^and$(though you may do, if you want to). This makes the pattern more readable.The pattern is labeled 'yes' so it can be easily identified in the JSON output and counted as a positive matchYou 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 likejq:# 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 | jqHere's an example snippet for aPythonprogram to extract the name of the matched patterns :# loads the JSON outputoutput=json.loads('{ "max_responses": false, "messages": [...] }')# 'matched' is the list of the names of the patterns that matched against the last messagematched=[p['name']forpinoutput['messages'][-1]['patterns']ifp['matched']]# e.g. matched = `['yes','no']`Generic instructionsCommon optionsThe following options are common to both bots :--config-fileand--config-dirlet you change the default configuration directory and file. All configuration files will be looked up from this directory ;--config-fileallows overriding the location ofconfig.yml.--backendselects thechattersystem to use : it currently supports "console", "signal" and "jabber" (see below)--stealthwill make the bot connect and listen to messages but print answers to the console instead of sending it ; useful to observe the bot's behavior in a real chatroom...--debug / -d / --verbosity / -vthose options modify the verbosity level :--debugis a flag that sets it toDEBUGwhile with--verbosityyou can definethe exact level(e.g.-v TRACE).Configuration file : config.ymlOptions can also be taken from a configuration file.
By default it reads theconfig.ymlfile in the current directory but can be changed with the--config-fileand--config-diroptions.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 asappended for lists (option--ibmcloud-url https://api...will becomeibmcloud_url: https://api...and--keywords-file 1.json --keywords-file 2.jsonwill become :keywords_files:-1.json-2.jsonSee also sample configurations in thetests/directory.If unsure,  please first reviewYAML syntaxas it has a few traps.Using the Jabber/XMPP backendBy specifying--backend jabberyou can make the bot chat with XMPP (a.k.a. Jabber) users.Jabber-specific options--jabber-usernameand--jabber-passwordare the JabberID (e.g.myusername@myserver.im) and password of the bot's account used to send and read messages. If--jabber-usernameis missing,--usernamewill be used.--jabber-recipientis the JabberID of the person to send the message to. If missing,--recipientwill be used.A.omemodirectory inside the configuration directory will be created or reused if existing to store OMEMO authentication data.Exampletransbot -C tests/transbot-sample-conf -b jabber -U mybot@myserver.im -r me@myserver.im`With :-b jabberto select the XMPP/Jabber backend-U mybot@myserver.imtheJabberIDof the bot-r me@myserver.imtheJabberIDof the correspondentCommon issuesIf you have the following error :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.omemodirectory and retry.Using the Signal backendBy specifying--backend signalyou can make the bot chat with Signal users.PrerequistesFor package and source installations, you must firstinstall and configuresignal-cli.For all installations, you mustregisterorlinkthe computer where the bot will run ; e.g. :signal-cli link --name MyComputerWith docker images you can do this registration by using the--signal-registeroption. 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 seesignal-cli's man pagefor more details about the registration process.Signal-specific options--signal-usernameselects the account to use to send and read message : it is a phone number in international format (e.g.+33123456789). Inconfig.yml, make sure to put quotes around it to prevent YAML thinking it's an integer (because of the 'plus' sign). If missing,--usernamewill be used.--signal-recipientand--signal-groupselect the recipient (only one of them should be given). Make sure--signal-recipientis in international phone number format and--signal-groupis a base 64 group ID (e.g.--signal-group "mABCDNVoEFGz0YeZM1234Q=="). If--signal-recipientis missing,--recipientwill be used. To get the IDs of the groups you are in, run :signal-cli -U +336123456789 listGroupsExample :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"External resourcesIBM Watson Language Translator serviceSignal messaging :https://signal.orgXMPP resources :https://xmpp.org/software/libraries.htmlOMEMO compatible clients :https://omemo.top/Gaijim, a Windows/MacOS/Linux XMPP client with OMEMO support :gajim.org|dev.gajim.org/gajimConversations, an Android XMPP client with OMEMO support and paid hosting :https://conversations.im