How can I add a middleware logger to my bot? - botframework

I tried to add telemetry services following this tutorial, but I looked at my logs in azure and I didn't see user messages. How can I add a middleware that can save user's conversations?
What I'm trying to do is to capture the messages that LUIS and QnA could not find an answer for. So we want to log these so we can improve our bot in the future.
I know LUIS has this feature already in luis.ai, but we want to add more information than what LUIS captures.

You have to do a custom implementation for storing user conversations. I have used Azure Table in one of my implementations to store the conversation. The table structure will have the conversation id + user id as the unique key and then storing the conversation in json format in the table. The conversation data is updated by intercepting every message sent to and from the bot. You can refer this MSDN article for a reference implementation.

Related

Can I create a configuration page for a Teams bot app?

I'm building my first Teams app which will have two primary functions:
Proactively send a message to the channel (the bot is installed into) when a specific event occurs on my backend.
Members of the channel reacts to the message via actions.
I finally have a pretty good idea of how to set this up (I think) - but one part I'm missing is that in order to identify the specific app installation as belonging to one of my customers, I need to be able to allow the installing user to supply extra information like e.g. an API-key so that I can associate the specific channel with my specific customer.
Is there any way of doing this with a bot app? I've found examples for creating a configuration page, but they all seem to be associated with tab apps?
I could of cource have the bot ask the user for the information - but maybe there's a "cleaner" way?
Any examples or tutorials would be greatly appreciated as I find it rather hard to get stuff working using Microsoft's own examples etc. :)
Thanks a lot!
When you receive any message from the user, either by typing to your bot, or even installing it into a channel, group chat, or personal context (where you get the conversationUpdate event), you are able to get specific details off of the activity object. If the user sends a message, for instance, then the text property on the activity object will have a value. Incidentally, this is the same activity you will use to get the conversation details you need for the Proactive message.
With regards your question, the activity class also includes a tenantId property, hanging off the conversation property. This is the unique Microsoft 365 Id for the tenant, which would be what I'd suggest to uniquely identify them for your API, or licensing, or similar.

Add members to an existing conversation

(New to Bot Framework)(Using botbuilder SDK4) I have a requirement of passing the control to an agent in case the bot does not recognise the intent of the phrase entered by the customer. I want to connect the customer and the agent using the bot. In my current attempt to achieve this, I am using adapter.continueConversation(conversationReference, logic)
But then I realised, there is an entity called members in the conversation (there exists a method getConversationMembers in botframework-connector/lib/connectorApi/operations/conversations.d.ts).
Question 1: Can I use this attribute for the aforementioned use case?
Question 2: How to add multiple members in a conversation?
Creating a custom middleware is the most efficient way to handover a conversation from the bot to an agent. Here is an example of a bot that implements middleware to forward messages between users and agents with proactive messages. The example uses an array based handover provider to save the state of every conversation. You should implement your own provider with a database structure to fit your project requirements.
Hope this helps.

Questions about saving bot state

