# CONVA Plus

By now you must have configured and published your Assistant via the Slang Console and also maybe customized it as required. Congratulations! :) If you have not already done that, you can do so by following the instructions [here](https://docs.conva.ai/slang/getting-started/integrating-slang-retail-assistant/setting-up-the-assistant).

Let's start coding!

{% hint style="warning" %}
For testing, we recommend using a physical Android device instead of an emulator because most emulators don't work well with microphones.&#x20;
{% endhint %}

## 1. Configure the build system

The first step is to update the app's build system to include Slang's Retail Assistant SDK.&#x20;

{% tabs %}
{% tab title="Android Native" %}

### Add the Slang dependency to your Gradle files

Add the path to the Slang maven repository to your top-level Gradle file

```
# Add this to your top level Gradle file

allprojects {  
    repositories {    
        …    
        maven { url "http://maven.slanglabs.in:8080/artifactory/gradle-release" }  
    }
}
```

Add the Slang Retails Assistant dependency to your app's Gradle file

```
# Add this to your app's Gradle file

dependencies {  
    …   
    implementation 'in.slanglabs.assistants:slang-retail-assistant:5.0.5'
}
```

{% endtab %}

{% tab title="React Native" %}

### Install the Slang Retail Assistant package

The next step is to install the required packages inside your code repo

#### yarn setup

If you use yarn for install packages, run the below command

```
yarn add @slanglabs/slang-conva-react-native-retail-assistant 
```

{% hint style="warning" %}
The default package is built and packaged with androidx framework, if your app does not support androidx, please use the below
{% endhint %}

```
yarn add @slanglabs/slang-conva-react-native-retail-assistant@non-androidx 
```

#### npm setup

If you use npm for managing your packages, run the below command&#x20;

```bash
npm install @slanglabs/slang-conva-react-native-retail-assistant --save
```

Because Slang uses native libraries, you need to link the package to your codebase to run the automatic linking steps

```
react-native link @slanglabs/slang-conva-react-native-retail-assistant
```

Finally, add the path to the Slang maven repository (to download native library dependencies) to your top-level gradle file

```
# Add this to your top level gradle file

allprojects {  
    repositories {    
        …    
        maven { url "http://maven.slanglabs.in:8080/artifactory/gradle-release" }  
    }
}
```

{% endtab %}

{% tab title="Flutter" %}

### Install the Slang Retail Assistant package

Run the below command to install the required packages inside your code repo.

```
 $ flutter pub add slang_retail_assistant
```

Once done, run the command '`dart pub get`' and ensure Slang assistant is added to the dependencies.

```

dependencies:
  slang_retail_assistant: ^8.0.0
```

#### Next is to import Slang Retail Assistant in your dart code.

```
import 'package:slang_retail_assistant/slang_retail_assistant.dart';
```

{% endtab %}

{% tab title="Web" %}

## **Using Slang Retail Assistant Package**

You can add our NPM package to your project using any of your preferred package manager -&#x20;

**yarn**

```sh
$ yarn add @slanglabs/slang-retail-assistant@8.6.0
```

**npm**

```bash
$ npm install @slanglabs/slang-retail-assistant@8.6.0 --save
```

If you are build a simple HTML project, you can still use our SDK using the script below -&#x20;

```html
<script type="text/javascript" src="https://unpkg.com/@slanglabs/slang-retail-assistant@8.6.0/index-iife.js" defer></script>
```

{% endtab %}
{% endtabs %}

## 2. Code integration

### 2.1 Initialization

The next step is to initialize the SDK with the [keys](https://docs.conva.ai/slang/getting-started/setting-up-the-assistant#adding-a-new-assistant) you obtained after creating the Assistant in the Slang console.&#x20;

{% tabs %}
{% tab title="Android Native" %}
The recommendation is to perform the initialization in the `onCreate` method of the `Application` class. If the app does not use an `Application` class, the next best place would be the `onCreate` method of the primary `Activity` class.

```java
// Your application class 

protected void onCreate(Bundle savedInstance) {  
    ...
    AssistantConfiguration configuration = new AssistantConfiguration.Builder()    
        .setAPIKey(<API Key>)    
        .setAssistantId(<AssistantId>)
        .setEnvironment(STAGING)  // Change this to PRODUCTION once you've published the Assistant to production environment    
        .build();  
    SlangRetailAssistant.initialize(this, configuration);
}
```

{% endtab %}

{% tab title="React Native" %}
This should ideally be done in the componentDidMount of your main app component

```javascript
import SlangRetailAssistant from '@slanglabs/slang-conva-react-native-retail-assistant';

SlangRetailAssistant.initialize({
    requestedLocales: ['en-IN', 'hi-IN'], // The languages to enable
    assistantId: '<assistant id>',        // The Assistant ID from the console
    apiKey: '<API Key>',                  // The API key from the console
})
```

{% endtab %}

{% tab title="Flutter" %}
This should ideally be done inside the main method.

```dart
import 'package:slang_retail_assistant/slang_retail_assistant.dart';

var assistantConfig = new AssistantConfiguration()
 ..assistantId = "<AssistantId>"
 ..apiKey = "<APIKey>"
 ..requestedLocales = ['en-IN', 'hi-IN'];

SlangRetailAssistant.initialize(assistantConfig);
```

{% endtab %}

{% tab title="Web" %}
If you're using async/await, then -

```javascript
import SlangRetailAssistant from '@slanglabs/slang-retail-assistant';

await SlangRetailAssistant.init({
    assistantID: '<assistant id>',        // The Assistant ID from the console
    apiKey: '<API Key>',                  // The API key from the console
})
```

If you use Promise callback, then -

```javascript
import SlangRetailAssistant from '@slanglabs/slang-retail-assistant';

SlangRetailAssistant.init({
    assistantID: '<assistant id>',        // The Assistant ID from the console
    apiKey: '<API Key>',                  // The API key from the console
}).then(() => {
    // other integration code...
})
```

{% hint style="info" %}
If you are using a framework like React, we recommend putting this code inside a `useEffect` block. \
\
If you are building a simple HTML project, then put this code inside an `document.addEventListener('DOMContentLoaded', () => {})` event listener.
{% endhint %}
{% endtab %}
{% endtabs %}

### 2.2 Show the Assistant Trigger (microphone icon)

Once the Assistant is initialized, the next step is to show the Assistant Trigger (ie the microphone button) that the app's users can click on to invoke the Assistant and speak to it.

{% tabs %}
{% tab title="Android Native" %}
Add the below line to the `onResume` method of the Activities where you want the Assistant to be enabled.

```java
protected void onResume(Bundle savedInstance) {  
    ... 
    SlangRetailAssistant.getUI().showTrigger(this); // There is a corresponding hideTrigger too if needed
}
```

{% endtab %}

{% tab title="React Native" %}
One can call "show" and "hide" methods as required to control the visibility of the Assistant

```javascript
SlangRetailAssistant.ui.showTrigger(); // There is a corresponding hideTrigger too if needed
```

{% endtab %}

{% tab title="Flutter" %}
Use "showTrigger" and "hideTrigger" APIs to control the visibility of the Assistant as shown below.

```javascript
SlangRetailAssistant.getUI().showTrigger();
SlangRetailAssistant.getUI().hideTrigger();
```

{% endtab %}

{% tab title="Web" %}
One can call "show" and "hide" methods as required to control the visibility of the Assistant

```javascript
SlangRetailAssistant.getUI().showTrigger(); // There is a corresponding hide too if needed
```

{% endtab %}
{% endtabs %}

By default, the trigger is sticky, which means that it will show up on all Activities after it is made visible. To prevent the trigger from showing up on specific activities, you will need to call:&#x20;

```
     SlangRetailAssistant.getUI().hideTrigger(this)
```

{% hint style="info" %}
Note that there are two types of Assistant Icons. Global and Inline. Refer to this [page](https://docs.conva.ai/slang/advanced-topics/customizing-the-assistant/customizing-the-visual-nature-of-the-assistant#slang-trigger) for more details and how to make use of it in your app. The default is the "Global" Assistant Icon
{% endhint %}

### 2.3 Implement Actions

{% hint style="info" %}
**Refresher:** A `UserJourney` represents a path that a user may take to reach their goal when using a web or mobile app. See [Voice Assistant Concepts](https://docs.conva.ai/slang/user-journey-and-app-states#user-journey) for details.
{% endhint %}

{% hint style="info" %}
Refresher: The Actions for the various User Journeys can also be specified directly in the console. Refer to the ["Define Actions for various User Journeys"](https://docs.conva.ai/slang/getting-started/customizing-the-assistant#define-actions-for-various-user-journeys) section for details
{% endhint %}

Now if the actions (basically the visual change that the app should do) corresponding to the various User Journeys have not been already defined in the console, the app needs to do that via code and implement the Actions associated with the various User Journeys supported by the Assistant. This can be done as shown below

{% tabs %}
{% tab title="Android Native" %}

```
SlangRetailAssistant.setAppAction(new SlangRetailAssistant.AppAction() {
    @Override
    public SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {        
        // Handle search requests
        // ...

        return new SearchResultsAppState(OrderViewAppState.SUCCESS);
    }
   
    public OrderManagementAppState onOrderManagement(OrderInfo orderInfo, OrderManagementUserJourney orderourney) {        
        // Handle order management requests
        // ...
        
        return new OrderViewAppState(OrderViewAppState.SUCCESS);
    }
    
    public OfferAppState onOfferManagement(OfferInfo offerInfo, OfferManagementUserJourney offerManagementUserJourney) {
        // Handle offers requests
        // ...
        
        return new ViewOfferAppState(ViewOfferAppState.SUCCESS);
    }  
    
    public CheckoutAppState onCheckOut(CheckoutInfo checkoutInfo, CheckoutUserJourney checkoutUserJourney) {
        // Handle checkout requests
        // ...
        
        return new CheckoutCompleteAppState(CheckoutCompleteAppState.SUCCESS);
    }
    
    public NavigationAppState onNavigation(NavigationInfo navInfo, NavigationUserJourney navJourney) {        
        // Handle navigation requests
        // ...
        
        return new NavigationCompleteAppState(SUCCESS);
    }
        
    @Override
    public void onAssistantError(final AssistantError error) {
        // Handle errors that might have occurred during the Assistant lifecycle
        
        // Error codes available 
        // FATAL_ERROR, SYSTEM_ERROR, ASSISTANT_DISABLED, INVALID_CREDENTIALS, 
    }
}
```

{% endtab %}

{% tab title="React Native" %}

```
const actionHandler = {
  onSearch: (searchInfo, searchUserJourney) => {
    // Handle the search request    
    // ...
    
    searchUserJourney.setSuccess();
    return SearchUserJourney.AppState.SEARCH_RESULTS;
  },

  onOrderManagement: (orderInfo, orderManagementUserJourney) => {
    // Handle the order request    
    // ...
    
    orderManagementUserJourney.setViewSuccess();
    return OrderManagementUserJourney.AppState.VIEW_ORDER;
  },

  onNavigation: (navigationInfo, navigationUserJourney) => {
    // Handle the navigation request    
    // ...
    
    navigationUserJourney.setNavigationSuccess();
    return NavigationUserJourney.AppState.NAVIGATION;
  },

  onAssistantError: errorCode => {
    // Handle errors that might have happened during the processing of the
    // Assistant
    
    // Error codes available 
    // FATAL_ERROR, SYSTEM_ERROR, ASSISTANT_DISABLED, INVALID_CREDENTIALS,    
  },
};

SlangRetailAssistant.setAction(retailAssistantListener)
```

{% endtab %}

{% tab title="Flutter" %}

```
//Set the action handler via the setAction method
class AppAction implements RetailAssistantAction {

  @override
  void initState() {
    super.initState();
    SlangRetailAssistant.setAction(this);
  }

  @override
  void onAssistantError(Map<String, String> assistantError) {
    // Handle errors that might have occurred during the Assistant lifecycle
  }

  @override
  SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney searchUserJourney) {
    // Handle search requests
    // ...
    return new SearchResultAppState(SUCCESS)
  }
}

var action = new AppAction();
SlangRetailAssistant.setAction(action);

```

{% endtab %}

{% tab title="Web" %}

```javascript
const actionHandler = {
  onSearch: (searchInfo, searchUserJourney) => {
    // Handle the search request    
    // ...
    
    searchUserJourney.setSuccess();
    return SearchUserJourney.AppStates.SEARCH_RESULTS;
  },

  onManageOrder: (orderInfo, orderManagementUserJourney) => {
    // Handle the order request    
    // ...
    
    orderManagementUserJourney.setViewSuccess();    
    return OrderManagementUserJourney.AppStates.VIEW_ORDER;
  },

  onNavigation: (navigationInfo, navigationUserJourney) => {
    // Handle the navigation request    
    // ...
    
    navigationUserJourney.setNavigationSuccess();    
    return NavigationUserJourney.AppStates.NAVIGATION;
  },

};

SlangRetailAssistant.setAction(retailAssistantListener)
```

{% endtab %}

{% tab title="Android (Deprecated)" %}

```java
SlangRetailAssistant.setAction(new SlangRetailAssistant.Action() {
    @Override
    public SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {        
        // Handle search requests
        // ...
        
        userJourney.setSuccess();
        return SearchUserJourney.AppState.SEARCH_RESULTS;
    }
    
    public NavigationUserJourney.AppState onNavigation(NavigationInfo navInfo, NavigationUserJourney navJourney) {        
        // Handle navigation requests
        // ...
        
        userJourney.setNavigationSuccess();
        return NavigationUserJourney.AppState.NAVIGATION;
    }
    
    public OrderManagementUserJourney.AppState onOrderManagement(OrderInfo orderInfo, OrderManagementUserJourney orderourney) {        
        // Handle order management requests
        // ...
        
        userJourney.setViewSuccess();        
        return OrderManagementUserJourney.AppState.VIEW_ORDER
    }
    
    @Override
    public void onAssistantError(final AssistantError error) {
        // Handle errors that might have occurred during the Assistant lifecycle
        
        // Error codes available 
        // FATAL_ERROR, SYSTEM_ERROR, ASSISTANT_DISABLED, INVALID_CREDENTIALS, 
    }
}
```

{% endtab %}
{% endtabs %}

The following user journeys are currently supported by the Slang Retail Assistant:

* Voice Search&#x20;
* Voice Order Management
* Voice Offers
* Voice Checkout
* Voice Navigation

{% hint style="info" %}
Backward compatibility note: Earlier offers and checkout were targets inside Navigation Journey. Now they have become their own full-blown user journeys
{% endhint %}

The Action Handler interface has an explicit callback for each of the supported user journeys. Whenever the Assistant detects the user's journey (based on what they spoke), it invokes the callback associated with that user journey.&#x20;

When these callbacks are invoked, the Assistant also passes the parametric data corresponding to the user journey that the Assistant was able to gather. The app is then expected to:&#x20;

1. Consume the parametric data as needed
2. Optionally launch appropriate UI actions
3. Set appropriate conditions in the Assistant based on the app's internal state
4. Return the `AppState` that the app transitioned to

### 2.4 Return the `AppState` and `Condition`

{% hint style="info" %}
**Refresher:** An `AppState` typically corresponds to a screen that the app transitioned to based on user input. See [Voice Assistant Concepts](https://docs.conva.ai/slang/user-journey-and-app-states#app-states) for details.
{% endhint %}

An `AppState` indicates which state the app transitioned to, based on the user-journey and parametric data that was passed to the app. The list of`AppState`s that are supported depends on the user journey.&#x20;

Conditions represent more detailed states of the app within a particular app state. For example, the search might have failed when performing the search or the items might be out of stock. The app can use Conditions to indicate the correct condition to the Assistant. The condition controls the message that the Assistant speaks up after the call-back returns.

{% tabs %}
{% tab title="Android Native" %}

```
public SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {        
   // Handle the Search requests
   // ...
   
   return new SearchResultsAppState(SUCCESS);
}
```

{% endtab %}

{% tab title="React Native" %}

```
onSearch: async (searchInfo, searchUserJourney) => {
    // Handle the search request    
    // ...
    searchUserJourney.setSearchSuccess();
    return SearchUserJourney.AppState.SEARCH_RESULTS;
}
```

{% endtab %}

{% tab title="Flutter" %}

```
@override
SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney searchUserJourney) {
    // Handle search requests
    // ...
    return new SearchResultAppState(SUCCESS)
}
```

{% endtab %}

{% tab title="Web" %}

```
onSearch: async (searchInfo, searchUserJourney) => {
    // Handle the search request    
    // ...
    searchUserJourney.setSuccess();
    return SearchUserJourney.AppStates.SEARCH_RESULTS;
}
```

{% endtab %}

{% tab title="Android (Deprecated)" %}

```
public SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {        
   // Handle the Search requests
   // ...
   searchUserJourney.setSearchSuccess(); // Set the condition
   return SearchUserJourney.AppState.SEARCH_RESULTS;
}
```

{% endtab %}
{% endtabs %}

#### 2.4.1 Assistant Prompts

Based on the `AppState` returned and the conditions that were set, the Assistant will speak out an appropriate message to the user.&#x20;

{% hint style="info" %}
The prompts spoken by the Assistant are customizable. Refer to the [Customizing the Assistant](https://docs.conva.ai/slang/getting-started/integrating-slang-retail-assistant/code-integration-basic-steps/broken-reference) section, if you're interested in customization.
{% endhint %}

That's it! These are the basic set of steps required to add Slang's In-App Voice Assistant into your app.&#x20;

Beyond this integration, Slang Voice Assistants provide a lot more power and flexibility to cater to the more advanced needs of the apps. Please refer to the [Advanced Concepts](https://docs.conva.ai/slang/getting-started/integrating-slang-retail-assistant/code-integration-basic-steps/broken-reference) section for more details.

####
