Community
Botium Champions
Botium champion is the award we set up to give out as our appreciation to those who are making an impact on our projects.
Community is the heart of Botium and our champions are driving the community! We would like to express our gratitude to those nerds by giving out some shiny stuffs and the privilege of being our champion!
There are several ways of contribution.
Are you a restless developer? You can support us by writing code and catching bugs
Do you have a big network? Share your Botium use cases and experience with your mates
Are you an expert? Answer community questions on stackoverflow or github (+links)
Do you have tester genes? Help us by pointing out flaws or suggesting new features
Are you a researcher? Support us with the scientific proof of coolness
Contribution Guide
We love Open Source software. Open Source software helped us in our professional careers for the last 20 years, and we are giving back to the community.
All Botium Core code (Botium Core, Botium Bindings, Botium CLI) and most connectors are hosted on Github <https://github.com/codeforequity-at> and open for contributions.
Prerequisites
Good knowledge of Node.js and Javascript
Knowledge on Git and Github
In case you have some troubles, please __ALWAYS__ attach the debug output from Botium
Please don’t post any secret information (like access keys for Dialogflow or IBM Watson)
Guidelines for code contributions
Of course, code contributions are welcome! There are many possible ways of extending Botium.
Contributions to Botium Core
Please fork the repository
Please create an issue and refer to it in the pull request
Add unit tests for implemented behaviour
- The NPM script “npm run build” has to succeed before posting a pull request
it will run unit tests
it will enforce eslint and rollup build
Someone from the core team will review and give feedback within 1-2 days
Contribute Botium Connectors
There is a Developer Guide available below
Tell us about your work! We are happy to include your connector in Botium Core and thank you in our release notes!
Contribute Botium Asserters
There is a Developer Guide available below
Tell us about your work! We are happy to include your asserter in Botium Core and thank you in our release notes!
We want to recognise everyone making positive influence in our community. We are doing our part of the job by tracking every possible Botium champion out there, but if you feel like that we are missing someone, let us know!
First Steps - Botium Core
Botium Core is the core library for Botium. Some core connectors and BotiumScript is implemented in Botium Core.
Clone and Run Tests
Here are the commands to clone the Botium Core repository, install the dependencies, running the build and running the test suite:
git clone https://github.com/codeforequity-at/botium-core.git
cd botium-core
npm install
npm run build
npm test
Pull Requests
As usual on Github, you can fork the repository and create a Pull Request with your changes. One of the core developers will get in contact.
We expect that any code changes are covered by unit tests.
Make sure that the commands npm run build and npm test are working with your changes, otherwise the Pull Request will be declined for sure!
Important Files
src/BotDriver.js - the main entry file
Reads the botium.json and other configuration sources
Initializes scripting and containers
src/Capabilities.js - capability names
Holds the list of supported capability names
src/Defaults.js - default capability values
Holds the list of default capability values
src/scripting/ScriptingProvider.js - entry point for BotiumScript
Initializes BotiumScript runtime
Holds context for scripting runtime
Reads BotiumScript files
src/scripting/Compiler*.js - BotiumScript parsers
Parsing the supported BotiumScript file formats
src/scripting/logichooks/asserters/*Asserter.js - integrated asserters
Media asserter, NLP asserters, …
src/scripting/logichooks/logichooks/*LogicHook.js - integrated logic hooks
Pause, Wait, …
src/scripting/logichooks/userinputs/*Input.js - integrated user input methods
Buttons, Forms, …
Developing Botium Connectors
Howto develop your own Botium Connector - see Botium Wiki
Howto develop your own HTTP/JSON Botium Connector - see Botium Wiki
Howto deploy my own Botium Connector - see Botium Wiki
Developing Custom Asserters
Developing Custom Asserters - see Botium Wiki
Developing Botium Logic Hooks
Developing Custom Logic Hooks - see Botium Wiki
Developing Custom Hooks
There are capabilities for running your custom logic, developed in Javascript, during Botium script execution.
CUSTOMHOOK_ONBUILD
CUSTOMHOOK_ONSTART
CUSTOMHOOK_ONUSERSAYS
CUSTOMHOOK_ONBOTRESPONSE
CUSTOMHOOK_ONSTOP
CUSTOMHOOK_ONCLEAN
There are several options how to inject our Javascript code here. The functions are called with arguments from Botium as nested structure.
container: the currently executing Botium container
meMsg (only for CUSTOMHOOK_ONUSERSAYS): message sent to bot
botMsg (only for CUSTOMHOOK_ONBOTRESPONSE): message received from bot
request: for doing HTTP(S) requests
As NPM module
Your custom NPM module has to export exactly one function.:
"CUSTOMHOOK_ONUSERSAYS": "my-own-module",
As Javascript file
Your file has to export exactly one function.:
"CUSTOMHOOK_ONUSERSAYS": "path/to/your/javascript/file.js",
Example function in file.js:
module.exports = ({ container, meMsg }) => {
console.log('in userSays hook');
meMsg.CUSTOM_VALUE = 'something'
}
Custom File Format Precompiler
If you have custom file format, then you have to use a precompiler to convert it to any standard file format.
Supported input and output file extensions are same as supported file extensions of Botium:
.convo.txt,
.utterances.txt,
.pconvo.txt,
.scriptingmemory.txt,
.xlsx,
.convo.csv,
.pconvo.csv,
.yaml,
.yml,
.json
.md
You dont have to keep the file extension. (It is possible to convert .md to .json for example)
Output file format can be any standard Botium Script format, but we suggest to use JSON (or YAML) file format. They can contain all parts of a script in a single file, and it is easy to work with.
There is a limitation with precompilers. It is not possible to create more files from one. Using JSON output file format can help handle this limitation.
Configuration capabilities
The preformatters are dynamic. You can use more precompilers, even from the same type. The capabilities are dynamic too, there are many ways to structure them:
Just for one precompiler:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS.NAME": "<precompilername>",
"PRECOMPILERS.VARIABLE1": "..."
}
or:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS": {
"NAME": "<precompilername>",
"VARIABLE1": "..."
}
}
same as string:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS": "{\"NAME\": \"<precompilername>\",\"VARIABLE1\": \"...\"}"
}
For more precompilers:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS.0.NAME": "<precompilername>",
"PRECOMPILERS.0.VARIABLE1": "...",
"PRECOMPILERS.1.NAME": "<precompilername>",
"PRECOMPILERS.1.VARIABLE1": "..."
}
or:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS.0": {
"NAME": "<precompilername>",
"VARIABLE1": "..."
},
"PRECOMPILERS.1": {
"NAME": "<precompilername>",
"VARIABLE1": "..."
}
}
or:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS": [
{
"NAME": "<precompilername>",
"VARIABLE1": "..."
},
{
"NAME": "<precompilername>",
"VARIABLE1": "..."
}
]
}
same as string:
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS": "[{\"NAME\": \"<precompilername>\",\"VARIABLE1\": \"...\"},{\"NAME\": \"<precompilername>\",\"VARIABLE1\": \"...\"}]"
}
JSON_TO_JSON_JSONPATH Precompiler
Compiles not-standard-json using JsonPath.
This precompiler just supports extraction of utterances.
Capabilities
NAME
Set to JSON_TO_JSON_JSONPATH to use this compiler.
CHECKER_JSONPATH
Optional. If the precompiler does not found anything using this JsonPath, then ignores the source json file.
ROOT_JSONPATH
Optional. Maps the source JSON to utterance struct array. (One entry in map can be mapped to one utterance reference name)
UTTERANCE_REF_JSONPATH
JsonPath to the utterance reference name
UTTERANCES_JSONPATH
JsonPath to the utterances
Example
Source Json:
{
"domains": [
{
"name": "Banking",
"intents": [
{
"name": "Transfer",
"sentences": [
{
"text": "Send 2 bucks to savings!"
}
]
}
]
}
]
}
Capabilities:
{
PRECOMPILERS: {
"NAME": "JSON_TO_JSON_JSONPATH",
"CHECKER_JSONPATH": "$.domains[*].intents[*]",
"ROOT_JSONPATH": "$.domains[*].intents[*]",
"UTTERANCE_REF_JSONPATH": "$.name",
"UTTERANCES_JSONPATH": "$.sentences[*].text"
}
}
SCRIPTED Precompiler
Compiles not-standard Text, Excel, CSV, YAML, JSON, Markdown file toBotiumScript File Formats using JavaScript code.
Capabilities
NAME
Set to SCRIPT to use this precompiler.
SCRIPT
The JavaScript code - it is not a function, do not use return there, but set the module.exports variable.
Example
For the sake of simplicity we use JSON file with just utterances as output. But of course all features of all file types can be used.
Basic example, json
{
"PROJECTNAME": "Precompiler",
"CONTAINERMODE": "echo",
"PRECOMPILERS": {
"NAME": "SCRIPT",
"SCRIPT": "const utterances = {};for (const entry of scriptData) {;utterances[entry.intent] = entry.sentences;};module.exports = { scriptBuffer:{utterances} };"
}
}
Basic example
const utterances = {}
for (const entry of scriptData) {
utterances[entry.intent] = entry.sentences
}
module.exports = { scriptBuffer: { utterances } }
scriptData is a predefined variable with the contents of the file. It is string, or JSON, depending on file format.
Set module.exports variable with the compiled contents. You can use two fields if you want to process the current file:
scriptBuffer with the compiled content (text or json). Falsy value means, precompiler does not want to change anything.
filename with this field you can change filename, and extension.
Or put the compiled contents direct into result field:
module.exports = { utterances }
Filtering by filename
if (filename.endsWith('.json')) {
module.exports = ...
}
filename is a predefined variable. If you dont process the content, simply dont set module.exports field.
Filtering by content
if (scriptData.utterances) {
const utterances = {}
for (const entry of scriptData.utterances) {
utterances[entry.intent] = entry.sentences
}
module.exports = ...
}
Change file extension
Lets suppose we have a json in a text file. And its format is different as Botium standard JSON format. So we have to change the content, and the extension too:
const utterances = {}
// creating utterances from scriptData
module.exports = { scriptBuffer:{utterances}, filename: filename + ".json" }