Skip to content

Commit

Permalink
Merge pull request #40 from sendbird/feature/elliot/added-ai-chatbot-…
Browse files Browse the repository at this point in the history
…widget-sample

Added ai chatbot widget sample
  • Loading branch information
elliot-choic authored Aug 16, 2024
2 parents a688bff + 2a138d5 commit c2f6aa7
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 1 deletion.
5 changes: 5 additions & 0 deletions uikit-samples/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize|stateHidden" />

<activity
android:name=".customization.aichatbot.WebViewAiChatBotActivity"
android:configChanges="orientation|screenSize"
android:launchMode="singleTop" />

<!-- notification activities -->
<activity
android:name=".notification.NotificationHomeActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.sendbird.uikit.samples.R
import com.sendbird.uikit.samples.common.extensions.cleanUpPreviousSampleSettings
import com.sendbird.uikit.samples.common.extensions.logout
import com.sendbird.uikit.samples.customization.aichatbot.showWebViewAiChatBotSample
import com.sendbird.uikit.samples.customization.channel.showChannelHeaderSample
import com.sendbird.uikit.samples.customization.channel.showChannelLayoutSample
import com.sendbird.uikit.samples.customization.channel.showInputMenuSample
Expand Down Expand Up @@ -196,6 +197,17 @@ class CustomizationHomeActivity : AppCompatActivity() {
description = getString(R.string.text_moderation_custom_open_channel_sample),
) { showModerationOpenChannelSample(activity = this) },
// endregion

// region ai chatbot customization
CustomizationItem(
isHeader = true,
title = getString(R.string.text_title_ai_chatbot_features)
),
CustomizationItem(
title = getString(R.string.text_webview_chatbot_widget),
description = getString(R.string.text_webview_custom_chatbot_widget_sample),
) { showWebViewAiChatBotSample(activity = this) },
// endregion
)

data class CustomizationItem(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.sendbird.uikit.samples.customization.aichatbot

import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.util.Log
import android.view.ViewGroup
import android.webkit.ConsoleMessage
import android.webkit.WebChromeClient
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.sendbird.uikit.samples.common.preferences.PreferenceUtils
import com.sendbird.uikit.samples.databinding.ActivityWebViewAiChatbotBinding
import com.sendbird.uikit.samples.databinding.DialogWebViewAiChatbotBinding

// Set the Bot ID
private const val BOT_ID = "client_bot"

fun showWebViewAiChatBotSample(activity: Activity) {
activity.startActivity(Intent(activity, WebViewAiChatBotActivity::class.java))
}

class WebViewAiChatBotActivity : AppCompatActivity() {
private val binding: ActivityWebViewAiChatbotBinding by lazy {
ActivityWebViewAiChatbotBinding.inflate(layoutInflater)
}
private val aiChatBotDialogBinding: DialogWebViewAiChatbotBinding by lazy {
DialogWebViewAiChatbotBinding.inflate(layoutInflater)
}

// Create the Dialog to chat with the AI ChatBot
private val dialog: Dialog by lazy {
Dialog(this).apply {
setContentView(aiChatBotDialogBinding.root)
window?.let {
it.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
}
}

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

binding.fbWidget.setOnClickListener {
// Open the WebView to chat with the AI ChatBot
showAIChatBotWidget()
}
}

private fun showAIChatBotWidget() {
// Load the WebView to chat with the AI ChatBot Widget
with(aiChatBotDialogBinding.wvChatBot) {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
webChromeClient = object : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
// Handle error
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
}
}

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
)
}
}
dialog.show()
}
}

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()
19 changes: 19 additions & 0 deletions uikit-samples/src/main/res/layout/activity_web_view_ai_chatbot.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fbWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:backgroundTint="@color/ondark_01"
android:contentDescription="@null"
android:src="@drawable/logo_sendbird"
app:borderWidth="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
11 changes: 11 additions & 0 deletions uikit-samples/src/main/res/layout/dialog_web_view_ai_chatbot.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

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

</androidx.constraintlayout.widget.ConstraintLayout>
7 changes: 6 additions & 1 deletion uikit-samples/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,18 @@
<string name="text_report_inappropriate">Inappropriate</string>
<string name="text_report_error">Couldn\&#39;t report message.</string>

<!-- AI ChatBot -->
<string name="text_title_ai_chatbot_features">AI ChatBot Feature</string>
<string name="text_webview_chatbot_widget">WebView ChatBot Widget</string>
<string name="text_webview_custom_chatbot_widget_sample">Embed an AI chatbot in WebView</string>

<string name="text_list_item_nickname_format">#%d. %s</string>

<string name="text_resend">Resend</string>
<string name="text_delete">Delete</string>
<string name="text_cancel">Cancel</string>
<string name="text_custom_header">Custom Header</string>
<string name="text_menu_thumbs_up" >Thumbs Up</string>
<string name="text_menu_thumbs_up">Thumbs Up</string>
<string name="text_menu_thumbs_down">Thumbs Down</string>
<string name="text_choose_report_category_dialog">Choose the report category</string>

Expand Down

0 comments on commit c2f6aa7

Please sign in to comment.