I want to integrate Chatbot widget in android by loading static html in webview not by using android sdk

Hi,

What I’m trying to do =>
I’m trying to integrate the yellow.ai chatbot in my Android app. I’m not going with the sdk approach as this is not what I want. So, I’m loading the widget script in static HTML and loading that HTML in my webView( android). I’m writing this all code in kotlin.


What is the challenge =>
My HTML is loading correctly and also the script is working, but while loading the yellow.ai using the script provided I’m getting the following error. Even the HTML when loaded inside Chrome was working fine but not in webView.

"Uncaught SecurityError: Failed to read the 'cookie' property from 'Document': Access is denied for this document.", source: https://cdn.yellowmessenger.com/plugin/widget-v2/latest/dist/main.min.js (2)

Can anyone please help with this?


What I have tried =>

I have tried to get the solution online but it didn’t help. Also, I have given all the permission to webView to load this script still it is not working.


Please find the below code for reference →

Android Part


import android.annotation.SuppressLint
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.webkit.CookieManager
import android.webkit.WebChromeClient
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity


class MyBotActivity: AppCompatActivity() {

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.my_bot_activity)

        val myBotWebView = findViewById<WebView>(R.id.botWebView)


        val cookieManager: CookieManager = CookieManager.getInstance()
        cookieManager.setAcceptThirdPartyCookies(myBotWebView, true)


        // Load the index.html file from the raw folder
        val rawResId = resources.getIdentifier("index", "raw", packageName)
        val htmlData = resources.openRawResource(rawResId).bufferedReader().use { it.readText() }
        myBotWebView.settings.javaScriptEnabled = true
        val settings = myBotWebView.settings
        settings.allowFileAccess = true
        settings.domStorageEnabled = true
        settings.allowFileAccessFromFileURLs = true
        settings.allowUniversalAccessFromFileURLs = true

        myBotWebView.webChromeClient = object : WebChromeClient() {
            // Handle alert dialogs
            override fun onJsAlert(view: WebView?, url: String?, message: String?, result: android.webkit.JsResult): Boolean {
                // Implement your custom alert dialog here
                // For example, you can use an AlertDialog to display the message
                result.confirm()
                return true
            }

            // Show progress in the title bar
            override fun onProgressChanged(view: WebView?, newProgress: Int) {
                super.onProgressChanged(view, newProgress)
                // Implement progress update logic here, if needed
            }

            // Handle JavaScript dialogs (prompt, confirm, etc.)
            override fun onJsPrompt(view: WebView?, url: String?, message: String?, defaultValue: String?, result: android.webkit.JsPromptResult): Boolean {
                // Implement your custom JavaScript dialog handling here
                // For example, you can use an AlertDialog to prompt for user input
                result.cancel()
                return true
            }
            // Handle geolocation permissions request
            override fun onGeolocationPermissionsShowPrompt(origin: String?, callback: android.webkit.GeolocationPermissions.Callback) {
                // Implement your geolocation permission request handling here
                // For example, you can show a dialog asking the user for permission
                callback.invoke(origin, true, false)
            }
        }

        myBotWebView.webViewClient = object : WebViewClient() {
            override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest): WebResourceResponse? {
                // Check if the request is for a TrustedScriptURL
                val requestUrl: Uri? = request.url
                if (requestUrl != null) {
                    // Load the TrustedScriptURL
                    val trustedRequest = object : WebResourceRequest {
                        override fun getUrl(): Uri = request.url
                        override fun getMethod(): String = request.method
                        override fun getRequestHeaders(): Map<String, String> = request.requestHeaders
                        override fun hasGesture(): Boolean = request.hasGesture()
                        override fun isForMainFrame(): Boolean = request.isForMainFrame()
                        override fun isRedirect(): Boolean = request.isRedirect()
                    }
                    return super.shouldInterceptRequest(view, trustedRequest)
                }

                // For other requests, proceed as usual
                return super.shouldInterceptRequest(view, request)
            }
        }






        // Display the HTML content in the WebView
        myBotWebView.loadDataWithBaseURL(null, htmlData, "text/html", "UTF-8", null)
