Embeding in WebView with Channel

Webchat PostMessage Integration Guide

Overview

This guide explains how to integrate a webchat into a WebView component on mobile devices or on any web page without using the chat-ui-launcher script.

While the code examples in this guide use JavaScript in a browser environment, the principles, concepts, and methods described apply equally to both browser and WebView contexts. The core functionality and integration process remain the same regardless of the specific environment.

The webchat uses the PostMessage mechanism for communication between the web content and the hosting environment (native app or web page). This approach provides flexibility for developers who want more control over the webchat integration and communication process.

Mobile Integration

For mobile applications, this guide explains how to use the PostMessage mechanism to embed the webchat into a WebView component.

Web Page Integration

For web developers who prefer not to use the chat-ui-launcher script, this guide demonstrates how to embed the webchat directly into any web page using an iframe. This method requires manual handling of the PostMessage communication but offers greater customization and control.

In both scenarios, the PostMessage API ensures secure and efficient communication between the webchat and its hosting environment, whether it's a native mobile app or a web page.


PostMessage Mechanism in General

The PostMessage API allows secure communication between the webchat (running in the WebView) and the native app or website.

Sending Information to Webchat

To send information to the webchat, use the following format:

{
  "type": "EVENT_TYPE",
  "payload": {
    // Event-specific data
  }
}

Receiving Messages from Webchat

Set up event listeners in your native code or website to handle messages sent from the webchat.

window.addEventListener('message', (event) => {
   if(event.data.type === 'CLOSE_CONVERSATION_WINDOW'){
     // Handle the CLOSE_CONVERSATION_WINDOW event 
   }
})

Supported Events

Events to Send to Webchat

  1. SET_CONFIG
    Required to initialize the webchat.

    {
      "session": {
        "id": "unique-session-identifier"
      },
      actionButtons: {
        conversationWindow: {minimize: false, resetAndMinimize: false}
      }
    }
    

  2. START_CONVERSATION
    Starts a new conversation. No payload required.

  3. CLOSE_CONVERSATION
    Closes and resets the current conversation. No payload required.

  4. DESTROY
    Destroys the webchat and closes the conversation session. No payload required.

Events Received from Webchat

  1. WEBCHAT_READY
    Sent when the webchat is initialized and ready.

  2. CLIENT_MESSAGE_SENT
    Sent when a user sends a message.

  3. MESSAGE_RECEIVED
    Sent when the webchat receives a message from the bot.

  4. CONVERSATION_END
    Sent when the conversation is finished.

  5. CLOSE_CONVERSATION_WINDOW
    Sent when the user clicks the close (X) icon.

  6. MINIMIZE_CONVERSATION_WINDOW
    Sent when the user clicks the minimize icon.

  7. DESTROY_DONE
    Sent when the webchat is destroyed.


Implementation Steps

  1. Embed the webchat in your environment (e.g., using an iframe in a web page).
  2. Implement the PostMessage mechanism for two-way communication.
  3. Generate and manage a unique session ID on the host side.
  4. Listen for the WEBCHAT_READY event from the webchat.
  5. Send the SET_CONFIG event to initialize the webchat, including the session ID.
  6. Implement handlers for other events as needed.
  7. Ensure proper session management throughout the lifecycle of your application.

Example WEB Implementation

Below is a working example of a complete HTML file embedding the webchat. Note: this file must be served from localhost:8000 due to channel configuration.

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <style>
    iframe {
      height: calc(100vh - 4px);
      width: 100%;
      border: none;
    }
    body {
      margin: 0;
    }
  </style>
</head>

<body>

<script type="text/javascript">
  window.sentiOneChat.initWebChat({
    chatSrc: "https://webchat.app.chatbots.sentione.com/fullscreen",
    channelId: "dd301990-c156-4afb-b43e-f995c9a84a84",
  });
</script>

<iframe
  id="webchat-frame"
  src="https://webchat.app.chatbots.sentione.com/fullscreen/dd301990-c156-4afb-b43e-f995c9a84a84"
  title="WebChat">
</iframe>

