Slack interactive message not triggering Post request on my bot - c#

I'm working on a bot using the Microsoft Bot Framework. I'm trying to get it up and running on Slack, and got blocked by an issue regarding interactive buttons. In a waterfall dialog flow, I'm creating a choice prompt like below
private async Task<DialogTurnResult> IdentifyUserTypeAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var message = "Please select what kind of user you are"
userTypes = await userTypeRepository.GetAllUserTypesAsync();
var options = new PromptOptions
{
Prompt = MessageFactory.Text(message),
Choices = ChoiceFactory.ToChoices(userTypes.Select(x => x.UserType.ToString()).ToList()),
Style = ListStyle.HeroCard,
};
await state.ConversationState.SaveChangesAsync(stepContext.Context);
return await stepContext.PromptAsync(UserTypeDialogId, options);
}
On the Slack app, the buttons renders correctly, like in the image below.
However, when I click the buttons, nothing happens. I see the request on my local slack client actually calls my slack app, and returns with a 200.
I have followed this tutorial on setting up the Slack app using ABS:
https://learn.microsoft.com/en-us/azure/bot-service/bot-service-channel-connect-slack?view=azure-bot-service-4.0&tabs=abs
On the slack app I have the following configurations
Redirect URL:
Scopes:
Events are enabled, and I have added the request URL. The black part is my bot handle, taken from ABS
I have subscribed the following Bot events
The bot is configured to be always online:
And lastly, I have enabled interactivity, and added the request URL, which seemed to be validated correctly by the Slack app.
Am I missing something? I have tried to start over multiple times, but I end up in the same situation, where the button doesn't seem to fire anything on my bot code. There's simply no incomming request to the Bot's webserver.

A fix is on the way. In the meantime, there are two workarounds you can try. You can create a classic Slack app, or you can bypass the ABS Slack connector by using the Slack adapter instead.
You can see a discussion of this here: https://github.com/microsoft/BotBuilder-Samples/issues/2553

Related

ShowTypingMiddleware sending typing activities after response is sent to user by the bot

I have created a v4 Bot Framework SDK (C#) based bot. And I am using the two middleware inside the adapter which are in same order -
public AdapterWithErrorHandler(ICredentialProvider credentialProvider,
BotConfigurationSettings configuration,
IUtility utility,
BotStateSet botStateSet,
ConversationState conversationState = null)
: base(credentialProvider)
{
// Show Typing Middleware
Use(new ShowTypingMiddleware(1000, 2000));
// Auto Save State Middleware
Use(new AutoSaveStateMiddleware(botStateSet));
}
The problem is that typing middleware send the typing activity sometimes intermittently and sometimes more frequently after a message is sent to the user and displayed in bot window.
But the side effect of this behavior is that it looks like bot typing another response but then typing indicator disappears.
This is very well reflected when I see that Dependency Call is cancelled in Application Insights.
I have tried to add custom delay and period values, but noting much happens.
Use(new ShowTypingMiddleware(1000, 2000));
I assume the reason might be AutoSaveStateMiddleware is trying to save conversation state and typing middleware is supposed to send activity after a period of delay but soon state is saved and then typing activity is cancelled.
I want to know how we can fix this behaviour.

How to call custom dialogs in MessageController for custom events

Problem statement:
I want to call dialogs from MessageController when custom events are sent to the bot.
Setup:
I have a bot build using Microsoft Bot Framework [v3.15.3]
I have a set of custom events that are sent to the bot from external systems to notify the bot adn ask it to perform actions.
[ Example, MarkUserAsOfflineInBackEndStore ShowExternalActionCompletedMessageToUser]
My users connect to the bot using a web portal that has a webchat connect. This also sends custom events to the bot to notify the bot about user actions
[Example UserClickedOnLogoutFromSite , userNavigatedToDifferentPage]
For these events also the bot has to take some actions.
Problem Statement:
From my message controller I have to redirect to different dialog based on different events that come in.
My current setup is below:
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
if (activity.Type == ActivityTypes.Event)
{
var eventDialog = GetEventDialog(scope, activity);
if (eventDialog != null)
{
await Conversation.SendAsync(activity, () => eventDialog).ConfigureAwait(false);
}
}
else
{
await Conversation.SendAsync(activity, () => scope.Resolve<RootDialog>()).ConfigureAwait(false);
}
}
I want the user ot be able to talk to the bot without error irrespective of the events that are happening. This means that If the bot is waiting for user input using context.Wait(...) the events should not cause unexpected behavior.
I explored calling dialogs using context.Call but could not find a recommended way to get the context reference in messagecontroller.
Looking for suggestion on how to setup the code here.
In my basic scenario,when i send messages one at a time and one event at a time with no waits, it seems to be working correctly. But with complex dialog i get "Sorry my bot code is having an error".
Your issue seems to be based on a common misunderstanding of the MakeRoot delegate in Conversation.SendAsync. The delegate cannot be used to control which dialog the activity is sent to. The reason you have to pass a delegate to begin with instead of just a dialog is because in most cases no new dialog should be constructed. The idea behind Conversation.SendAsync is to send the activity to whatever dialog is on top of the stack. From the documentation:
The MakeRoot factory method is invoked for new conversations only, because existing conversations have the dialog stack and state serialized in the IMessageActivity data.
While I don't know the details of what you're trying to do, I presume you should be able to respond to most events in a way that does not require the use of a dialog. If you're sure you want to send those events to a dialog, you need to keep in mind that there's only one dialog stack and only one dialog on top of the stack, which means you'd need to make sure all of your dialogs are able to handle all possible events gracefully. Please have a look at the documentation to better understand dialogs and dialog flow: https://learn.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-manage-conversation-flow?view=azure-bot-service-3.0

