-3

I am building a chat bot via the Microsoft bot framework and recently deployed it as web-chat on a web page. In my web page, it is essential that I have a side box where data is shown that is gathered and calculated from the bot.

Can anyone help me to create this? Right now, I don't know how to create this window/box/iframe.

My chatbot negotiates with the user. I want to show the user data like the items that are available for negotiating in a kind of information box. It should be able to refresh it after an event that happens during the chat. So far, i implemented the web chat with inside the html code of the webpage as it is described by the Microsoft docs for web chat.

Script47
  • 14,230
  • 4
  • 45
  • 66
but28
  • 19
  • 1
  • 7
  • Can you please add some code snippets or add some details regarding different approaches you have tried? Are your trying to build off of one of the WebChat samples, or are your using a framework like React or Angular? – tdurnford Apr 09 '19 at 18:18
  • Thanks for your comment. Actually, I don´t know how to approach this. I am not familiar with React or Angular. Should this help with my issue? I checked the webchat samples in github but I couldnt find a fitting sample. To clarify: I have a html page. In the left side of the page should be the web chat running and in the right sight a container/box that shows data from the chat bot. The bot is written in js node. As it needs data from the chatbot it needs to communicate anyhow with the bot. I dont know how to build it.. – but28 Apr 10 '19 at 11:46

1 Answers1

1

The easiest way to display information gathered from the chat is to send back channel events from the bot with the data and then intercept the message with a custom activity middleware in WebChat. Then you can process the data on the webpage however you'd like.

Bot - NodeJs SDK v4

In the bot, we are going to send back channel events to WebChat with the data we have gathered in the chat. Basically, you just need to send an activity with the type property set to 'event' and the name attribute set to some string value - we are going to use data in this case. The conversation data is going to be encapsulated in the activity's channel data.

await step.context.sendActivity({name: 'data', type: 'event', channelData: data});

WebChat - Custom Middleware

In WebChat, we are going to implement a custom middleware that is going to check incoming activities for the type and name values we specified earlier. When we do encounter a back channel event, we can handle the incoming data and update the web page.

const store = createStore(
  {},
  ({ dispatch }) => next => action => {
    if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
      let { channelData, name, type } = action.payload.activity;
      channelData || (channelData = {});

      if(type === 'event' && name === 'data') {
        this.props.handleData(channelData);
      }
    }
    return next(action);
  });

Screenshot

enter image description here

Since WebChat is built with React, I would highly recommend building this web page with React as well. There is already a sample - customization-selectable-activity - that splits the page into two columns with WebChat in one column and an activity inspector in the other. You could easily modify this sample to meet your requirements by adding the custom middleware to WebChat in this sample and changing the inspector view to a data table.

Requesting WebChat Token

Note, for the simplicity of getting started,you can fetch the DirectLine token from the client side; however, it is recommended that you create a backend REST API to generate and manage your tokens.

const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', 
{ 
  method: 'POST',
  headers: {
    'Authorization': `Bearer <SECRET>`,
    'Content-Type': 'application/json'
  },
});

const { token } = await res.json();

Hope this helps.

tdurnford
  • 3,632
  • 2
  • 6
  • 15
  • Thanks for the comment. Yes it helps but i am still struggling in how to display the data when i got the event from the bot. I tried to rebuild the suggested sample but the webpage wouldnt let me see any content (i assume, because the index.html file is in 'public' folder). If i would be able to run the sample with my bot I hope it would be easier for me to see what i could change for my task. For this sample there is no documentation, though, and like this difficult to understand. – but28 Apr 17 '19 at 23:36
  • to be more concrete: do you have a simple idea for the handleData function from above to display the data in a data table? – but28 Apr 17 '19 at 23:45
  • To connect the sample to your bot, you need to pass in a token for the bot in the WebChat.js file - currently it is retrieving a token from MockBot. The handleData function should be passed in as a prop from WebChat's parent and called in the middleware. Basically, it should just add the data to the parent's state, and then react should update the data view if you have passed the state elements as props to the data view. – tdurnford Apr 18 '19 at 17:56
  • thank you very much @tdurnford. So far i have put the secret directly into the code because i dont know how to generate the token for my bot. It is not clear to me where i do have to put the code for the http request. Maybe you can also help me with that? I tried this in Webchat.js instead of the MockBot-Line (ln 21): const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', {method: 'POST', header: 'Bearer' + 'SECRET'}); but this doesnt work.. alternatively: is there another solution where i just put the secret in code instead of using tokens? – but28 Apr 20 '19 at 11:34
  • I just updated my answer with how to generate a WebChat token. Note, you can do this from the client side; however, it is recommended that you create a back end service to generate and manage your tokens. – tdurnford Apr 20 '19 at 16:58