//        myBotWebView.loadUrl("https://cdn.yellowmessenger.com/plugin/widget-v2/latest/dist/main.min.js")
        /*myBotWebView.evaluateJavascript("""
            window.ymConfig = {
        bot: "x1680501144352",
        host: "https://cloud.yellow.ai",
      };
      (function () {
      console.log("------------- chat bot init ------------");
        var w = window,
          ic = w.YellowMessenger;
        if ("function" === typeof ic)
          ic("reattach_activator"), ic("update", ymConfig);
        else {
          var d = document,
            i = function () {
              i.c(arguments);
            };

          function l() {
            var e = d.createElement("script");
            (e.type = "text/javascript"),
              (e.async = !0),
              (e.src =
                "https://cdn.yellowmessenger.com/plugin/widget-v2/latest/dist/main.min.js");
            var t = d.getElementsByTagName("script")[0];
            t.parentNode.insertBefore(e, t);
          }
          (i.q = []),
            (i.c = function (e) {
              i.q.push(e);
            }),
            (w.YellowMessenger = i),
            w.attachEvent
              ? w.attachEvent("onload", l)
              : w.addEventListener("load", l, !1);
        }
      }
      console.log("------------- chat bot done ------------");
      )();
        
        """.trimIndent()){}
    */
    }
}

HTML PART ------------


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <h1>CHAT BOT</h1>
    <body> Yellow.ai chatbot integration</body>
    <footer>
        <script>
          const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://cdn.yellowmessenger.com/plugin/widget-v2/latest/dist/main.min.js';
    const config = {
      "bot": "{botID}",
        "host": "https://cloud.yellow.ai",
        "payload": {
          "type":"",
          "amount":"00",
          "time":"04/04/2023 12:30:30 PM",
          "trans_id":"7898969678675",
          "name":"User name",
          "service_provider":"mobile"
        },
        "hideChatButton": true
    };

    script.innerHTML = `
    (function() {
          var w = window,
            ic = w.YellowMessenger;
          if ("function" === typeof ic) {
            ic("reattach_activator");
            ic("update", window.ymConfig);
          } else {
            var d = document,
              i = function() {
                i.c(arguments);
              };

            function l() {
              var e = d.createElement("script");
              e.type = "text/javascript";
              e.async = true;
              e.src = "https://cdn.yellowmessenger.com/plugin/widget-v2/latest/dist/main.min.js";
              var t = d.getElementsByTagName("script")[0];
              t.parentNode.insertBefore(e, t);
            }
            i.q = [];
            i.c = function(e) {
              i.q.push(e);
            };
            w.YellowMessenger = i;
            w.attachEvent ? w.attachEvent("onload", l) : w.addEventListener("load", l, false);
          }
        })();
    `;
    cosole.log("-------- config --------")
    window['ymConfig'] = config;
    document.body.appendChild(script);
        </script>
    </footer>
</html>


Please help me, if someone knows why I’m receiving the security exception.

THanks in Advance!!! :slight_smile:

We do not recommend to use script is mobile app.
If you are doing so, we won’t be able to help with problems you might come across due to your implementation.

Script is not optimized for mobile screen and there is a lot of handling that is needed.
In our native SDK we also use webview to load the bot, it is public feel free to check the implementation.

1 Like

Hi Sukrit,

Thank you for your reply.

I have tried integrating the SDK into the mobile application, and it was working fine. However, our aim is to make it dynamic using the script provided in the integration documentation. I just want to know if it is possible to pass the payload data in PWA ( Set up Chat widget | yellow.ai ) that I’m able to load in a webView using the mentioned URL (Bot). Please let me know if it is possible.

Thank you! :blush:

Hi @Sukrit_Gupta, any idea regarding this?

Hi, please share your BotId, our support team will reach out to you to understand the use case and provide solution.