Skip to content

In app chat

Maksym Svitlovskyi edited this page Aug 1, 2024 · 30 revisions

Find more info about Live chat product on Infobip docs.

Intro

In-app chat is the mobile component for connecting and interacting with Infobip's LiveChat product. In-app chat is built on top of Mobile Messaging SDK and that's why Mobile Messaging should be included into your application and properly configured. In-app chat requires from you a careful setup, both in your mobile app and in your Infobip account. The following steps must be prepared in order to ensure the chat communication:

  1. Include and setup Mobile Messaging SDK plugin in your application. If you haven't already, please follow its Quick start guide carefully. Only by being able to receive a pushRegistrationId in your device, you'll be able to successfully connect to In-app chat in the next steps.

  2. Create a LiveChat Widget and connect it with the Mobile Messaging application profile you created in step 1 to the widget configuration.

  3. Setup In-app chat for Mobile Messaging SDK plugin, put inAppChatEnabled: true in configuration:

InfobipMobilemessaging.init(Configuration(
        ...
        inAppChatEnabled: true,
        ...
));

Display In-app chat screen

In-app chat provides a built-in chat screen which you can quickly embed into your own application. It contains a navigation toolbar, a messages list and the message text and attachment input. For a more flexible and customizable approach to show chat, such as hiding the toolbar and/or the input to replace them with your own, check the next section Display In-app chat view. Together with chat customization options you can integrate In-app chat to perfectly fit all your design needs. If instead you prefer to use our provided components, initialize In-app chat screen with just one line of code:

InfobipMobilemessaging.showChat()
android_chat_screen ios_chat_screen
Examples of Android and iOS In-app chat

It will immediately open the chat screen on top of the current screen. It is a quick and simple to integrate full screen end-to-end chat solution.

Display In-app chat view

In-app chat provides ChatView widget where you have much more control over the chat. The widget offers many public functions and properties, such as control over the visibility of navigation toolbar and message input, and the possibility of replacing with your own. Although you have a full control over the chat screen content, there are some steps we recommend you to follow:

Full code of example integration of ChatView can be checked in the Example application.

  1. Create base skeleton of stateful widget and build ChatView. ChatView constructor optional arguments withToolbar and withInput allows you to define visibility of navigation toolbar and message input. The only mandatory argument onNativeViewCreated callback function provides you with a ChatViewController, which offers the public functions to control the chat.
import 'package:infobip_mobilemessaging/chat_view.dart';

class ChatViewDemo extends StatefulWidget {
  const ChatViewDemo({super.key});

  @override
  State createState() => _ChatViewDemoState();
}

class _ChatViewDemoState extends State<ChatViewDemo> {
  ChatViewController? _chatViewController;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ChatView(
      withInput: true,
      withToolbar: true,
      onNativeViewCreated: _onNativeViewCreated,
    );
  }

  void _onNativeViewCreated(ChatViewController controller) {
    _chatViewController = controller;
  }
  1. Use the ChatViewController to subscribe chat events and much more, see controller public functions for more details. You can find all chat events in the ChatViewEvent class.
import 'package:infobip_mobilemessaging/chat_view.dart';
import 'package:infobip_mobilemessaging/models/chat_view_event.dart';

...

  void _subscribeToEvents() {
    _chatViewController?.on(
        ChatViewEvent.chatViewChanged, (String chatView) => {
          log('chat view changed: $chatView'),
        }
    );
  }
  
...

