How to use Bot Service in Xamarin.Forms project (WebView version)

Background

Nowaways Microsoft focuses on the Azure products especially in the AI area. This article is to demonstrate how to migrate Bot Framework into Xamarin.

The reason why I wrote this article is simple. I support Xamarin product in MS, and I’d love to learn the technology for Bot. After this article, I will write different topics also, such as how to migrate Azure Cognitive Service to Xamarin, etc.

Technical Skills

  • Xamarin (WebView)
  • Bot Framework (Web Chat)

What you need to know

You should have some basic knowledge on Xamarin and Bot Framework to read this article. This article will demonstrate how to migrate a Web App Bot into Xamarin application. Since it’s a web app bot, so it’s possible to use it directly in the WebView.

There will be one more artile regarding how to use Direct Line Service as the channel to communicate between Bot and Xamarin. In that case, the channel of the Bot will be Direct Line.

Implementation

Prerequisite

Follow MS offical document:Create a bot with Bot Service to create a basic Bot Service。

Notice: if you are just doing this for testing, you can use F0 for free. Other settings can all be default.

Main Concepts

This approach is not very good actually. There will be some disadvantages in this approach which I will mention later.

To embedded the Bot into WebView, we have 2 approaches:

  • Use the secret key to get the access token, and use the token to generate the URL to embed. (Option 1)
  • Directly use the secret key to generate the URL and embed. (Option 2)

Option 1 - Keep your secret hidden, exchange your secret for a token, and generate the embed

First let me introduce the pros and cons.

Pros:

Since the token is got via a GET Web Request, so the token is unique and random, which cause the URl will also be unique. So the best pro for this approach is: other people will not be able to get the URL and use your Bot Framework to their own applications.

Cons:

The process is more complicated. And since needs to use a web request to get the token, so there might be more time-cost for this approach to render the WebView than directly use the secret key.

Option 2 - Embed the web chat control in your website using the secret

Pros:

Quite straightforward, and the time-cost should be less then Option 1.

Cons: As long as other people got the URL, anyone can embed the Bot Framework to their own websites or WebView.

Get the Secrect Key for your Bot

  1. Sign inAzure portal

  2. Find the Web App Bot from your Resource Group, click it to get in the detail page.

  3. Click the Channels from the menu in the left pane.

    Azure Bot Channels

  4. Find the secrect key from the correct Channel. Here we need to find from the Web App Channel. Click Edit.

    Edit Web Bot Channel

  5. Get a key there. Notice that there will be 2 keys by default, and they can be re-generated.

    Bot Keys

Detail steps to migrate to Xamarin.Forms project

Here we will only use the Option 1 mentioned above, which is to get the token to generate the URL.

  1. Create a cross-platform Xamarin.Forms app based on .NET Standard template.

  2. By default we will use the MainPage.xaml as the start page. We will put a Label there to welcome us for using this WebView Bot, and another button to navigate to WebView page which will host our Bot.

    Code in MainPage.xaml:

    1
    2
    3
    4
    5
    <!-- Below code is inside the ContentPage -->
    <StackLayout>
    <Label Text="Welcome to WebView Bot!" VerticalOptions="Center" HorizontalOptions="Center" />
    <Button Text="Go to Bot!" x:Name="WebViewButton" VerticalOptions="Center" HorizontalOptions="Center" />
    </StackLayout>
  3. In MainPage.xaml.cs code behind file, we will do couple of things. First we will implement the method to get the token, we will use HTTP GET method to post Web Request. Code as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    private async Task<string> GetBotServiceToken()
    {
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("BotConnector", "YOUR_BOT_SECRET");

    var url = new Uri("https://webchat.botframework.com/api/tokens");
    var response = await client.GetAsync(url);

    if (response.IsSuccessStatusCode)
    {
    var content = response.Content.ReadAsStringAsync();

    string token = JsonConvert.Deserialize<string>(content);

    Application.Current.Properties["botToken"] = token;

    return token;
    }

    return String.Empty;
    }
  4. Then we will implement the Click event for the WebViewButton. Code as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private async void WebViewButton_Clicked(object sender, EventArgs e)
    {
    string token = String.Empty;

    if (String.IsNullOrEmpty(Application.Current.Properties["botToken"].ToString()))
    {
    // Get the token from HTTP Request
    token = await GetBotServiceToken();
    }
    else
    {
    token = Application.Current.Properties["botToken"].ToString();
    }

    await Navigation.PushAsync(new BotWebViewPage(token));
    }
Notice that I used the `Application.Current.Properties` to store the token. In that case, if the user happened to go back to the previous page, we will not need to get the token again until the token expires.
  1. Now we create a new page (ContentPage) called BotWebView. There is only one WebView element in that page. Code as below:

    1
    2
    <WebView x:Name="BotWebView" VertialOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
    </WebView>
Notice that we did not assign the value to the `Source` attribute. This is due to the URL will be generated in the backend code.
  1. Now in the code behind source code file, we need to re-define one constructor for this page. First we need to get the value of the token which will be pushed by the MainPage. The other thing is that we will directly assign the URL to WebView.Source. Code as below:

    1
    2
    3
    4
    5
    6
    7
    public BotWebView(string token)
    {
    InitializeComponent();
    // Notice to replace the YOUR_BOT_NAME
    string botWebViewUrl = "https://webchat.botframework.com/embed/YOUR_BOT_NAME?s" + token;
    this.BotWebView.Source = botWebViewUrl;
    }
  1. After these steps, the demo should be working now. But there is a small bug there, which is the WebView will not be resized when click on the Input textbox in the Bot WebView under Android. This is unreasonable, but it’s true and it’s by-design.

    To fix this, we need to add below code to the constructor of the App function under App.xaml.cs file. Code as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public App()
    {
    InitializeComponent();

    // Need to add below code
    Xamarin.Forms.PlatformConfiguration.AndroidSpecific.Application.SetWindowSoftInputModeAdjust(this, Xamarin.Forms.PlatformConfiguration.AndroidSpecific.WindowSoftInputModeAdjust.Resize);

    MainPage = new NavigationPage(new XAMBotWebView.MainPage());
    }

Now the demo is totally completed.

Additional Content

There will be some potential issue with this demo. Based on my testing, this approach will work better in normal website’s iframe element. But if we used it on mobile app, after several times switching back to previous pages, there will be some issue that the bot will stuck and not work anymore.

But there is advantage for this approach is that this is really very easy to implement and you don’t need to have so much experience in developing Xamarin application.

If you do not have time to learn and you want to have a simple bot working on your mobile app, use this method!

How to use Bot Service in Xamarin.Forms project (DirectLine version) Troubleshooting for Xamarin.Android binding project
You need to set install_url to use ShareThis. Please set it in _config.yml.

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×