c# - 如何使用 xamarin 表单开发 salesforce 聊天机器人

标签 c# .net xamarin xamarin.forms salesforce

我想使用 xamarin forms 应用程序开发 Salesforce 聊天机器人。我找不到我应该使用的 sdk 或 nuget 包。似乎没有关于此的可用信息。

This salesforce article ,我发现他们在哪里为 Android 和 iOS 做这件事。

我试过使用android库的.jar文件,但是不行,因为iOS开发也需要单独的。我找到了 this article但不确定他们正在开发什么软件包和平台。

如何将 Salesforce Einstein Chatbot 与 Xamarin 表单集成。有人可以帮我解决这个问题吗?

最佳答案

这就是我设法整合 Salesforce chatbot 的方式

public class SfChatbotViewModel : BaseViewModel
{
    public SfChatbotViewModel()
    {

    }
}  
<controls:HybridWebView Margin="0" x:Name="webView"
    VerticalOptions="FillAndExpand"
    HorizontalOptions="FillAndExpand" />

这是 HybridWebView Webview共享(公共(public))项目中的控制

    public class HybridWebView : Xamarin.Forms.WebView
    {
        Action<string> action;
        public static readonly BindableProperty UriProperty = BindableProperty.Create(
            propertyName: "Uri",
            returnType: typeof(string),
            declaringType: typeof(HybridWebView),
            defaultValue: default(string));
        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }
        public void RegisterAction(Action<string> callback)
        {
            action = callback;
        }
        public void Cleanup()
        {
            action = null;
        }
        public void InvokeAction(string data)
        {
            if (action == null || data == null)
            {
                return;
            }
            action.Invoke(data);
        }
    }
Below `Webview renderer` in Android project

    public class HybridWebViewRenderer : WebViewRenderer
    {
        const string JavascriptFunction = "function initESW(data){jsBridge.invokeAction(data);}";
        Context _context;
        public HybridWebViewRenderer(Context context) : base(context)
        {
            _context = context;
        }
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);
            global::Android.Webkit.WebView.SetWebContentsDebuggingEnabled(true);
            if (e.OldElement != null)
            {
                Control.RemoveJavascriptInterface("jsBridge");
                ((HybridWebView)Element).Cleanup();
            }
            if (e.NewElement != null)
            {
                CookieManager.Instance.SetAcceptCookie(true);
                CookieManager.Instance.SetAcceptThirdPartyCookies(Control, true);
                Control.SetWebViewClient(new JavascriptWebViewClient(this, $"javascript: {JavascriptFunction}"));
                Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
                Control.Settings.AllowFileAccess = true;
                Control.Settings.JavaScriptEnabled = true;
                Control.Settings.AllowFileAccessFromFileURLs = true;
                Control.Settings.AllowUniversalAccessFromFileURLs = true;
                Control.Settings.AllowContentAccess = true;
                Control.Settings.DomStorageEnabled = true;
                Control.SetWebChromeClient(new WebChromeClient());
    
                var content_UAT = LoadData("ChatUAT.html");
    
                Control.LoadDataWithBaseURL("https://service.force.com/embeddedservice/5.0/esw.min.js",
                    content_UAT,
                    "text/html;",
                    null,
                    "https://service.force.com/embeddedservice/5.0/esw.min.js");
            }
        }
        public class JavascriptWebViewClient : FormsWebViewClient
        {
            string _javascript;
            public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript) : base(renderer)
            {
                _javascript = javascript;
            }
            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                base.OnPageFinished(view, url);
                view.EvaluateJavascript("document.cookie", null);
            }
            public override void OnReceivedSslError(Android.Webkit.WebView view, SslErrorHandler handler, SslError error)
            {
                Console.WriteLine("Salesforce webview error: ", error);
                base.OnReceivedSslError(view, handler, error);
            }
            public override void OnReceivedHttpError(Android.Webkit.WebView view, IWebResourceRequest request, WebResourceResponse errorResponse)
            {
                base.OnReceivedHttpError(view, request, errorResponse);
            }
            public override void OnLoadResource(Android.Webkit.WebView view, string url)
            {
                base.OnLoadResource(view, url);
            }
        }
        public class JSBridge : Java.Lang.Object
        {
            readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
            public JSBridge(HybridWebViewRenderer hybridRenderer)
            {
                hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
            }
            [JavascriptInterface]
            [Export("invokeAction")]
            public void InvokeAction(string data)
            {
                HybridWebViewRenderer hybridRenderer;
                if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
                {
                    ((HybridWebView)hybridRenderer.Element).InvokeAction(data);
                }
            }
        }
    
        //this methods html file content from assets folder
        public string LoadData(string inFile)
        {
            Stream stream = Android.App.Application.Context.Assets.Open(inFile);
            StreamReader sr = new StreamReader(stream);
            string text = sr.ReadToEnd();
            sr.Close();
            return text;
        }
    }

