## Android
# Migration Guide
Version 1.x had an issue where a corrupted ymAuthentication token was passed in some cases from SDK to the server. The conversation history was thus mapped to the corrupted ymAuthenticationToken
Version 2.x has fix for this issue and thus a correct ymAuthenticationToken is always passed.
However, as the correct ymAuthentication is different from the corrupted token, our server treats this user as a new user which leads to a complete loss of history of user conversations.
The user will have a fresh start after updating the app.
Note:
1. ymAuthentication was corrupted only when it contained `=` character in 1.x versions
2. This issue was happening only on Android platform.
For more info feel free to email us at mobile@yellow.ai
## Installation
### Gradle
To integrate YMChat into your Android project using gradle, specify the following configurations in App level `build.gradle` file
```gradle
repositories {
jcenter()
// Add these two lines
maven { url "https://jitpack.io" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
...
...
...
dependencies {
...
...
implementation 'com.github.yellowmessenger:YMChatbot-Android:2.2.+
}
```
Note: By puting + at the end, you need not to worry about updating and releaseing your app for every patch we are making in SDK.
Still, if you want to use exact and latest version please visit the github repository mentioned
[https://github.com/yellowmessenger/YMChatbot-Android/releases](https://github.com/yellowmessenger/YMChatbot-Android/releases)
### File provider
:::note
The following key in your strings.xml file is only required for version v1.4.0 to v2.5.0. Starting from version v2.5.0, it is no longer necessary to add this key.
:::
Add following key in your `strings.xml` file, this will override default file provider used by SDK.
Overriding the file provider path will avoid conflict with other app using YM CHATBOT SDK. You can use your application id and suffix it with ".fileprovider"
Example - applicationId : "com.abc.xyz" then application_id_for_provider = com.abc.xyz.fileprovider
```xml
<string name="application_id_for_provider">your.application.id.fileprovider</string>
```
## Basic Usage
Import the YMChat library in your Activity.
```java
import com.yellowmessenger.ymchat.YMChat;
import com.yellowmessenger.ymchat.YMConfig;
```
After the library is imported the basic bot can be presented with few lines as below
Example `onCreate` method of the Activity:
```java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Dummy bot id. (Purrs a lot)
String botID = "x1587041004122";
//Get YMChat instance
YMChat ymChat = YMChat.getInstance();
ymChat.config = new YMConfig(botId);
setContentView(R.layout.activity_main);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(view -> {
//Starting the bot activity
try {
ymChat.startChatbot(this);
} catch (Exception e) {
//Catch and handle the exception
e.printStackTrace();
}
});
}
```
## YMConfig
YMConfig can be used to set the bot id and other bot related settings. It is recommended to set all appropriate config **before** starting the bot
### Initialize YMConfig
YMConfig requires `botID` to initialize. All other settings are optional.
```java
ymChat.config = new YMConfig("<BOT-ID>");
```
### YM AuthenticationToken
ymAuthenticationToken is used to associate an identity of the user with the chat bot. This token is unique and remains constant for each individual user, and should be kept secure.
Whenever chatbot is launched with ymAuthenticationToken it will load the previous chats associated with this user since **inception**.
```java
ymChat.config.ymAuthenticationToken = "your-token"
```
:::note
History will load only when `Show history` flag is enabled in the channel settings.
:::
### Push Notifications
YMChat supports firebase notifications. Assign your `FCM token` to deviceToken
```java
ymChat.config.deviceToken = "your-firebase-device-token"
```
:::note Mapping Firebase service key against Bot Id
Firebase service account Json file is required to send notifications. You need to map service account json file against your bot ID. Request your contact person from `yellow.ai` to share api for same. For more information about Firebase service account json file and how to get it check link [here](https://developers.google.com/assistant/engagement/notifications#get_a_service_account_key)
:::
### Payload
Additional information can be passed in the form of key value pair from app to bot using payload.
```java
HashMap<String, Object> payloadData = new HashMap<>();
//Setting Payload Data
payloadData.put("some-key", "some-value");
ymChat.config.payload = payloadData;
```
Payload can be used to pass information from host app to bot. The payload dictionary should be JSON compatible else an error will be thrown
For passing data from bot to app refer bot [Bot Events](#bot-events)
:::note payload security
Payload is securely passed in HTTPS post request to protect the information passed in it
:::
#### Trigger journey
A specific journey can be triggered on launch, by passing the slug in the payload.
```java
HashMap<String, Object> payloadData = new HashMap<>();
//Setting Payload Data
payloadData.put("JourneySlug", "checkout-cart");
ymChat.config.payload = payloadData;
```
### On Premise / Region Specific deployments
Your on-prem deployment URL can be set to `customBaseUrl`
```java
ymChat.config.customBaseUrl = "https://yourcustomurl.com";
```
If the bot is deployed in a specific region (Example: r1,r2,r3..rn) on yellow.ai cloud, set the `customBaseUrl` as follows
```java
ymChat.config.customBaseUrl = "https://rx.cloud.yellow.ai";
```
Here rx = r1,r2,r3,r4,r5 etc.
### Custom loader
You can customize the loading image while bot loads. Just pass the URL in the following way. It is recommended to use jpg, png, svg or gif
```java
ymChat.config.customLoaderUrl = "https://example.com/your/custom/image.gif"
```
### V2 bot
You can enable V2 bot by setting the version in config. Default value is 1
```java
ymChat.config.version = 2;
```
### Speech to Text
#### Enable Speech to Text
Speech to text can be enabled by setting the enableSpeech flag present in config. Default value is `false`
```java
ymChat.config.enableSpeech = true
```
:::note
To enable Speech to text please add record audio permission (`<uses-permission android:name="android.permission.RECORD_AUDIO" />`) in manifest file.
:::
#### Mic Icon Color
You can change the mic button icon color by setting `fabIconColor` in `enableSpeechConfig` of YMConfig:
```java
ymChat.config.enableSpeechConfig.fabIconColor = "#000000"
```
### Mic Background Color
You can change the mic button bakground color by setting `fabBackgroundColor` in `enableSpeechConfig` of YMConfig:
```java
ymChat.config.enableSpeechConfig.fabBackgroundColor = "#0000FF"
```
### Hide Input Bar
You can hide the input bar while bot is loading by setting the disableActionsOnLoad flag present in config. Default value is `false`
```java
ymChat.config.disableActionsOnLoad = true
```
### Use Lite version
You can use lite version of the bot by setting the useLiteVersion flag present in config. Default value is `false`
```java
ymChat.config.useLiteVersion = true
```
### Colors
#### Status bar
Status bar color can be set on `statusBarColor` color variable
```java
ymChat.config.statusBarColor = R.color.red
```
or
```java
ymChat.config.statusBarColorFromHex = "#FF0000"
```
Note: if both `statusBarColor` and `statusBarColorFromHex` is used then `statusBarColorFromHex` will take priority
#### Close button
Close button color can be set on `closeButtonColor`
```java
ymChat.config.closeButtonColor = R.color.white
```
or
```java
ymChat.config.closeButtonColorHex = "#FFFFFF"
```
Note: if both `closeButtonColor` and `closeButtonColorFromHex` is used then `closeButtonColorFromHex` will take priority
## Starting the bot
Once the config is set, chat bot can be presented by calling `startChatbot()` and passing your Activity context as an argument
```java
ymChat.startChatbot(this);
```
## Get Chatbot Fragment
If clients want to use Chatbot Fragment in thier application, they can call the following method to get the fragment
```java
Fragment chatbotView = ymChat.getChatBotView(this);
```
Clients can embed this fragment in their activity and begin the transaction as they do for any other fragment.
## Bot Events
Bot events are used to pass information from bot to app. Events from bot can be handled using event Listeners. Simply define the `onSuccess` method of `onEventFromBot` listener.
```java
ymChat.onEventFromBot(botEvent -> {
switch (botEvent.getCode()) {
case "event-name": break;
}
});
```
#### Bot close event
Bot close event is separately sent and it can be handled by listening to onBotClose event as mentioned below. To programatically close bot use `ymChat.closeBot()` method
```java
ymChat.onBotClose(() -> {
Log.d("Example App", "Bot Was closed");
});
```
## Close bot
Bot can be programatically closed using `closeBot()` function
```java
ymChat.closeBot();
```
## Reload bot
To reload the bot with the same configuration, use the `reloadBot()` function. This will reload the bot without closing and reopening it.
```java
ymChat.reloadBot();
```
## Register Device
If you want to receiving push notifications without or before launching the bot, you can register your device.
To use this api `apiKey`, `botId`, `deviceToken` and `ymAuthenticationToken` are mandatory parameters.
```java
try {
YMChat ymChat = YMChat.getInstance();
//Mandatory config `botId`, `deviceToken` and `ymAuthenticationToken`
YMConfig ymConfig = new YMConfig("your bot id");
ymConfig.deviceToken = "your FCM Token";
ymConfig.ymAuthenticationToken = "your ymAuthentiction token";
// Set custom base url in case your bot does not belong to india region and yellow cloud
// Example- If your bot is in `r5` region custom base url would be `https://r5.cloud.yellow.ai
// ymConfig.customBaseUrl = "https://r5.cloud.yellow.ai";
ymChat.registerDevice(apiKey, ymConfig, new YellowCallback() {
@Override
public void success() {
Toast.makeText(MainActivity.this, "Device Registered", Toast.LENGTH_SHORT).show();
}
@Override
public void failure(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
//Catch and handle the exception
e.printStackTrace();
}
```
## Unlink Device Token
If you want to stop receiving push notifications you can unlink the device.
To use this api `apiKey`, `botId` and `deviceToken` are mandatory parameters.
Device token typically is unlinked when the user logs out of the app.
```java
try {
YMChat ymChat = YMChat.getInstance();
YMConfig ymConfig = new YMConfig("your bot id");
// Set the FCM token as device token, this is required so that it can be removed and customer stop receiving the notification
ymConfig.deviceToken = "your FCM Token";
// Set custom base url in case your bot does not belong to india region and yellow cloud
// Example- If your bot is in `r5` or EURO region custom base url would be `https://r5.cloud.yellow.ai
// ymConfig.customBaseUrl = "https://r5.cloud.yellow.ai";
ymChat.unlinkDeviceToken(apiKey, ymConfig, new YellowCallback() {
@Override
public void success() {
Toast.makeText(MainActivity.this, "Token unlinked", Toast.LENGTH_SHORT).show();
}
@Override
public void failure(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
//Catch and handle the exception
e.printStackTrace();
}
```
:::note API Key
API key can be generated/found by visiting `https://cloud.yellow.ai` -> Overview -> Configure -> API Key section
Existing client can upgrade their dependency to `v2.1.+` and replace exisitng key with new API Key.
Client using SDK version below `v2.1.0` will have no impact.
:::
## Unread Message Count
If you want to show an indicator in your app if there is any unread messages, you can achieve that by calling the given api when bot is in closed state.
Pre condition to use this api is that customer must have opened the bot at least once with `ymAuthenticationToken` otherwise you will receive an error message.
To use this api `botId` and `ymAuthenticationToken` are mandatory parameters.
```java
try {
YMChat ymChat = YMChat.getInstance();
YMConfig ymConfig = new YMConfig("your bot id");
// `ymAuthenticationToken` is required to identify the right
ymConfig.ymAuthenticationToken = "your ymAuthentiction token";
// Set custom base url in case your bot does not belong to india region and yellow cloud
// Example- If your bot is in `r5` region custom base url would be `https://r5.cloud.yellow.ai
// ymConfig.customBaseUrl = "https://r5.cloud.yellow.ai";
ymChat.getUnreadMessagesCount(ymConfig, new YellowDataCallback() {
@Override
public <T> void success(T data) {
YellowUnreadMessageResponse response = (YellowUnreadMessageResponse) data;
Toast.makeText(MainActivity.this, "Unread messages - " + response.getUnreadCount(), Toast.LENGTH_SHORT).show();
}
@Override
public void failure(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
//Catch and handle the exception
e.printStackTrace();
}
```
## Dependencies
Following dependencies are used in chat bot SDK
```java
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'com.squareup.okhttp3:okhttp:4.7.2'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'androidx.multidex:multidex:2.0.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
```
## Permissions
We are declaring and asking for following permission in our manifest file
```java
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```
All permissions will be asked at run time except INTERNET.
For attachment (picking file/images from phone storage)
```java
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```
### Conditional Permission
#### Record Audio
If you want to use Speech to text feature please add following permission in your manifest
```java
<uses-permission android:name="android.permission.RECORD_AUDIO" />
```
#### Location
If your bot requires Location permission please add following permission in your manifest
```java
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
```
## Important
If facing problem in release build, add the following configuration in the app's proguard-rules.pro file.
```java
-keep public class com.yellowmessenger.ymchat.** {
*;
}
```
## Demo App
A demo has been created to better understand the integration of SDK in Android app
[https://github.com/yellowmessenger/YmChatBot-Android-DemoApp](https://github.com/yellowmessenger/YmChatBot-Android-DemoApp)
## FAQs
1. How to handle notifications in the foreground when the bot is closed?
Use the following code snippet to handle the notifications you receive when the app is open in the foreground.
```js
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService: FirebaseMessagingService() {
final
var TAG: String = "YMLog"
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.i(TAG + " Remote message", remoteMessage.toString())
Log.i(TAG + " Remote message", remoteMessage.data.toString())
super.onMessageReceived(remoteMessage)
}
}
```
:::info
For more details regarding the integration, see
* [Android SDK documentation](https://docs.yellow.ai/docs/platform_concepts/mobile/chatbot/android).
* [Test app with Android SDK and Firebase integration](https://github.com/yellowmessenger/YmChatBot-Android-DemoApp)
:::
2. How to trigger a specific bot flow when the user clicks on the notification?
Use the following code snippet to open the bot and trigger a specific bot flow when the user clicks on the notification.
```js
if (payloadData.get("botId") != null) {
String botId = (String) payloadData.get("botId");
YMChat ymChat = YMChat.getInstance();
ymChat.config = new YMConfig(botId);
ymChat.config.version = 2;
ymChat.config.ymAuthenticationToken = "2gs20emoof1666164936076";
if (payloadData.get("journeySlug") != null) {
String journeySlug = (String) payloadData.get("journeySlug");
botPayloadData.put("JourneySlug", journeySlug);
ymChat.config.payload = botPayloadData;
}
try {
ymChat.startChatbot(this);
} catch (Exception e) {
e.printStackTrace();
}
}
```