Use ContinueDialogAsync in ProActive message after ending dialog turn - botframework

I am trying to 'pause' a bot conversation and resume it via a ProActive Message.
The way I have been trying to do so is by ending the dialog turn to 'pause' the conversation. Following I'm using ContinueDialogAsync in my ProActive message to 'resume' the conversation. Below is how I'm doing this as part of the ProActive message:
DialogManager dialogManager = new DialogManager(this.resourceExplorer.LoadType<AdaptiveDialog>(this.resourceExplorer.GetResource("echobot-final.dialog")));
dialogManager.UseResourceExplorer(this.resourceExplorer);
dialogManager.UseLanguageGeneration();
var conversationStateAccessors = conversationState.CreateProperty<DialogState>(nameof(DialogState));
var dialogSet = new DialogSet(conversationStateAccessors);
dialogSet.Add(dialogManager.RootDialog);
var dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken);
However, when running the ContinueDialogAsync after the dialog turn had been ended previously, I run into this error:
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=Microsoft.Bot.Builder.Dialogs.Adaptive
StackTrace:
at Microsoft.Bot.Builder.Dialogs.Adaptive.Generators.ResourceMultiLanguageGenerator.TryGetGenerator(DialogContext dialogContext, String locale, LanguageGenerator& languageGenerator)
I'm not getting this NullReferenceException though when removing the EndTurn from the dialog, so I believe I my dialogContext object should be correct?
Am I misunderstanding the concept of ending a dialog turn?
What is the correct approach to pause a conversation, and resume the conversation later?

In the Bot Framework, a turn is the time between the bot receiving an activity in an HTTP request and the bot responding to that request. Note that responding to an HTTP request is different from replying to an activity. The bot can reply by sending new activities to ABS in their own HTTP requests, and it can do this many times in a turn. The HTTP response is not another activity, it's just a status code (like 200 OK) that signifies the end of the turn.
There's not really a concept of a "dialog turn." There are "steps" in waterfall dialogs and adaptive dialogs, though they don't correlate to turns since a step can span multiple turns and a turn can span multiple steps. There is an "End Dialog Turn" action in adaptive dialogs which I think is what you're talking about, but it just ends the turn. The word "Dialog" may be superfluous/misleading there.
There also isn't really a concept of "pausing" a conversation. A conversation is understood to be a series of turns and activities exchanged between a bot and one or more users. Your bot always needs to know what to do about every request that reaches its endpoint, so it's up to you to define what pausing a conversation means.
I'm guessing you want the bot to respond differently or not respond at all while the conversation is paused. You will need some sort of bot state for the bot to know that it's paused for a given user or conversation, and dialogs use bot state so a dialog would do. Whatever you do to indicate to the bot that the conversation is paused, you can just undo it to unpause it. Just ending the turn won't work because that doesn't add anything to state and the next turn will start as soon as the user sends a message.

Related

Is there a way to allow multiple responses per Slack channel for a form sent through Workflow Builder?

I've set up a workflow (with Slack Workflow Builder) to send a survey to a channel, asking for feedback. I want everyone to be able to answer it, but as soon as one person responds the workflow completes.
Going back to the setup I see the message "If you send this form to a channel, keep in mind that only one person can click the button to submit a response."
If I can't send to more than one person at a time, and I can't get multiple people in a channel to respond, is there any other workaround I could try?

MS Teams Bot - Detect user is typing

I have a MS Team bot, and I'd like to greet user when they start using the bot again.
So I try to use the ActivityTypes.Typing to do so, but it seems MS Teams hasn't supported it yet.
Is there anyone has experience with it or can suggest other solution?
Thanks.
no, user installs the bot as an app so user doesn't uninstall it but
stop using it for a while and then they want to use it again. I think
their behavior would be click to the bot app, start typing, and send
message. I'd like to greet them before they send the message
Unfortunately, this is not possible. For sure not with Teams. onMembersAdded only ever gets fired once. There is no event that would be sent to the bot to tell it that the user is going to be sending a message. I'm not sure which, if any, channels/clients that would send a typing indicator to a bot. I don't know of any that do. Bot's don't typically receive typing activities, only send. You might be able to get that to work, but that wouldn't really help unless the channel/client supported that feature.
I think the best you could do is to have logic to store the last time the user messaged or the bot responded. Then, when the user sends their new message (after that predetermined amount of time away), then the bot could respond with a message before its response.
For example:
last message/active time for this user was 2 days ago
user messages bot with "i'd like to rent a car"
code logic determines it has been long enough to warrant a comment on that:
bot messages with "It's been a while since we chatted, welcome back!"
bot messages with response to intent: "Sure! what make of car would you like to rent?"

How to make Trigger Action by Reaction Posted on MS Teams

I am making bot works for Microsoft Teams.
Goal: To make bot to detect reaction posted for any messages in the user's MS teams channel.
Problems:
Using onReactionsAdded in activityhandler(MS BotFramework) , my bot detects the reaction posted only for the bot messages
Is there any possible way to make trigger action by posting reaction for users' posts in MS Teams?
This is similar to the fact that you Bot won't receive every single message posted in the channel / group chat - only those that "#mention" your bot. It's different in a 1-1 chat with the bot though - there it will receive everything. If you want to make sure you get every single reaction, you'd need to call the Graph for that. See Get a reply to a channel message as an example - right near the bottom of the page it shows "reactions" (it's empty in that example).
#Cambria a Bot receive's the reactionAdded event only when there is a reaction on a message the Bot itself posted. Reacting on a user's post does not trigger an event with the Bot.

Dialog Event that First on Bot Response

BotFramework documentation refers to handling user interruption via OnContinueDialogAsync event, which first when user sends a response but before it hits the dialog.
I was wondering if there is an event that fires when Dialog completes a step but before it is returned to the user. Reason I ask is because I need to sanitize the response to the user through an additional layer, and want it to fire for all bot responses.
Middleware was designed, and can be used, for exactly this scenario.

Proactive Interruptions

I am using an Azure Function to send a Proactive message to the client. How do i "reset" a conversation when a Proactive message is sent.
Within the bot, a user might be prompted for something (ex. time of day). A proactive message may get sent to them before they respond. In this scenario, I would like to reset/cancel the previous dialog and start fresh.
I am already able to reset the dialog using CancelAllDialogsAsync which works fine for user-driven messages.
I am sending my proactive message using ConnectorClient, which bypasses the framework, and sends directly to the client, thus never hitting my middleware to reset the dialog.
How can I get the proactive message sent to the framework (i can send the response from the bot no problem)
I would highly recommend you solve this by having your function send your bot a backchannel event under the context of the ConversationReference via the ConnectorClient. This way the bot maintains ownership for all the details about state and what should happen when this event occurs rather than that responsibility leaking to the function. The bot then watches for this custom event and responds to it however it sees fit.
If you need any more details let me know and I'll update my answer.

Resources