I read through this https://learn.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-state about saving state data. I have some questions regarding the same:-
Lets take a bot exposed through the browser channel as an example here:-
What is the lifetime of the data stored? For instance when the bot saves data using context.ConversationData.SetValue(..) Is the data purged when the session is over(when the user refreshes the page)?
The From object from Activity has Id and Name. Are these generated by the channel each time a chat session begins? For instance, if I was chatting with bot then refresh the web page, now will my Id and Name have changed?
Same question about conversation. If I refresh the page and begin the conversation again, do I get a new conversation ID?
I read in some blog that if you use dialogs, the dialog stack state is automatically saved in whichever storage you have configured. Is this correct? If so, why? Say I refresh the page, will I be able to retrieve the state of the dialog stack and resume the conversation from there?
If you are giving code samples, request you to give C# samples if possible
Thanks very much in advance!
Hi, I hope below answer will find useful to you :
1.
What is the lifetime of the data stored? For instance when the bot saves data using context.ConversationData.SetValue(..) Is the data
purged when the session is over(when the user refreshes the page)?
ANS:->
As per the guidelines by Bot Framework, State API is in the state of depreciation. you will have to use your own state management service to maintain the state of your Bot. Ref: https://learn.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-state
So assuming you are using Table Storage or SQL Database for storing your bot in this case the data will persist as long as your storage account and database available.
2.
The From object from Activity has Id and Name. Are these generated
by the channel each time a chat session begins? For instance, if I
was chatting with bot then refresh the web page, now will my Id and
Name have changed?
ANS:->
This depends on how you initialize the chat. for instance, if you are using
Web chat : It will be empty id.
Skype : It will be skype id and user name
DirectLine : you can define your own id and name as per your need.
3.
Same question about the conversation. If I refresh the page and begin the conversation again, do I get a new conversation ID?
ANS:->
Yes. Every time you refresh your webpage you will be assigned new conversationId but in case of DirectLine you can use the previous conversation id to maintain the history of your conversation. you can store the conversation id in local storage or in browser's cookies and read whenever you feel to load the chat history. If you don't need history to be preserved then I suggest let webchannel handle its own ids.
4.
I read in some blog that if you use dialogs, the dialog stack state is automatically saved in whichever storage you have configured. Is this correct?
ANS:->
Yes.
5.
If so, why? Say I refresh the page, will I be able to retrieve the state of the dialog stack and resume the conversation from there?
ANS:->
As hinted earlier, you will need to migrate your bot to use DirectLine API instead of webchat channel. As webchat doesn't support history so DirectLine.
Please refer the guidelines provided by Microsoft and Samples provided on GitHub.
https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-concepts
Quick answers:
As far as I know, there is no purge. And you can check the implementations of Azure DocumentDbBotDataStore or TableBotDataStore here. Based on my implementations, I saw there is a Timestamp column in the stored data so you could do cleanup based in that.
Generation of Id and Name fields (for From, but also for Recipient given the message origin / destination): yes they depend on the channel. I made a detailed answer about on SO: Bot Framework User Identification
Yes in the webchat's case
Yes, the dialog stack state is saved so that you can continue your conversation. "Say I refresh the page, will I be able to retrieve the state of the dialog stack and resume the conversation from there?": if you have the same details (channelId + conversationId, userId) you should yes. The exception is the webchat / directLine where you have to implement the fact that you keep the same IDs. For other channels like Slack, Facebook Messenger etc, these items remains the same and the dialog can continue where it stops on the previous messages exchange

Add unique key of my own to slack event requests

I created a slack app with distribution (multiple clients)
and I subscribe to events several events like a message posted in a channel.
Beside the team_id field for identifying the client team - is there an ability to put my own key for a client?
Thank you.
No, Sack does not store any custom data for you. Its your job as an app developer to store all team related information for your app and link it to the Slack team_id. This is usually done with a database.
You can however include custom IDs with Slack requests, e.g. in the response you get from an interactive message. See this answer for more details on how this works.

How do I correlate user between channels?

From what I see, Bot Framework is providing an abstraction over users in different channels by providing a ChannelAccount class that has ChannelId/Address pair to identify user via its account and Id property, which is... okay, here's the question.
I suppose that the idea behind Id is to provide a unique and persistent identifier that can be used to cross-correlate users between account (i.e., I can say that Slack user #alpha is also email user alpha#company.con). This idea is supported by the fact that ChannelAccount for my bot always has same Id regardless of the channel (and Address is different between channels, obviously).
If this is right, and I hope it is, is there any way to provide BotConnector with the correlation information? I.e., I want BotConnector to give me ChannelId/Address, and I'd give back user Id which I'd the get back in incoming message.
The purpose of this is quite simple: I want the code inside my bot to use the Id as already correlated identifier so that I can log it, build logic from it and so on.
BotFramework does not yet support linking of accounts. In the interim, take a look at this post for one way you might implement a solution:
Why isn't BotUserData persisting and retrievable in my Bot Framework bot?

Resources