Skip to main content

Librairy to implement chatbot and broadcast bot on multiple platform (telegram, signal an whatsapp) at the same time

Project description

Py multi-platform bot

1 - Presentation

This API is meant to help create a simple non-AI multi-platform chatbot and difusion bot. It is meant to be a tool that can be used by people who aren't particullarly technically minded.

It will hopefully support as platforms :

  • The terminal (for testing)
  • Telegram
  • Signal (will be implemented relatively quickly)
  • Whatsapp (will be implemented relatively quickly)
  • A website (no plan to implement yet)

1.a - Installation

This repository is packaged on Pypi under the name pymultibots, and can thus be installed using :

pip install pymultibots

1.b - Example

An example is present at example/, for now it can be run by using the command :

python3 terminal_example.py

An example of a telegram bot is also present in the same directory.

while being located in the example/ folder.

2 - List of parameters

Parameters for the bot (dialogue, chat ID, etc...) are passed by json objects (or dict in the python code).

2.a - proposed definition of dialogue bot

For the dialogue part of the bot, the dialogue can be described by this structure :

{
	"start" : {
		"message" : "This bot is a simple bot asking you for your username and email",
		"file_paths": [
			"./python_logo.png"
		],
		"no_response" : true,
		"next_state" : "username"
	},
	"username" : {
		"message" : "Please enter your username :",
		"store_key" : "uname",
		"input_restriction" : "max_length:10",
		"restriction_message" : "Your username can't be more than 10 characters long",
		"next_state" : "has_email"
	},
	"has_email" : {
		"message" : "Do you want to input an email ?",
		"options" : ["[Y] yes I want to input an email !", "[n] no I'd rather not !"],
		"option_key" : ["Y", "n"],
		"allow_different_key" : true,
		"next_state" : ["email", "end_state"],
		"default_state" : "end_state"
	},
	"email" : {
		"message" : "Please enter your email :",
		"store_key" : "email",
		"next_state" : "has_more_emails"
	},
	"has_more_emails" : {
		"message" : "Do you want to input an other aditional email ?",
		"options" : ["[Y] yes I want to input an additional email !", "[n] no I'd rather not !"],
		"option_key" : ["Y", "n"],
		"allow_different_key" : true,
		"next_state" : ["more_email_happend", "end_state"],
		"default_state" : "end_state"
	},
	"more_email_happend" : {
		"no_response" : true,
		"write_values" : [
			{
				"key" : "email",
				"value" : ", ",
				"operation" : "append"
			}
		],
		"next_state" : "more_email"
	},
	"more_email" : {
		"message" : "Please enter your additional email :",
		"store_key" : "email",
		"store_operation" : "append",
		"input_restriction" : "max_length:10",
		"restriction_message" : "Your username can't be more than 10 characters long",
		"next_state" : "has_more_emails"
	},
	"end_state" : {
		"message" : "Thank you for answering !",
		"end_state" : true,
		"cooldown" : 2
	}
}

This is passed to the to_add function as a dict so it can be read of a json or yml file.

Each state is an entry in the dict, with the first state when interogating the bot being named start.

Here is a list of keys to parameterize the dialogue bot :

  • "message" (str) : The messages that will be sent.
  • "file_paths" (list or str) : List of path of files or images if you want to join one to the message
  • "no_response" (bool) : If true, doesn't wait for a response to pass to the next state (thus "next_state" needs to be a state and not a list of states).
  • "store_key" (str) : Name of key where the input given by the user will be stored.
  • "store_operation" (str) : Type of operation to be done to the key (default is set) :
    • append to simply append, either using + for strings, .add for sets or .append. If no value is set, the default is the string "".
    • add/substract to convert to float and add/substract to a float of default 0
    • multiply/divide to convert to float and multiply/divide by a float of default 1
    • and/or to convert to a bool and apply an and/or to a bool of default False.
  • "write_values" (list of dict) : Each dict in the list must have a "key" and "value" entry describe to what key and what value to set, and can have an "operation" entry which follows the same rules as the "store_operation" field described above, except that no conversion are made so you have full control of the types. "write_values" operations are evaluated in order before the operation described by "store_key" and "store_operation".
  • "options" (list of str) : A list of options to be selected.
  • "option_key" (list of str) : List of keys that correspond to each entry (for backend that requiere the user to choose an option by typing).
  • "option_values" (list) : Values associated to each option.
  • "allow_different_key" : If options are to be selected, wether to allow a key not in the list or not. Requires default_state to be set if "next_state" is a list.
  • key_not_in_list_message (str) : What message to send to the user if the key is not in the list and "allow_different_key" is set to false.
  • "next_state" (str or list of str) : Either the state that will come next, or a list of states that correspond to each option if "options" are passed.
  • "default_state" (str) : Next state if the option given is not in the list of "options".
  • "default_value" : Default value to be store if the option given is not in the list of "options".
  • "end_state" (bool) : If true this command will end the conversation.
  • "input_restriction" (str) Restrictions to the user input. If "options" are passed, the restrictions onlly apply if the key given is not in "option_key" and "allow_different_key" is true. Multiple restriction can apply, separated by semicolons, like int;max_length:10 to allow only an int with maximum of 10 characters. The possible restrictions are :
    • int to force the user to input an integer
    • number to force the user to input a number (floating point or not, separeted by . or ,)
    • max_length:N to prevent having more than N character.
  • "restriction_message" (str) : Message to be sent to the user if the input is restricted by "input_restriction"
  • "cooldown" (int) : Cooldown before being able to talk again to the bot.

