To use Stringee Live Chat API, you need to have a widget key which will be used to identify your portal. You can get that key by doing the following steps:
Install stringee-plugin from pub.dev by running the following command from the project root:
$ flutter pub add stringee_plugin
Check out plugin's documentation for more information.
## Setup
### Android
1. The Stringee Android SDK requires some permissions from your app's `AndroidManifest.xml` file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```
If your project uses ProGuard, you may have to add the following settings to the ProGuard configuration file to ensure Stringee builds correctly:
proguard-rules.pro
in your app/ dir
and insert inside:
-dontwarn org.apache.**
-keep class com.stringee.** { *; }
-keep class org.apache.** { *; }
/app/buidl.gradle
:
android {
...
buildTypes {
...
release {
...
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
pod install --repo-update
.xcworkspace
Build Settings
tab -> Other linker flags
add $(inherited)
flagBuild Settings
tab -> Enable bitcode
select NO
Build Settings
tab -> Allow Non-modular includes in Framework Modules
select YES
import 'package:stringee_plugin/stringee_plugin.dart';
...
StringeeClient client = StringeeClient();
StringeeChat chat = new StringeeChat(client);
The StringeeClient class is defined in the Stringee Plugin. It includes methods interacting with Stringee Server. The StringeeChat class is defined in the chat section in the Stringee Plugin. It includes methods interacting with Stringee Server.
Chat Profile is an object that will let you know:
chat.getChatProfile('YOUR_WIDGET_KEY').then((value) {
print("getChatProfile: " + value.toString());
bool status = value['status'];
if (status) {
List queueList = value['body']['queues'];
}
});
To chat with your agents, your customers have to connect to Stringee server first. But they are not users in your system, they can be anybody, so you need to generate a token for them. To do that, call the following function:
late String token;
...
chat.getLiveChatToken('YOUR_WIDGET_KEY', 'YOUR_CUSTOMER_NAME', 'YOUR_CUSTOMER_EMAIL').then((value) {
print("getLiveChatToken: " + value.toString());
bool status = value['status'];
if (status) {
token = value['body'];
}
});
In which:
Next, we will connect to Stringee Server. You must do this before you can start a live chat conversation.
Register the client's events and chat's events.
client.eventStreamController.stream.listen((event) {
Map<dynamic, dynamic> map = event;
switch (map['eventType']) {
case StringeeClientEvents.didConnect:
handleDidConnectEvent();
break;
case StringeeClientEvents.didDisconnect:
handleDiddisconnectEvent();
break;
case StringeeClientEvents.didFailWithError:
int code = map['body']['code'];
String msg = map['body']['message'];
handleDidFailWithErrorEvent(code,msg);
break;
case StringeeClientEvents.requestAccessToken:
handleRequestAccessTokenEvent();
break;
case StringeeClientEvents.didReceiveCustomMessage:
handleDidReceiveCustomMessageEvent(map['body']);
break;
case StringeeClientEvents.timeoutInQueue:
handleTimeoutInQueueEvent(map['body']);
break;
case StringeeClientEvents.conversationEnded:
handleConversationEndedEvent(map['body']);
break;
case StringeeClientEvents.userBeginTyping:
handleUserBeginTypingEvent(map['body']);
break;
case StringeeClientEvents.userEndTyping:
handleUserEndTypingEvent(map['body']);
break;
default:
break;
}
});
...
chat.eventStreamController.stream.listen((event) {
Map<dynamic, dynamic> map = event;
if (map['eventType'] == StringeeChatEvents.didReceiveObjectChange) {
handleDidReceiveObjectChangeEvent(map['body']);
}
});
...
/// Invoked when the StringeeClient is connected
void handleDidConnectEvent() {}
/// Invoked when the StringeeClient is disconnected
void handleDiddisconnectEvent() {}
/// Invoked when StringeeClient connect false
void handleDidFailWithErrorEvent(int code, String message) {}
/// Invoked when your token is expired
void handleRequestAccessTokenEvent() {}
/// Invoked when get Custom message
void handleDidReceiveCustomMessageEvent(Map<dynamic, dynamic> map) {}
/// Invoked when no agent answer this chat and time out route in queue
void handleTimeoutInQueueEvent(Map<dynamic, dynamic> map) {}
/// Invoked when conversation ended
void handleConversationEndedEvent(Map<dynamic, dynamic> map) {}
/// Invoked when user send begin typing event
void handleUserBeginTypingEvent(Map<dynamic, dynamic> map) {}
/// Invoked when user send end typing event
void handleUserEndTypingEvent(Map<dynamic, dynamic> map) {}
/// Invoked when receive an chat change event
void handleDidReceiveObjectChangeEvent(StringeeObjectChange stringeeObjectChange) {}
Connect by calling:
...
client.connect(token);
...
Before starting a live chat conversation, you can update the customer information to Stringee Server, so your agent can know more about your customer (where is the customer from? what type of cell phone the customer using?...). To do that, call the following function:
chat.updateUserInfo("USER_NAME", "USER_EMAIL", "USER_AVATAR").then((value) {
bool status = value['status'];
if (status) {
}
});
Then start a live chat conversation by calling:
chat.createLiveChatConversation(queueId).then((value) {
bool status = value['status'];
if (status) {
StringeeConversation conversation = value['body'];
}
});
In which:
Follow this instruction Messages
To end the live chat conversation, you call the following method:
conversation.endChat().then((value) {
bool status = value['status'];
if (status) {
}
});
Next, we will connect to Stringee Server. You must do this before you can start a live chat conversation.
Register the client's events and chat's events.
client.eventStreamController.stream.listen((event) {
Map<dynamic, dynamic> map = event;
switch (map['eventType']) {
case StringeeClientEvents.didConnect:
handleDidConnectEvent();
break;
case StringeeClientEvents.didDisconnect:
handleDiddisconnectEvent();
break;
case StringeeClientEvents.didFailWithError:
int code = map['body']['code'];
String msg = map['body']['message'];
handleDidFailWithErrorEvent(code,msg);
break;
case StringeeClientEvents.requestAccessToken:
handleRequestAccessTokenEvent();
break;
case StringeeClientEvents.didReceiveCustomMessage:
handleDidReceiveCustomMessageEvent(map['body']);
break;
case StringeeClientEvents.didReceiveChatRequest:
handleDidReceiveChatRequestEvent(map['body']);
break;
case StringeeClientEvents.didReceiveTransferChatRequest:
handleDidReceiveTransferChatRequestEvent(map['body']);
break;
case StringeeClientEvents.timeoutAnswerChat:
handleTimeoutAnswerChatEvent(map['body']);
break;
case StringeeClientEvents.conversationEnded:
handleConversationEndedEvent(map['body']);
break;
case StringeeClientEvents.userBeginTyping:
handleUserBeginTypingEvent(map['body']);
break;
case StringeeClientEvents.userEndTyping:
handleUserEndTypingEvent(map['body']);
break;
default:
break;
}
});
...
chat.eventStreamController.stream.listen((event) {
Map<dynamic, dynamic> map = event;
if (map['eventType'] == StringeeChatEvents.didReceiveObjectChange) {
handleDidReceiveObjectChangeEvent(map['body']);
}
});
...
/// Invoked when the StringeeClient is connected
void handleDidConnectEvent() {}
/// Invoked when the StringeeClient is disconnected
void handleDiddisconnectEvent() {}
/// Invoked when StringeeClient connect false
void handleDidFailWithErrorEvent(int code, String message) {}
/// Invoked when your token is expired
void handleRequestAccessTokenEvent() {}
/// Invoked when get Custom message
void handleDidReceiveCustomMessageEvent(Map<dynamic, dynamic> map) {}
/// Invoked when receive chat request
void handleDidReceiveChatRequestEvent(StringeeChatRequest chatRequest) {}
/// Invoked when receive transfer chat request from other agent
void handleDidReceiveTransferChatRequestEvent(StringeeChatRequest chatRequest) {}
/// Invoked when time out chat request for agent
void handleTimeoutAnswerChatEvent(StringeeChatRequest chatRequest) {}
/// Invoked when conversation ended
void handleConversationEndedEvent(Map<dynamic, dynamic> map) {}
/// Invoked when user send begin typing event
void handleUserBeginTypingEvent(Map<dynamic, dynamic> map) {}
/// Invoked when user send end typing event
void handleUserEndTypingEvent(Map<dynamic, dynamic> map) {}
/// Invoked when receive an chat change event
void handleDidReceiveObjectChangeEvent(StringeeObjectChange stringeeObjectChange) {}
Connect by calling:
String token = '';
...
client.connect(token);
...
After receiving a chat request, agent can accept or reject this chat request.
To accept chat request, call the following function:
chatRequest.accept().then((value) {
bool status = value['status'];
if (status) {
chat.getConversationById(chatRequest.convId).then((value) {
StringeeConversation conversation = value['body'];
});
}
});
After accept chat request success, you can get conversation by conversationId from chat request
To reject chat request, call the following function:
chatRequest.reject().then((value) {
bool status = value['status'];
if (status) {
}
});
Follow this instruction Messages
To end the live chat conversation, you call the following method:
conversation.endChat().then((value) {
bool status = value['status'];
if (status) {
}
});
For agent want to create a ticket for a missed live chat conversation, you call:
chat.createLiveChatTicket('YOUR_WIDGET_KEY', 'CUSTOMER_NAME', 'CUSTOMER_EMAIL', 'TICKET_DESCRIPTION').then((value) {
bool status = value['status'];
if (status) {
}
});
If you want to send chat's content to an email at any time, you can use the following function:
conversation.sendChatTranscript('EMAIL', 'DOMAIN').then((value) {
bool status = value['status'];
if (status) {
}
});
You can view a completed version of this sample app on GitHub: https://github.com/stringeecom/stringee_flutter_plugin/tree/master/example