这是 iOS渲染器

[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace SfChatbot.iOS
{
    public class HybridWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
    {
        const string JavascriptFunction = "function initESW(data){jsBridge.invokeAction(data);}";
        //const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
        WKUserContentController userController;

        public HybridWebViewRenderer() : this(new WKWebViewConfiguration())
        {
        }

        public HybridWebViewRenderer(WKWebViewConfiguration config) : base(config)
        {
            userController = config.UserContentController;
            var script = new WKUserScript(new NSString(JavascriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
            userController.AddUserScript(script);
            userController.AddScriptMessageHandler(this, "invokeAction");
        }

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                userController.RemoveAllUserScripts();
                userController.RemoveScriptMessageHandler("invokeAction");
                HybridWebView hybridWebView = e.OldElement as HybridWebView;
                hybridWebView.Cleanup();
            }

            if (e.NewElement != null)
            {
                base.OnElementChanged(e);
                var assembly = IntrospectionExtensions.GetTypeInfo(typeof(SfChatbot.iOS.HybridWebViewRenderer)).Assembly;
                Stream stream = assembly.GetManifestResourceStream("SfChatbot.iOS.Resources.ChatUAT.html");

                string content1 = "";
                using (var reader = new System.IO.StreamReader(stream))
                {
                    content1  = reader.ReadToEnd();
                }

                LoadSimulatedRequest(new NSUrlRequest( new NSUrl("https://service.force.com/embeddedservice/5.0/esw.min.js")), content1);
                
            }
        }

        public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
        {
            ((HybridWebView)Element).InvokeAction(message.Body.ToString());
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                ((HybridWebView)Element).Cleanup();
            }
            base.Dispose(disposing);
        }

        //not being used
        public string LoadUATData()
        {
            var uri = new UriBuilder("https://run.mocky.io/v3/37c8-1f4501adeeff").Uri;
            ServicePointManager.ServerCertificateValidationCallback = new
                RemoteCertificateValidationCallback
                (
                   delegate { return true; }
                );
            var client = new WebClient();
            var content = client.DownloadString(uri);

            //SMS UAT
            var content1 = content.Replace("t1", "https.my.salesforce.com").
               Replace("t2", "https://.cs81.force.com").
               Replace("t3", "00D260009").
               Replace("t4", "5260000004C").
               Replace("t5", "573200004").
               Replace("t6", "EmbeddedServiceLiveAgent_Parent04I260000000AIbca0f71c").
               Replace("t7", "https://salesforce.com/embeddedservice/5.0/esw.min.js").
               Replace("path", "src");

            return content1;
        }
    }

Salesforce提供javacript文件,我们需要将其转换为 html 格式并分别保存在 Assets 和 Resource 文件夹中 androidiOS .如果任何页面没有 CSS应用(执行后,在输出中),你需要添加Lightings CSS head 中的样式html 的标签文件。

如果键盘有任何问题是在打字时隐藏屏幕,请寻求帮助 this .从 this question 获取 Salesforce 聊天文件的格式.

关于c# - 如何使用 xamarin 表单开发 salesforce 聊天机器人,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71414615/

相关文章:

c# - 使桌面客户端无需更新即可使用较新的 EF 数据库迁移

.net - 强制 PowerShell 使用 .NET CLR 版本 2

c# - 弹出式导航 - iOS

c# - 为什么这个 .net UIAutomation 应用程序会泄漏/合并?

c# - Visual Studio 发布 Web 部署出现 ERROR_USER_NOT_ADMIN 错误

javascript - 当 View 中的函数完成时重新加载部分 View ?

c# - 显示 FolderbrowserDialog 后不会触发某些事件

c# - 这个 "Lambda Expression"是做什么的?

android - obj/Debug/android/src/{name space} 的目录名是 MD5 哈希吗?

xamarin - Skia View 中的透明部分