.net 如何用xamarin表单开发销售聊天机器人

zujrkrfu  于 2023-02-26  发布在  .NET
关注(0)|答案(1)|浏览(111)

我想用xamarin forms应用程序开发Salesforce聊天机器人。我找不到什么sdk或nuget包,我应该使用。似乎没有关于这方面的可用信息。
This salesforce article,我已经发现,在那里他们这样做的Android和iOS。
我已经尝试过使用.jar文件的android库,但不工作,为iOS开发也需要单独.我找到了this article,但不知道什么包,哪个平台,他们正在开发.
如何将Salesforce Einstein聊天机器人与Xamarin表单集成。有人能帮我解决这个问题吗?

zkure5ic

zkure5ic1#

Jar文件,nuget包对我不起作用。我刚刚使用了带有自定义渲染器的webview。这就是我如何设法集成Salesforce chatbot

public class SfChatbotViewModel : BaseViewModel
{
    public SfChatbotViewModel()
    {

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

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

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格式并分别保存在androidiOS的Assets和Resource文件夹中。如果任何页面未应用CSS(执行后,在输出中),则需要在html文件的head标签中添加Lightings CSS样式。
如果键盘在键入时隐藏屏幕有任何问题,请从this获取帮助。从this question获取Salesforce聊天文件的格式。

相关问题