3

I'm trying to send and receive events from an embedded webchat which follows the code for the website from this example https://github.com/ryanvolum/backChannelBot and the bot implements the code from Bot framework get the ServiceUrl of embedded chat control page answered by ezequiel

Here's how it all looks in my setup index.html

<!DOCTYPE html>
<!-- 
NOTE: This sample requires a bot which can send and receive specific event messages. Follow the instructions on 
https://github.com/ryanvolum/backChannelBot to deploy such a bot. 
This is a sample HTML file which shows how to embed an instance of WebChat which listens for event activities. For the sake
of demonstration it specifically listens for events of name "changeBackground". Using the backChannelBot sample 
our page can listen for events of name "changeBackground" and send events of name "buttonClicked". This 
highlights the ability for a bot to communicate with a page that embeds the bot through WebChat. 

1. Build the project: "npm run build"
2. Start a web server: "npm run start"
3. Aim your browser at "http://localhost:8000/samples/backchannel?[parameters as listed below]"
For ease of testing, several parameters can be set in the query string:
    * s = Direct Line secret, or
    * t = Direct Line token (obtained by calling Direct Line's Generate Token)
    * domain = optionally, the URL of an alternate Direct Line endpoint
    * webSocket = set to 'true' to use WebSocket to receive messages (currently defaults to false)
    * userid, username = id (and optionally name) of bot user
    * botid, botname = id (and optionally name) of bot
-->
<html>

<head>
    <meta charset="UTF-8" />
    <title>Bot Chat</title>
    <link href="../../botchat.css" rel="stylesheet" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <style>
        .wc-chatview-panel {
            width: 320px;
            height: 500px;
            position: relative;
        }
        .h2{
            font-family: Segoe UI;
        }
    </style>
</head>

<body>
    <h2 style="font-family:Segoe UI;">Type a color into the WebChat!</h2>
    <div id="BotChatGoesHere" class="wc-narrow"></div>
    <button onclick="postButtonMessage()" style="width:120px;height:60px;padding:20px;margin-left:80px;margin-top:20px;">Click Me!</button>

    <script src="../../botchat.js"></script>
    <script>
            var params = BotChat.queryParams(location.search);
            var user = {
                id: params['me'] || 'userid',
                name: params["tester"] || 'username'
                };

            var bot = {
                id: params['somebot'] || 'botid',
                name: params["somebot"] || 'botname'
            };
            window['botchatDebug'] = params['debug'] && params['debug'] === "true";
            var botConnection = new BotChat.DirectLine({
                secret: params['mysecret'],
                token: params['t'],
                domain: params['ngroktunneledurl.com/api/messages'],
                webSocket: params['webSocket'] && params['webSocket'] === "true" // defaults to true
            });
            BotChat.App({
                botConnection: botConnection,
                user: user,
                bot: bot
            }, document.getElementById("BotChatGoesHere"));
            botConnection.activity$
                .filter(activity => activity.type === "event" && activity.name === "changeBackground")
                .subscribe(activity => changeBackgroundColor(activity.value))
            const changeBackgroundColor = (newColor) => {
                document.body.style.backgroundColor = newColor;
            }
            const postButtonMessage = () => {
                botConnection
                    .postActivity({type: "event", value: "", from: {id: "me" }, name: "buttonClicked"})
                    .subscribe(id => console.log("success"));
            }
        </script>
</body>

</html>

And the bot file MessagesController.cs

using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using Kaseya_AI_Kbot.LuisDialog;

[BotAuthentication]
public class MessagesController : ApiController
{
   public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        if (activity.Type == ActivityTypes.Event &&
            string.Equals(activity.Name, "buttonClicked", StringComparison.InvariantCultureIgnoreCase))
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // return our reply to the user
            Activity reply = activity.CreateReply("I see that you just pushed that button");
            await connector.Conversations.ReplyToActivityAsync(reply);
        }

        if (activity.Type == ActivityTypes.Message)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // return our reply to the user
            var reply = activity.CreateReply();
            reply.Type = ActivityTypes.Event;
            reply.Name = "changeBackground";
            reply.Value = activity.Text;
            await connector.Conversations.ReplyToActivityAsync(reply);
        }
        else
        {
            HandleSystemMessage(activity);
        }
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

    private async Task HandleSystemMessage(Activity message)
    {
        if (message.Type == ActivityTypes.DeleteUserData)
        {
            // Implement user deletion here
            // If we handle user deletion, return a real message
        }
        else if (message.Type == ActivityTypes.ConversationUpdate)
        {
            if (message.MembersAdded.Any(o => o.Id == message.Recipient.Id))
            {
                ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl));

                var reply = message.CreateReply();

                reply.Text = "Welcome to the bot!";

                await client.Conversations.ReplyToActivityAsync(reply);
            }
        }
        else if (message.Type == ActivityTypes.ContactRelationUpdate)
        {
            // Handle add/remove from contact lists
            // Activity.From + Activity.Action represent what happened
        }
        else if (message.Type == ActivityTypes.Typing)
        {
            // Handle knowing tha the user is typing
        }
        else if (message.Type == ActivityTypes.Ping)
        {
        }
    }

    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        if (activity.Type == ActivityTypes.Event &&
            string.Equals(activity.Name, "buttonClicked", StringComparison.InvariantCultureIgnoreCase))
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // return our reply to the user
            Activity reply = activity.CreateReply("I see that you just pushed that button");
            await connector.Conversations.ReplyToActivityAsync(reply);
        }

        if (activity.Type == ActivityTypes.Message)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // return our reply to the user
            var reply = activity.CreateReply();
            reply.Type = ActivityTypes.Event;
            reply.Name = "changeBackground";
            reply.Value = activity.Text;
            await connector.Conversations.ReplyToActivityAsync(reply);
        }
        else
        {
            HandleSystemMessage(activity);
        }
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }
}

}

