AI Chatbot Guide v1
AI Chatbot
Version 1

Integrate widget into your Android app

Copy link

This guide provides a step-by-step approach to embedding an AI chatbot widget into your Android application using WebView. By loading an HTML string into a WebView, you can embed an AI chatbot widget directly into your app.


Prerequisite

Copy link

Before you start, make sure you have the following information:

  • Your Sendbird bot ID. If you don't have a bot, create one on Sendbird Dashboard under AI chatbot > Bot studio > Create bot. For further information, see the Bot studio guide.


Integration steps

Copy link

The following steps guide you through the process of embedding an AI chatbot widget into your iOS application using WebView.

Step 1 Define the WebView in XML

Copy link

Start by defining a WebView in your XML layout file. This WebView will be used to load and display the AI chatbot widget.

<WebView
    android:id="@+id/wvchatbot"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Step 2 Configure and load the WebView

Copy link

When you're ready to display the chatbot, set up the WebView and configure its settings to optimize performance and user interaction.

class WebViewAichatbotActivity: AppCompatActivity() {
    ...

    private fun loadAIchatbotWidget() {
        // Load the WebView to chat with the AI chatbot Widget
        with(aichatbotDialogBinding.wvchatbot) {
            settings.javaScriptEnabled = true
            settings.domStorageEnabled = true

            if (url == null) {
                loadDataWithBaseURL(
                    "app://local", // Added baseUrl to preserve chat history when the page reloads, allowing restoration of previous chat sessions
                    widgetHtmlString(PreferenceUtils.appId, BOT_ID),
                    "text/html",
                    "utf-8",
                    null
                )
            }
        }
    }
    ...
}

Step 3 Dynamically generate HTML for the chatbot

Copy link

The HTML content that drives the chatbot is generated dynamically using the widgetHtmlString() function. This function constructs an HTML document as a string, embedding the necessary elements to render the chatbot.

private fun widgetHtmlString(appId: String, botId: String) =
    """
        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>chatbot</title>

            <!-- Load React first and then, ReactDOM. Also, these two libs' version should be same -->
            <script crossorigin src="https://unpkg.com/react@18.2.0/umd/react.development.js"></script>
            <script crossorigin src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.development.js"></script>

            <!-- Load chat-ai-widget script and set process.env to prevent it get undefined -->
            <script>process = { env: { NODE_ENV: '' } }</script>
            <script crossorigin src="https://unpkg.com/@sendbird/chat-ai-widget@latest/dist/index.umd.js"></script>
            <link href="https://unpkg.com/@sendbird/chat-ai-widget@latest/dist/style.css" rel="stylesheet" />

            <!--Optional; to enable JSX syntax-->
            <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
            <style>
                html,body { height:100% }
                #aichatbot-widget-close-icon { display: none }
            </style>
          </head>
          <body>
            <!-- div element for chat-ai-widget container -->
            <div id="root"></div>

            <!-- Initialize chat-ai-widget and render the widget component -->
            <script type="text/babel">
                const { ChatWindow } = window.ChatAiWidget
                const App = () => {
                    return (
                        <ChatWindow
                            applicationId="$appId"
                            botId="$botId"
                        />
                    )
                }
                ReactDOM.createRoot(document.querySelector('#root')).render(<App/>);
            </script>
          </body>
        </html>
    """.trimIndent()

Note: If you want to prevent the chatbot from reloading when the screen rotates, modify the android:configChanges attribute in the manifest.


Error handling

Copy link

When integrating a WebView to display dynamic content such as an AI chatbot, effectively handling errors is crucial to maintain a smooth user experience.

Handle JavaScript errors with WebChromeClient

Copy link

WebChromeClient allows you to intercept JavaScript errors and other console messages from the WebView to debug issues efficiently.

private fun loadAIchatbotWidget() {
    ...
    webChromeClient = object : WebChromeClient() {
       override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
           Log.e("WebViewError", "Error: ${consoleMessage?.message()} at line ${consoleMessage?.lineNumber()} of ${consoleMessage?.sourceId()}")
           if (consoleMessage?.messageLevel() == ConsoleMessage.MessageLevel.ERROR) {
               Toast.makeText(this@WebViewAichatbotActivity, "An error occurred while     loading the chatbot. Please try again.", Toast.LENGTH_SHORT).show()
           }
           return true
       }
    }
    ...
}

Manage loading errors with WebViewClient

Copy link

Intercept and handle errors that occur during the web content loading, such as network errors or issues with HTTP responses.

private fun loadAIchatbotWidget() {
    ...
   webViewClient = object : WebViewClient() {
        override fun onReceivedError(
            view: WebView?,
            request: WebResourceRequest?,
            error: WebResourceError?
        ) {
            // Log the loading error
            Log.e("WebViewError", "Failed to load content: ${error?.description}")

            // Display a toast message to inform the user
            Toast.makeText(this@MainActivity, "Failed to load the chatbot. Please check your internet connection.", Toast.LENGTH_SHORT).show()
        }

        override fun onReceivedHttpError(
            view: WebView?,
            request: WebResourceRequest?,
            errorResponse: WebResourceResponse?
        ) {
            // Log the HTTP error
            Log.e("WebViewError", "HTTP error: ${errorResponse?.statusCode} ${errorResponse?.reasonPhrase}")

            // Display a toast message to inform the user
            Toast.makeText(this@MainActivity, "A server error occurred. Please try again later.", Toast.LENGTH_SHORT).show()
        }
    }
    ...
}

For a complete sample of this guide, see this sample page.