ChatViewController public functions

  /**
   * Navigates chat from [THREAD] back to [THREAD_LIST] destination in multithread chat.
   * It does nothing if widget is not multithread.
   * All multi-thread chat destinations:
   * LOADING, THREAD_LIST, LOADING_THREAD, THREAD, CLOSED_THREAD, SINGLE_MODE_THREAD
   */
  void showThreadsList();

  /**
   * Set the language of the chat.
   * Parameter [language] in locale format e.g.: en-US
   */
  void setLanguage(String language);
  
  /**
   * Set contextual data of the chat.
   * If the function is called when the chat is loaded data will be sent immediately, otherwise they will be sent to the chat once it is loaded.
   * Every function invocation will overwrite the previous contextual data.
   * See [ChatViewEvent.chatLoaded] to detect if chat is loaded.
   * Parameter [data] in JSON string format
   * Parameter [allMultiThreadStrategy] multithread strategy flag, true -> ALL, false -> ACTIVE
   */ 
  void sendContextualData(String data, bool allMultiThreadStrategy)

  /**
   * Set the theme of the Livechat Widget.
   * You can define widget themes in [https://portal.infobip.com/apps/livechat/widgets"](Live chat widget setup page) in Infobip Portal, section `Advanced customization`.
   * Please check widget [https://www.infobip.com/docs/live-chat/widget-customization](documentation) for more details.
   * Function allows to change widget theme while chat is shown - in runtime.
   * If you set widget theme before chat is initialized by [InAppChatView.init] the theme will be used once chat is loaded.
   * Parameter [widgetTheme] unique theme name, empty or blank value is ignored.
   */
  void setWidgetTheme(String widgetTheme);

  /**
   * Sends draft message to be show in chat to peer's chat.
   * Parameter [draft] message to be sent
   */
  void sendChatMessageDraft(String draft);

  /**
   * Sends message to the chat.
   * Parameter [message] message to be send, max length allowed is 4096 characters
   */
  void sendChatMessage(String message);

  /**
   * Sends attachment to the chat.
   * Parameter [attachment] attachment to be send
   */
  void sendChatAttachment(ChatViewAttachmentData attachment);

  /**
   * Returns true if chat is synchronized and multithread feature is enabled, otherwise returns false.
   */
  Future<bool> isMultithread();

  /**
   * Registers a callback for the given event name.
   * [ChatViewEvent] class provides constants of all available events names
   */
  Future<void> on(String eventName, Function callback);

  /**
   * Unregisters a callback for the given event name.
   */
  Future<void> unregister(String eventName, Function? callback);

  /**
   * Unregisters all callbacks for the given event name.
   */
  Future<void> unregisterAllHandlers(String eventName);

Customize In-app chat

You can define your own custom appearance for chat view: It is part of Configuration object passed to InfobipMobilemessaging.init(). If it is undefined, its settings will be taken from web widget configuration (as defined in Infobip Portal). We offer an example on chat customization in the example application.

Common

  • Top bar:
    • toolbarTitle (String) -- title for the top bar
    • toolbarTitleColor (String) -- in hex format, color of top bar title text
    • toolbarTintColor (String) -- in hex format, tint color of top bar
    • toolbarBackgroundColor (String) -- in hex format, background of top bar
  • Chat:
    • widgetTheme (String) -- name of the Livechat widget theme, you can read more about Livechat widget themes
    • chatBackgroundColor (String) -- in hex format, chat background color
    • noConnectionAlertTextColor (String) -- in hex format, text color at no internet connection alert
    • noConnectionAlertBackgroundColor (String) -- in hex format, background color in no internet connection alert
  • Input:
    • chatInputSeparatorVisible (Bool) -- controls visibility of separator line between chat and chat input
    • attachmentButtonIcon (String) -- path to file, icon which represent add attachment button in chat input
    • sendButtonIcon (String) -- path to file, icon which represent send button in chat input
    • sendButtonTintColor (String) -- in hex format, tint color of chat input send button
    • chatInputPlaceholderColor (String) -- in hex format, color of chat input placeholder
    • chatInputCursorColor (String) -- in hex format, color of chat input cursor
    • chatInputBackgroundColor (String) -- in hex format, background color of chat input

iOS

  • attachmentPreviewBarsColor (String) -- in hex format, changes color of background and navigation bar when previewing an attachment

  • attachmentPreviewItemsColor (Double) -- in hex format, changes tint color of loading indicator and error alert when previewing an attachment

  • textContainerTopMargin (Double) -- top margin of text container

  • textContainerLeftPadding (Double) -- left padding of text container

  • textContainerCornerRadius (Double) -- corner radius of text container

  • textViewTopMargin (Double) -- text view top margin

  • placeholderHeight (Double) -- height of placeholder

  • placeholderSideMargin (Double) -- placeholder left and right margins

  • buttonHeight (Double) -- height of chat input buttons

  • buttonTouchableOverlap (Double) -- change touchable area of a send button

  • buttonRightMargin (Double) -- right margin of a send button

  • utilityButtonWidth (Double) -- width of an attachment button

  • utilityButtonBottomMargin (Double) -- bottom margin of an attachment button

  • initialHeight (Double) -- initial height of a chat input

  • mainFont (String) -- font name without extension, changes text font in: placeholder, chat input, and no connection alert views

  • charCountFont (String) -- font name without extension, changes text font in character counter view

