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!!!