There are some special keys that can be stored :

  • "save" (bool) : Wether the values gather by the dialogue with the user needs to be saved or not.
  • "share" (bool) : If "share" is set to anything but true, the state will be saved but not broadcasted if a broadcaster is running.
  • "debug" (bool) : If "debug" is set to true it won't be broadcasted, and although states marked with the debug flag are saved, they are deleted if and when the state file is archived.

All special keys ("share", "debug", "cooldown" and "save") can be written without using the normal "write_values" option.

Every entry also have a field named time which denote the starting time of the dialogue as an iso timestamp. time_str is a string version of the time field according to the time_format parameter if present.

2.a.1 - Multilanguage bot

You can get a multilanguage dialogue from merging dialogue defined in different languages using the dialogue_utils.make_multilanguage_dialogue() function :

from pymultibots import dialogue_utils

dialogue = dialogue_utils.make_multilanguage_dialogue({
	"message" : "Welcome, please choose language !\n\n ¡Bienvenido! Elige el idioma.",
	"languages" : {
		"Francais" : french_language_dialogue,
		"Español" : spanish_language_dialogue
	}
})

You simply need to pass to the function a dict containing a starting message before language choice, and a dict of languages names associated with their dialogue dict as described in the previous section.

Any other key will be added to the newely generated "start" state, thus for example if you want your languages to be choses using short keys you can use :

from pymultibots import dialogue_utils

dialogue = dialogue_utils.make_multilanguage_dialogue({
	"message" : "Welcome, please choose language !\n\n ¡Bienvenido! Elige el idioma.",
	"languages" : {
		"[fr] Francais" : french_language_dialogue,
		"[es] Español" : spanish_language_dialogue
	},
	"option_key" : ["fr", "es"]
})

2.b - proposed list of particular key

Some keys have particular meaning :

  • send : If it is present and equal to anything but true (or 1), the answer won't be sent (if the bot has a broadcast component).
  • debug : If it is present and equal to true or 1 the answer won't be archived when the list of answers are archived.

2.c - proposed definition of broadcast bot

A dialogue bot can be joined with a broadcast bot which will format the broadcast text for each answer. Here is the typical structure of a broadcast definition :

{
	"filename" : "json_state_folder/terminal_broadcast_state.json",
	"sleep_interval" : 1,
	"template" : [
		"Time of day {time_str},\n",
		{
			"template" : "username : {uname},\n",
			"default_template" : "No username given,\n"
		}, {
			"template" : "user email : {email}",
			"requiered_keys" : ["email"],
			"default_template" : "no email provided."
		}
	]
}

Here is a list of keys to parameterize the broadcaster bot :

  • "filename" (str) : Where the broadcaster saves the list of entries already seen.
  • "sleep_interval" (float) : How often in seconds to check whether new entries were added (default is 1 second).
  • "template" (str or list of dict or str) : Template to create the message to broadcast, either a single str that gets formated using the keys stored by the bot, using the python function template.format(entry), or a list of dict describing sections of the message as described bellow.