Android

  • Status bar:
    • chatStatusBarColorLight (Bool) -- whether icons in status bar should be light, dark otherwise
    • chatStatusBarBackgroundColor (String) -- in hex format, color of the status bar
  • Top bar:
    • chatNavigationIcon (String) -- path to file, top bar navigation icon
    • chatNavigationIconTint (String) -- in hex format, color of a navigation icon
    • chatSubtitleText; (String) -- text of the top bar subtitle
    • chatSubtitleTextColor (String) -- in hex format, color of subtitle in the top bar
    • chatSubtitleTextAppearanceRes (String) -- id of text appearance from android styles used for the top bar subtitle, e.g.,: TextAppearance_AppCompat_Subtitle
    • chatSubtitleCentered (Bool) -- whether the top bar subtitle should be centered horizontally
    • chatTitleTextAppearanceRes (String) -- id of text appearance from android styles used for the top bar title
    • chatTitleCentered (Bool) -- whether the top bar title should be centered horizontally
    • chatMenuItemsIconTint (String) -- in hex format, color of top bar menu items icon
    • chatMenuItemSaveAttachmentIcon (String) -- path to file, top bar save menu item icon in attachment preview screen
  • Chat:
    • chatProgressBarColor (String) -- in hex format, color of a loading indicator
    • chatNetworkConnectionErrorText (String) -- text of a no connection alert
    • chatNetworkConnectionErrorTextAppearanceRes (String) -- id of text appearance from android styles used for a no connection alert
  • Input:
    • chatInputSeparatorLineColor (String) -- in hex format, color of a separator between the chat and the chat input
    • chatInputHintText (String) -- text of a chat input placeholder
    • chatInputTextColor (String) -- in hex format, color of text in input field
    • chatInputTextAppearance (String) -- id of text appearance from android styles used for a chat input text
    • chatInputAttachmentIconTint (String) -- in hex format, color of the add attachment icon in the input view
    • chatInputAttachmentBackgroundColor (String) -- in hex format, background color of the attachment icon in the input view
    • chatInputAttachmentBackgroundDrawable (String) -- path to file, icon which is used as background for attachment button in chat input
    • chatInputSendIconTint (String) -- in hex format, color of the send icon in the input view
    • chatInputSendBackgroundColor (String) -- in hex format, background color of the send icon in the input view
    • chatInputSendBackgroundDrawable (String) -- path to file, icon which is used as background for send button in chat input

Note: Same style can be achieved in an xml format of android styles. Define your own theme.

Livechat widget theme

Livechat widget themes are defined on the Live chat widget setup page on Infobip Portal. You can define multiple custom themes and customize various widget attributes, read Livechat documentation to get information about all possible widget customization options.

To set Livechat theme in In-app chat you must:

  1. Define the name and values of your theme(s) in a JSON format, under widget section Theme -> Advanced Customization, in Infobip Portal.
  2. Once you know the names of your themes, you can use them in Configuration.

Customer's Chat History

Once your app is installed, it is assigned a set of IDs for receiving push notifications and connecting to LiveChat. Additionally, a mostly empty "person" entity is automatically created on the Infobip side as part of the installation. For more details, see another page explaining users and installations terminology.

While having an anonymous customer/person fits some use cases, most likely you'll have an authenticated customer you can/want to identify (for example, by their email, phone number, or some other unique ID). To do so, use the Personalize feature of the Mobile messaging SDK. You can link your customer to your app installation and also you'll be able to recover a chat history with that customer.

Once your app has received the push registration, personalize your customer. Next time the chat shows up, previously sent messages will be present, recovering the open conversation.

There is also an option to depersonalize a customer. This reverts the customer to its original, anonymous state emptying the chat history. This is a common/suggested practice for log-out flows.

Handle notification taps

Mobile Messaging Plugin has notificationTapped event, which will be sent when user opens the app by tapping on the notification alert. Note that chat messages may be recognised by chat attribute:

