# wa-chat-server

Chat server based on the Watson Assistant API.

## Configuration

Generally, we need to enter these environment variables to run an assistant:
* `master_id` – Master chatbot id.
* `master_apikey` – Master chatbot apikey.
* `master_url` – Assistant URL.
* `master_timeout_ms` – (optional) Timeout period in MS for calling chatbot.

In order to ***enable saving history*** of conversation, we have to set
* `history_enabled` – Enable history

The behaviour of conversation restart is controlled by

* `soft_restart`

On conversation restart the client sends the text input `reset`. With `soft_restart === 'true'`
Watson is called with `options.restart = true` and `reset` is sent as a text input. Otherwise
a new Watson session is created (the default option).

For ***swagger documentation***, we have to set. Swagger documentation is located on ***URL/apidoc***
* `apidoc_enabled` - Enable documentation

For a ***multiskill bot***, we have to set
* `routing_enabled` – Enable routing.

and available child bots credentials
* `childNUMBER_alias ` – Assistant alias. NUMBER can be actually any string alias, but we recommend to use a chatbot order.
* `childNUMBER_id ` – Assistant id.

An example of such configuration could be

```
## Master assistant
master_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
master_environment_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
master_apikey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
master_url = https://api.eu-de.assistant.watson.cloud.ibm.com/instances/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# Child1 assistant
child1_alias = 'Child1'
child1_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
child1_environment_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# Child2 assistant
child2_alias = 'Child2'
child2_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
child2_environment_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# History enabled
history_enabled = true

# Routing enabled
routing_enabled = true
```

`{assistant}_environment_id` - when using *classic experience*, use **Assistant ID** as both `_id` and `_environment_id`. When using *new experience*, retrieve enviroment ID by opening **Environments** from left menu, open Settings (⚙️ icon) next to the environment name (e.g. Draft Environment), use **Environment ID** as bot `_id` and `_environment_id`.

Here are some optional configurations:

* `client_data_max_size_in_bytes` - Set this property to a positive value if you would like
to map data from the property `client` of the `.../message` API to the Watson context (property
`client`). If the configured data size is exceeded then a warning is logged and no client data
are mapped to the context.

* `json_raw_body` - Set this property to `true` to enable saving raw request body before parsing it
to JSON. Generally used to validate request sender by comparing HMAC signature in adapters.
Enabling this option will result in larger request size so consider using this feature only when required.
Buffer containing the raw request body will be passed in `rawBody` attribute of the request.

Alternative authentication configurations:

**IBM Cloud Pak For Data (CP4D)** - If the Watson Assistant service is provided on-premise instead of IBM Cloud,
there is an alternative authorization scheme using different set of credentials. Providing `token_service_url`
will force initialization of CP4D authorization instead of IAM authorization. In this case the value
`master_apikey` is not required.

- `token_service_url` - URL for the authorization endpoint that provides tokens. In standard CP4D installation
  it should be `https://{cpd_cluster_host}{:port}/icp4d-api/v1/authorize`.
- `token_service_username` - Username that is used for generating the token.
- `token_service_password` - Password that is used for generating the token. Not needed if `token_service_apikey`
  is provided.
- `token_service_apikey` - Apikey that is used for generating the token. When using apikey instead of password,
  `token_service_username` is still required - the apikey is generated for specific user. Not needed if
  `token_service_password` is provided.

### Adapter Configuration

If there are some wa-chat-server adapters used in the deployment of the bot,
the adapter configuration is placed on the same place as the wa-chat-server
configuration (e. g. `.env`). The adapter specific directives are prefixed with
`adapter__[ADAPTER_NAME]__` (for example `adapter__microsoft__appId`).

## LogDNA Logging

In order to use the LogDNA API for logging we need to set the following environment variables:

* `logdna_key` – Ingestion key for LogDNA.
* `logdna_url` – URL of the LogDNA API (ingestion endpoint, e. g. https://logs.eu-de.logging.cloud.ibm.com/logs/ingest).
* `logdna_app` – Name of the application (optional).
* `logdna_app_hostname` – Hostname of the application (optional).
* `logdna_log_level` – The log level (`error`, `info`, `warn` and `debug`). The default value is `error`.

If we configure LogDNA on local development instance (determined by the presence/absence of the `VCAP_APP_PORT` env. variable) then logs will be send to LogDNA as well as to the JavaScript console.

## Shared Context
Context variables 
```
$shared-PARAM
```
are shared with the whole router, which can thus affect its behaviour. This method populates the parameters in a *non-routing* way, i.e. there is no necessity for switching the dialog flow through the various chatbots. 

For sharing parameters during routing, see attribute `params` in [Routing from a master chatbot](#Routing-from-a-master-chatbot). 

## Routing

Routing allows us to pass the ongoing conversation from one chatbot to another. These are then distinguish into the master and child chatbots. Master chatbot may generally route to any child chatbot while the child chatbots may route only to the master, where is then decided what to do next. 

The routing is determined by a context variable of a specific format, see [Routing from a master chatbot](#Routing-from-a-master-chatbot) and [Routing from a child chatbot](#Routing-from-a-child-chatbot).

### Routing from a master chatbot
The target context variable for routing has to be set to
```
$route-target = TARGET_CHATBOT_ALIAS
```
where `TARGET_CHATBOT_ALIAS` is an alias for the chatbot, defined in the application configuration. 

There are some optional attributes that may be added to `$route`:

Attribute | Description
--- | --- 
`$route-intent` | A name of a forced intent (always starting with the character #). 
`$route-utterance` | A forced utterance whose value is a context variable. If not specified, the assistant sends the user's last utterance.
`$route-params` | An object of extra parameters that will be set using `$route-params-PARAM1`, `$route-params-PARAM2` and temporarily stored for the target chatbot context as `$incoming_route-params-PARAM1`, `$incoming_route-params-PARAM2`, etc. For a permanent action, we should use `$shared` instead, see [Shared Context](#shared-context) for more details.


In order to determine the caller assistant, the integration provides
```
$incoming_route-origin
```
as a context variable  for a master chatbot .



### Routing from a child chatbot
We don't specify the target as the child chatbot always route to the master. Therefore the context variable is just set to
```
$route-target = [MASTER]
```

Similarly, as for the routing from master to child chatbot (see [Routing from a master chatbot](#Routing-from-a-master-chatbot)), there are the optional attributes `intent` and `utterance` as well.