I've tested sending message activities which works fine, however trying to send an event from the bot to the webpage or from the webpage to the bot after receiving a message doesn't do anything.

The webpage says that BotChat is not defined at both but I'm not sure why

var params = BotChat.queryParams(location.search);

and

var botConnection = new BotChat.DirectLine({

in index.html

All of my app secrets/id and directline secret are added. I feel like the problem might be how I'm adding my secret and url in index.html but I'm not sure how I would set it all up

Community
  • 1
  • 1
Teragon
  • 239
  • 3
  • 13
  • Have you tried hard coding your secret and token temporarily, instead of relying on params? (just until you get it working, then add the parameters) – Eric Dahlvang Apr 24 '17 at 23:32
  • I attempted to hard code my secret and domain like this var `botConnection = new BotChat.DirectLine({ secret: "My_DirectLine_Secret_Here", domain: "https://xxxxxxxx.ngrok.io/api/messages" });` But that didn't seem to work. I'm not sure if its because I'm adding it wrong (very new to JS) – Teragon Apr 25 '17 at 16:47
  • The domain is to specify a different direct line endpoint: https://github.com/Microsoft/BotFramework-WebChat#user-content-named-direct-line-endpoint ... not the endpoint for your bot messages. Please try removing "domain: etc." – Eric Dahlvang Apr 25 '17 at 18:01
  • Okay so I've just changed it to `var botConnection = new BotChat.DirectLine({ secret: "My_directLine_Secret", });` Anytime I run the index.html locally it says says BotChat is not defined with the chrome console. Do I have to add some dependency to the web folder? – Teragon Apr 25 '17 at 18:13
  • It is easiest to just have the .css and .js files in the same directory when running locally. I tested this out, and it works as you expect it to: https://github.com/EricDahlvang/BackChannelEventTest/tree/master/TestStandalone – Eric Dahlvang Apr 25 '17 at 21:31

1 Answers1

2

I re-created your project and published it to Azure: http://QuickBackChannelEventTest.AzureWebsites.net/index.html

I posted the code on GitHub. You'll need to change the MicrosoftAppId and MicrosoftAppPassword in the web.config, and add your bot's Direct Line secret to the index.html page's BotChat.DirectLine creation:

var botConnection = new BotChat.DirectLine({
            secret: '**DIRECT_LINE_SECRET**',//params['mysecret'],
            //token: params['t'],
            //domain: params['ngroktunneledurl.com/api/messages'],
            webSocket: params['webSocket'] && params['webSocket'] === "true" // defaults to true
    });

I also added a folder called TestStandAlone that contains only Index.html, botchat.css and botchat.js: https://github.com/EricDahlvang/BackChannelEventTest/tree/master/TestStandalone This works as expected once the the Direct Line secret for the bot is set.

Eric Dahlvang
  • 8,252
  • 4
  • 29
  • 50