MS Bot Framework - pass data through markdown link

Is it possible to pass data through a markdown link? So for example:
var html = "[link1](test1) [link2](test2)";
var reply = message.CreateReply();
reply.Text = $"Welcome {newMember.Name + html}!";
client.Conversations.ReplyToActivityAsync(reply);
Is there a way to pick up the click event that would let me know which link was clicked?
In bot framework, if you are trying to collect data off of link click (or button of the OpenUrl type). The recommended way is by using a 302 redirect. This is because you generally do not have access to anything from the front end as stuartd is pointing out. For example, if you have a facebook bot how would you capture what the user clicks since nothing is sent to the bot? This is the problem you are running into. You would essentially have to send an activity to the bot when the user clicks a link, but without access to the Facebook front end how do you send that on click?
If you would like to see an example of a 302 redirect in a bot, I have made this example which has both Node and C# versions. This project shows how to do this with a button using the OpenUrl action type but can be applied to a link as well.

MS Teams outgoing webhook application

I have built a bot in Visual Studio using C#, which I have registered with the Bot framework. Its a test bot at the moment, which merely scans the incoming text and returns a message on how many characters are in the message. However, what I want to do is to hook this bot up to a Teams channel and use some sort of trigger (similar to slash commands in Slack) and then take the text from the message and send that to my bot, which will then run some code to forward that data on to an external URL, which would then reply back to the bot and then forward that data into the Teams channel. Does anyone know if something like this is possible? At the least all I need to know is whether I can get some functionality similar to slash commands in Slack, which I can then work with and get the desired outcome from this bot.
Firstly, the issue with Microsoft Teams bots that you either need to talk to them in 101 or mentioned them in a group conversation.
Secondly, the Slack-like commands are not supported and you need to understand the intent of a person. You can use buttons on cards instead.
It can be done in a few ways. The main idea is the following.
Bot: Hello, my name is Pradeep Patel. You can use me like "#pradeep launch ", where what is a parameter for launch command.
User: #pradeep launch rocket
Bot: User, the rocket has been launched.
User: #pradeep try jump
Bot: Sorry, I don't have the command "try" implemented. Please type "help" to find out more information.
You can use multiple tools to recognize intents:
RegEx
Google Api.ai
Microsoft LUIS

Microsoft.Bot.Builder.Location integrated with Cortana skills: issues selecting the address

I am building Chat bot using Microsoft builder SDK for c#. Currently, I have working location dialog using Microsoft.Bot.Builder.Location with Facebook, emulator and Skype channels.
Recently, I have been trying to integrate bot with Cortana channel however Location Dialog does not seem to work as well as in other channels.
Once I select to “enter shipping” it prompts me for the address. I say the address and it updates the page with found possible locations (as carousel cards) and straight after it updates the page prompting me for selection of the correct address out of the possible found. However, I cannot select the correct option as it already updated the page and I can no longer view possible locations.
This is the way I have implemented location dialog:
var locationDialog = this.dialogFactory.Create<LocationDialog>(
new Dictionary<string, object>()
{
{ "prompt", string.Format(CultureInfo.CurrentCulture, Resources.RootDialog_Delivery_Address_Prompt, (await qtyResult).From.Name ?? "User") },
{ "channelId", context.Activity.ChannelId },
{ "apiKey", "apiKey"},
{ "options",LocationOptions.SkipFinalConfirmation | LocationOptions.SkipFavorites},
});
I am wondering Is there a different approach to get user location (shipping address) for Cortana channel? Thank you!
did this ever get resolved? I am currently integrating the BotBuilder.Location library as well, and all is well on the skype, facebook, etc... side, but concerning Cortana, after it prompts "what location are you interested in?" there is no method for input (microphone doesn't open up and text input is disabled).
I had issues with this dialog as well. What I did was download the dialog and rework it completely to suit my needs (i also replaces bing with google as I could not get the search to work as it does on the bing maps site).
One of the issues is that the card and the message after it are two different messages. Cortana will update the canvas for each post, so I combined it into one.
I had a lot of issues with PromptDialog.Confirm not working so I replaced this with context.MakeMessage and attach the card as an attachment. Then post the message.
In the message, you can have both the card and the text/speech. Then await the response.
The only problem is that you will have to interpret the response. I have yet to figure out how to do this automatically.

Categories

Resources