If the template field is made of a list of dict, each entry in the list are formated one after the other and appened to each other to generate the message, using the following field for each dict :

  • "template" (str) : Template to create the message to broadcast using the python function template.format(entry)
  • "requiered_keys" (list of str) : List of keys that all need to be in the entry for the "template_text" to be formated and appened to the message.
  • "default_template" (str) : Template to create the message to broadcast using the python function default_template.format(entry) if the keys listed in "requiered_keys" are not all present in the entry.

2.d - proposed parameters

{
	"filename" : "json_state_folder/entry_list.json",
	"cancel_tag" : "cancel",
	"cancel_message" : "canceling the dialogue...",
	"timezone" : "utc",
	"time_format" : "%H:%M:%S %d/%m/%Y",
	"archive_dirpath" : "json_state_folder/archive/",
	"max_filesize_kb" : 0.5,
	"max_file_length" : 5,
	"max_archive_size_gb" : 0.00001
}

The bot can further be parameterized :

  • "filename" (str) : Path of where entries will be saved.
  • "cancel_tag" (str or list of str) : Tag or list of tag that if written in the answer to a question (case insensitive) will cancel the dialogue without cooldown.
  • "cancel_message (str) : Message that will be sent when canceling the dialogue.
  • "timezone" (str) : Timezone string (passed to pytz.timezone) forwhich the time field will be measured, default is utc.
  • "time_format" (str) : String that describe the format of the time_str field, according to the strftime() function of the datetime python package.
  • "archive_dirpath" (str) : Path of archive foler.
  • "max_filesize_kb" (float) : Maximum size of a file before being archived in Kb
  • "max_file_length" (int) : Maximum number of entry in a file before being archived.
  • "max_archive_size_gb" (float) : Maximum total archive folder size before the oldest archive file being deleted in Gb

2.e - proposed connection to platforms

For each backend (except the terminal backend which doesn't use account) you can log in to the account that will be used by the bot and/or the broadcaster using the function backend.log_in_account(account_params) with account_params being a dict with the following fields (depending on each platform) :

2.e.1 - proposed connection to telegram

from pymultibots.backends import telegram

backend = telegram.telegram_backend(backend_parameters)

backend.login_account({
	"telegram_chat_id" : "chat_id",
	"telegram_bot_token" : "bot_token",
	"force_option_key" : False,
	"proxy_url" : "127.0.0.1"
})

To connect to telegram you need to pass the following arguments :

  • "telegram_chat_id" ( str) : Id of the chat to which the broadcaster will broadcast.
  • "telegram_bot_token" (str) : Bot token.
  • "force_option_key" (bool, default is false) : Since telegram allows you to click on options, unless you set "force_option_key" to true the "option_key" parameter will be ignored so that the user can simply click rather than write an input by hand.
  • "proxy_url" (str) : Optional proxy through which the bot will interact with the telegram servers.

2.e.2 - proposed connection to signal

from pymultibots.backends import signal

backend = signal.signal_backend(backend_parameters)

backend.login_account({
	"todo" : "todo"
})

To connect to signal you need to pass the following arguments :

  • Todo

2.e.2 - proposed connection to whatsapp

from pymultibots.backends import whatsapp

backend = whatsapp.whatsapp_backend(backend_parameters)

backend.login_account({
	"todo" : "todo"
})

To connect to whatsapp you need to pass the following arguments :

  • Todo

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymultibots-0.1.0.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymultibots-0.1.0-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file pymultibots-0.1.0.tar.gz.

File metadata

  • Download URL: pymultibots-0.1.0.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.13.5 Linux/6.12.74+deb13+1-amd64

File hashes

Hashes for pymultibots-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a05755a1fe1fe3927b31e7de72f995ef0137f085dcd67a4b0e754578a0138b10
MD5 6806d3b97effdc26743a989af0e036ec
BLAKE2b-256 ad0291d3c4294b51779f1737bdb85bac262ba6baa13099a600ed168bd195705d

See more details on using hashes here.

File details

Details for the file pymultibots-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pymultibots-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.13.5 Linux/6.12.74+deb13+1-amd64

File hashes

Hashes for pymultibots-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4c6af698572d470983cc69c1f2f559aaf80577078f4582a48d0285b551d75ce4
MD5 89d1efbf36ba1c34a87977316fbbafa9
BLAKE2b-256 46f05485a2a3267393d724b4d8ee920b4b5317a43f0c7dd2171ee54e3a627006

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page