# Wingbot.ai - web chat component

Frontend React web chat component is supposed to be used within the wingbot.ai infrastructure.

## Architecture overview

```
                       |‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|
|‾‾‾‾‾‾‾‾‾‾‾‾|         |           chatbot infrastructure         |
| host page  |         |             (AWS/Azure/Docker)           |
|            |         |                                          |
| |‾‾‾‾‾‾‾‾| |         | |‾‾‾‾‾‾‾‾‾‾‾‾‾‾|         |‾‾‾‾‾‾‾‾‾‾‾‾‾| |
| |  chat  |-|- https -|-|  wingbot.ai  |         | chatbot app | |
| | widget |-|-- wss --|-|  Messaging   |- https -|    with     | |
| |________| |         | | Orchestrator |         | wingbot lib | |
|____________|         | |______________|         |_____________| |
  users web            |         |                       |        |
   browser             | |‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾| |
                       | |            MongoDB database          | |
                       | |______________________________________| |
                       |__________________________________________|
```

#### Chat/Orchestrator security options

Above the all low-level security options like firewalls, WAFs and on,
the chat itself provides **additional security features**

- web page whitelisting (XHR Referrer)
- IP whitelisting
- Session bound conversation (when user signs-out, the conversation is removed)
- OAuth/OpenID/SAML authentication (XHR, background i-frame, redirect)


## How to connect Wingbot Webchat to any website

The chat widget can be deployed by following methods:

- React component
- Append to HTML element
- CDN Hosted - HTML snippet method

### React component

UI component within a JSX component

```jsx

import { WingbotChat } from 'wingbot-chat-ui';

export default function MyChatComponent (props) {

    return (
        <WingbotChat
            pageId="<put your page-id here>"
            contextUserAgentProp="ua"
            contextScreenResolutionProp="sr"
        />
    );
}
```

**SCSS style**

Include following CSS style for deploying a default chat style

```scss
$ff: BlinkMacSystemFont, -apple-system, "Segoe UI", Rubik, Helvetica, Arial, sans-serif;

@use '~wingbot-chat-ui/scss/fontRubik' with (
    $wb-font-path: '~wingbot-chat-ui/scss/fonts'
);
@use '~wingbot-chat-ui/scss/general' with (
    $chat-font-family: $ff,
    $chat-square-btn: true
);

```

### Append to HTML element

Just in case if your project is not built on React

```javascript
import 'regenerator-runtime/runtime';
import { createWingbotChat } from 'wingbot-chat-ui';

const wingbotChat = createWingbotChat();

// replace with an immutable DIV element
const element = document.getElementById('chat');

wingbotChat('init', {
    pageId: '<put your page-id here>',
    contextUserAgentProp: 'ua',
    contextScreenResolutionProp: 'sr'
}, element);

```

### CDN Hosted - HTML snippet method

On the example below you can see the minimal setup for connecting the Wingbot webchat to a website.

```html
<link href="https://orchestrator.wingbot.ai/styles/wingbotChat.css" rel='stylesheet' type='text/css'>
<div id="chat"></div>
<script>
    window.wingbotChatCmds=window.wingbotChatCmds||[];
    window.wingbotChat=window.wingbotChat||function(){wingbotChatCmds.push(arguments)}

    wingbotChat('init', {
        pageId: '<put your page-id here>',
        contextUserAgentProp: 'ua',
		contextScreenResolutionProp: 'sr'
    }, document.getElementById('chat'));
</script>
<script async src="https://orchestrator.wingbot.ai/wingbotChat.js"></script>
```

#### We can split this example code to the 4 main parts:

- **CSS styles**
    - link with the basic webchat theme, working out of the box
    - feel free to create your own and replace it
- **Physical representation**
    - `<div id="chat"></div>` is physical representation of the webchat
    - it can be placed anywhere in your website
- **Webchat configuration**
    - this part is mostly for configuration the webchat configuration
    - `pageId` is mandatory and unique, if you don't know your `pageId` feel free to contact Wingbot support
    - `document.getElementById` can be set to any existing element in the website
- **Source to the webchat code**
    - the last line of the example is link to the actual webchat app
    - please do not download it and/or cache it somewhere in your infrastructure if you want to have the latest and the most secure version of Wingbot webchat


## Dig more deeply into the configuration

As we saw in the example above, webchat is configurable with 3 parameters.

Lets have a look little bit deeply about the configuration right now:

### Webchat commands and parameters:


```javascript
webchat (
    'init',    // `'init'` command should be always called to start a chat
    element,   // DOM element which is representation of the chat on the page
    config     // object with webchat configurations
);

```