InfobipMobilemessaging.on(
    LibraryEvent.notificationTapped,
    (Message message) => {
          if (message.chat) {print('Chat message tapped')}
        });

In-app chat events

In-app chat library supports all core SDK library events plus following chat specific events: All In-app chat events are currently supported only in Android.

Event Parameters Description
unreadMessageCounterUpdated Unread messages count Triggered when number of unread messages is changed.
chatViewStateChanged In-app chat view name: LOADING, THREAD_LIST, LOADING_THREAD, THREAD, CLOSED_THREAD, SINGLE_MODE_THREAD, UNKNOWN Triggered when when view in InAppChat is changed.
chatConfigurationSynced Triggered when chat configuration is synchronized. (Note: Android only)
chatLivechatRegistrationIdUpdated Livechat registration id Triggered when livechat registration id is updated. (Note: Android only)
chatAvailabilityUpdated Boolean telling if chat is available Triggered when chat availability is updated.

Library events can be subscribed on using the following code snippet:

import 'package:infobip_mobilemessaging/models/library_event.dart';

InfobipMobilemessaging.on(
    LibraryEvent.'<event name>',
    (event) => {
        print('Event received: ' + event.toString());
    });

Sending attachments

We've added sending attachments support, more info in iOS SDK docs, Android SDK docs

Attachments preview

For saving attachments to photo library you will need to add additional permissions

Supported attachment types

Unread chat push messages counter

An API is available to get and reset current unread chat push messages counter. The counter increments each time the application receives chat push message (this usually happens when chat screen is inactive or the application is in background/terminated state). In order to get current counter value use following API:

int counter = await InfobipMobilemessaging.getMessageCounter();

MobileMessaging SDK automatically resets the counter to 0 whenever user opens the chat screen. However, use the following API in case you need to manually reset the counter:

InfobipMobilemessaging.resetMessageCounter();

You can register to the event unreadMessageCounterUpdated with inAppChat.unreadMessageCounterUpdated value, in order to get updates of the counter in runtime.

Changing localization

The predefined messages prompted within the In-app chat (such as status updates, button titles, input field prompt) by default are localized using system locale setting, but can be easily changed providing your locale string with the following formats: "es_ES", "es-ES", "es".

InfobipMobilemessaging.setLanguage("es");

Sending Contextual Data

It is possible to send contextual data / metadata to Infobip’s Conversations via the Mobile Messaging SDK. Data can be sent several times but only last sent data are stored in conversation. Every sent data will overwrite the previously sent contextual data.

There are two possible scenarios:

  1. Contextual data is sent before chat is present and loaded. Mobile Messaging SDK stores the data and automatically sends it once the chat is loaded.
  2. Contextual data is sent when chat is present and loaded. In a single thread, the data will be sent to an open conversation. In multi-thread, LiveChat widget tracks a list of open conversations, and based on the strategy, it will either send it to a currently ACTIVE conversation or ALL conversations.

Multi-thread strategy

In-app chat supports having multiple conversations between an agent and a customer. Considering this, Mobile Messaging SDK needs to know to which conversations send contextual data:

  • ACTIVE - sends metadata to a currently active conversation
  • ALL - sends metadata to all conversations between an agent and a customer (This field has no impact in case of a single-thread LiveChat widget.)

Mobile Messaging SDK function to send contextual data has two parameters:

  1. The mandatory data, sent as string, in a format of JavaScript objects and values (for guidance, it must be accepted by JSON.stringify())
  2. A multithread strategy, possible values are:
  • true = metadata sent to ALL non-closed conversations for a widget
  • false = metadata sent to ACTIVE only conversation for a widget

Usage:

InfobipMobilemessaging.sendContextualData("{ exampleKey: 'InAppChat Metadata Value Example' }", false);

Note:

If you use In-app chat view you must use ChatViewController public function to send contextual data.

Multiple chat threads

Default LiveChat widget works with single chat thread, one customer can only have one single open conversation. But the LiveChat widget settings page offers option to enable multiple chat threads.

Multithread setting

When the setting above is enabled, the In-app chat UI will automatically offer in mobile:

  • A list (initially empty) of all the unsolved conversation threads the user has opened.
  • A button to "Start new chat" thread.
  • A navigation to each specific conversation thread, to open particular chat view tap on conversation thread in the list.
