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.
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.
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
)
}
}
}
...
}
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/[email protected]/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/[email protected]/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.
When integrating a WebView to display dynamic content such as an AI chatbot, effectively handling errors is crucial to maintain a smooth user experience.
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.