There are supported parameters for the config object:


| Parameter |  Default value | Description | Example |
|:-----------|------------|-------------|------------|
|`disableComposer`|`false`|Disables user input - makes chat read only||
|`resetOnClose`|`false`|Starts a new conversation when reopening chat after it's close||
|`pageId`|**required**|Identifier of page|`'134271f0-1d1c-42a3-9191-6288fd1a263b'`|
|`api`|`null`|Override an API URL of orchestrator (on-premise solutions only)||
|`websocket`|`null`|Override an websocket URL of the widget (on-premise solutions only)||
|`token`|`null`|Conversation token to continue in already existing conversation||
|`refreshInterval`|`15000`|Interval in miliseconds to refresh the credentials||
|`startAction`|`start`|Postback payload to send a non-visual chat event for start the conversation||
|`lang`|`null`|Force the widget to use specified language||
|`fallbackLang`|`'en'`|Use this language if it cannot be detected automatically||
|`reduxEnhancer`|`null`|Redux plugin to be used within chat||
|`onInit`|`() => {}`|Will be called when chat has been successfuly initialized||
|`headerText`|`null`|Set a static text to be used as a header||
|`context`|`{}`|Thread context variables - will be pushed to the bot||
|`uploadEnabled`|`false`|On/off for a file upload (boolean)|
|`uploadSizeLimit`|`1048576 * 6`|Hard limit for the file upload, bigger file cannot be uploaded|
|`uploadSoftLimitForResize`|`1048576 * 2.5`|Soft limit for the file upload, bigger file will be shrunk, `0` means no shrinking|
|`contextUserAgentProp`|`null`|Context prop to store user agent|`'ua'`|
|`contextScreenResolutionProp`|`null`|Context prop to store screen resolution|`'sr'`|
|`contextLangProp`|`null`|Context prop to store chat language|`'lang'`|
|`contextPathProp`|`null`|Context prop to store window path|`'path'`|
|`oauthMode`|`'iframe'`|Method for OAUTH authentication|`'xhr' | 'iframe' | 'redirect'`|
|`homeAction`|`undefined`|If `homeAction` is `true` or `string` home button will be enabled in the chat header. If `homeAction` is `string` home button sends a postback to `homeAction`. If `homeAction` is `true` home button sends a postback to `startAction` |`true`|
|`langFromUrl`|`undefined`|If `langFromUrl` is `true` language will be set based on url query parameter `lang`. If `langFromUrl` is `string` language will be set to `langFromUrl`|`true`|
|`startAnimationSequence`|💬😉|Default animation sequence of the button
|`hoverAnimationSequence`|👋😊|Hover animation sequence of the button
|`loadingAnimationSequence`|😴🍳🤗💅👔|Hover animation sequence of the button
|`onlineAnimationSequence`|`<svg>`|Hover animation sequence of the button
|`offlineAnimationSequence`|`<svg>`|Hover animation sequence of the button
|`persistentMenu`|`null`|Menu of the chat widget provided as a structure below

**Animation sequence**

list of animation frames with transitions

`{i: string|ReactElement,animate?:string,timeout?:number}[]`

- `i` - string (emoji) or react element
- `animate` - name of transition effect from (animate.style)[https://animate.style]
- `timeout` - time in ms (default: 2000)

```jsx
onlineAnimationSequence: [
    {
        i: (
            <svg width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M0 11.5C0 5.14873 5.14873 0 11.5 0V0C17.8513 0 23 5.14873 23 11.5V23H11.5C5.14873 23 0 17.8513 0 11.5V11.5Z" fill="#1FFFB4" />
            </svg>
        )
    }
]
```

**Persistent menu**

```javascript
persistentMenu: [
    {
        locale: 'default',
        call_to_actions: [
            {
                type: 'postback',
                title: 'Button Title',
                payload: 'address'
            }
        ]
    }
]
```


## Development

Because the frontend is in a separate repository, you must first link the frontend to the backend during development, and then run auto build.

Linking can be done via the utility link: https://docs.npmjs.com/cli/link, like this:

```
cd ~/<local_repo_path>/wingbot-chat-ui
npm link
cd ~/<local_repo_path>/wingbot-ai-orchestrator
npm link wingbot-chat-ui
```

Also, to have working React hooks, you need to link React library from chat to orchestrator
```
cd ~/<local_repo_path>/wingbot-chat-ui
npm link <orchestrator_path>/node_modules/react
```

Next, you need to run the command in the root of the wingbot-chat-ui project:

```
npm run develop
```

Furthermore, it is normally possible to continue the webchat project with the command:

```
npm run start
```