Threads list

The functionality for multiple chat threads works out of the box: there is no need for extra implementation in the mobile integrator's side.

Authenticated chat

It is possible to authenticate a user before accessing the In-app chat, given you have enabled this feature in the LiveChat widget.

Livechat widget JWT authentication setup

The authentication is accomplished by combining the Mobile Messaging SDK personalisation method with a JWT (JSON Web Token). The token needs to be generated by your end (see instructions here).

The authentication will use a unique identifier for your user, that can be an email address, a phone number, or an external identifier. It is crucial for this identifier to be valid, and to match the identity defined in the UserIdentity you passed in Mobile Messaging SDK personalisation call - there will be an authentication error otherwise.

Mobile messaging provides setJwt() method to give In-app chat the ability to authenticate users. In Android, provided JWT can be used multiple times during In-app chat lifetime, due to various events like screen orientation change, internet re-connection and others. You must ensure JWT expiration time is more than In-app chat lifetime.

/*
1 - The customer authenticate in your system, and you recognise his/her unique identifier
2 - You call personalise (InfobipMobilemessaging.personalize()) with this unique identifier (and optionally, with other attributes such as first name, second name, etc)
3 - Now you can display the chat as an authenticated user by doing the following:
*/

InfobipMobilemessaging.setJwt("your JWT");
InfobipMobilemessaging.showChat();

Chat and push notifications

In-app chat decides automatically when to send push notifications for incoming messages events based on the following rules:

  • If In-app chat is not loaded/disconnected => push notifications will be sent.
  • If your app is in the background or a device is locked regardless of its connection status => push notifications will be sent.
  • If the app is in the foreground and In-app chat is loaded/connected => push notification will NOT be sent.

In Android In-app chat connection is established and stopped based on component lifecycle. Chat connection is active only when Lifecycle.State is at least Lifecycle.State.STARTED. Chat connection is stopped when Lifecycle.State is below Lifecycle.State.STARTED.

In iOS chat could be loaded/connected but your app may have it hidden (e.g. behind another view) we provide you with the flexibility to control its connection. You can still receive push notifications in the foreground with these methods: stopConnection and restartConnection. Usage example:

InfobipMobilemessaging.showChat();
// Hide the chat, e.g., by displaying a new modal on top of it
InfobipMobilemessaging.stopConnection();
// Push notifications for new message events will start coming to the device
// When you detect that a chat is visible again to a user, you can reload the chat and stop push notifications by invoking: 
InfobipMobilemessaging.restartConnection();

Troubleshooting

If you face any issue using the chat, specially on the first time integration, we encourage to try your application code/certificates in our Example application, as this may give you a hint of potential mistakes. An example of the most common issues our integrators face:

  1. I get in the logs an error about no push registration id.

Please re-check the quick start guide and the steps mentioned above. For iOS, specially the part about the difference between Sandbox and Production environments, and how they need different p12 files uploaded to Infobip's web portal for Apple push notification's to work.

  1. When a chat push notification is tapped, the app is invoked, and remains wherever it previously was - but I want it to display the chat related to the push notification I tapped.

InAppChat cannot present itself: if needs the parent application (your app) to present it. So, when a push notification is tapped, your app needs to recognise that event, and present the chat if you wish so. You can detect when a push notification is tapped, its nature and content, by listening to our library-events. For this case, the event you are looking for is called 'notificationTapped'.

  1. The chat content appears blank, and the text input fields is disabled.

There are many reasons for the chat not working: from incorrect codes/ids in your setup, to badly defined livechat widget in Infobip's web portal. Usually, the console logs (if you enabled debug logs in our SDK) will give you a hint of the issue, and re-checking this guide, or comparing with our Example, should be enough to successfully integrate InAppChat. But if the issue continues, don't exitate to contact our support or ask for help here in our repository's Issues section.

  1. I have all the setup correct, but the chat is still blank and disabled.

Please confirm, within the security and authentication (last) section of your widget setup (in Infobip's web portal), if "Mobile app customer authentication - Authenticate users on mobile using JSON Web Token" is enabled. If you enabled it by mistake, disable it. If you want to authenticate mobile users, make sure you are sending a correct JSON Web Token (otherwise, similar to the point #1, the chat will remain disabled).

Clone this wiki locally