<script>
  const iframe = document.getElementById('webchat-frame');
  const chatOrigin = "https://webchat.app.chatbots.sentione.com";

  const sendMessageToWebchat = (type, payload) => {
    iframe.contentWindow.postMessage({ type, payload }, chatOrigin);
  };

  function getOrCreateSessionId() {
    const key = 'webchat-session-id';
    let sessionId = localStorage.getItem(key);
    if (!sessionId) {
      sessionId = crypto.randomUUID();
      localStorage.setItem(key, sessionId);
    }
    return sessionId;
  }

  const sessionId = getOrCreateSessionId();

  iframe.addEventListener('load', () => {
    sendMessageToWebchat('SET_CONFIG', {
      session: {
        id: sessionId
      },
      actionButtons: {
        conversationWindow: {minimize: false, resetAndMinimize: false}
      }
    });
  });

  window.addEventListener('message', (event) => {
    if (event.origin !== chatOrigin) return;

    switch (event.data.type) {
      case 'WEBCHAT_READY':
        console.log('[WebChat] Ready');
        sendMessageToWebchat('START_CONVERSATION');
        break;
      case 'CLIENT_MESSAGE_SENT':
        console.log('[WebChat] Client message sent');
        break;
      case 'MESSAGE_RECEIVED':
        console.log('[WebChat] Message received');
        break;
      case 'CLOSE_CONVERSATION_WINDOW':
      case 'MINIMIZE_CONVERSATION_WINDOW':
      case 'DESTROY_DONE':
        console.log('[WebChat] Event:', event.data.type);
        break;
    }
  });
</script>

</body>
</html>



Example Android implementation

It is possible to embed the SentiOne WebChat directly into a native Android application using a WebView. This approach allows developers to integrate the full conversational experience inside their mobile apps without relying on external browsers.

To achieve this, you should load the following URL inside your WebView:

<https://webchat.app.chatbots.sentione.com/fullscreen/CHANNEL_ID>

Replace CHANNEL_ID with the ID of the desired channel you want to connect to.

Make sure your WebView is configured to support JavaScript and allows communication via postMessage if needed.


A basic WebView setup in Android might look like this:

package com.example.myapplication

import android.os.Bundle
import android.util.Log
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.myapplication.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var webView: WebView
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val navView: BottomNavigationView = binding.navView

        val navController = findNavController(R.id.nav_host_fragment_activity_main)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)

        webView = findViewById(R.id.webView)
        webView.settings.apply {
            javaScriptEnabled = true
            domStorageEnabled = true
            allowFileAccess = true
            allowContentAccess = true
            mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW

            cacheMode = WebSettings.LOAD_DEFAULT
            databaseEnabled = true

            useWideViewPort = true
            loadWithOverviewMode = true
            builtInZoomControls = false
            displayZoomControls = false

        }

        webView.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                Log.d("WebView", "Page loaded: $url")

                val config = """
                    window.postMessage({
                      type: 'SET_CONFIG',
                      payload: {
                        session: {
                          id: "SESSION_ID_REPLACE_IT_WITH_SOME_MECHANIZM"
                        },
                        actionButtons: {
                          conversationWindow: {
                            minimize: false,
                            resetAndMinimize: false
                          }
                        }
                      }
                    }, '*');
                """.trimIndent()

                val start = """
                    window.postMessage({
                      type: 'START_CONVERSATION',
                      payload: {
                        
                      }
                    }, '*');
                """.trimIndent()

                sendPostMessage(config)
                sendPostMessage(start)
            }
        }

        // Use or replace channel id of proper, published project from https://app.chatbots.sentione.com/
        webView.loadUrl("https://webchat.app.chatbots.sentione.com/fullscreen/CHANNEL_ID")

    }

    fun sendPostMessage(message: String) {
        Log.d("WebView", message)
        webView.evaluateJavascript(message) { result ->
            Log.d("WebView", "PostMessage sent: $result")
        }
    }
}

Configure channel

In the alloweddomain field of the channel configuration, you must add the WebChat URL used in the WebView, for example:

This ensures that the chat will load properly and that domain-based restrictions will not block the session.


Example app: Download zip




Important Note on Session Management

The "session" field, particularly its "id" subfield, is crucial for proper webchat functionality.
The session ID should be generated on the host side (your application or webpage).
It is the host's responsibility to store and manage this session ID.
The host should keep the session ID up to date and reset it when necessary (e.g., starting a new conversation, user logout).
Proper session management ensures conversation continuity and user experience consistency.


Troubleshooting

  • If PostMessage events are not being received, check that JavaScript is enabled in the WebView.
  • Verify that the correct URL is being loaded in the WebView.
  • Ensure that the PostMessage event listeners are set up correctly on both the native and web sides.

Remember to refer to the latest documentation for your specific webchat provider, as the exact implementation details may vary.