I currently have a bot, which simply puts out some prompts in ms teams as such,
The code used to output the promptdialog before it is shown is as follows, which also shows the starting point of the dialog in my bot,
/* Starting point of dialogue. If no errors then we go straight to init options, which decides what the end user will see initially */
public virtual async Task StartAsync(IDialogContext context)
{
try
{
context.Wait(this.ShowInitOptions);
}
catch (Exception ex)
{
await ShowError(context, ex.Message);
}
}
public virtual async Task ShowInitOptions(IDialogContext context, IAwaitable<IMessageActivity> activity)
{
Trace.TraceInformation("ShowInitOptions()");
PromptDialog.Choice(
context: context,
resume: ChoiceReceivedAsync,
options: optionsList,
descriptions: choiceDescriptions,
prompt: "Please select an option from below.",
retry: "Please select an option from below.",
promptStyle: PromptStyle.Auto
);
}
You can see there is a resume method invoked, which when you click on a choice, it will go to this method.
Now in the bot code I have an additional api endpoint in an ApiController class, which is different to the default api/messages, which when executed will display an adaptive card in ms teams. This api endpoint is called by an external source, which provides a data source that is processed inside of the ApiController class. A message is then sent to ms teams by executing this line block of code here,
var connector = new ConnectorClient(new Uri(someUrl);
AdaptiveCardTemplate template = new AdaptiveCardTemplate(templateJson);
var myData = new
{
title = data.title,
name = data.name,
token = data.token,
reference = data.reference,
info = data.info,
newnote = data.newnote
};
string cardJson = template.Expand(myData);
// Parse the JSON
AdaptiveCardParseResult result = AdaptiveCard.FromJson(cardJson);
// Get card from result
AdaptiveCard card = result.Card;
message.Attachments.Add(new Attachment()
{
Content = card,
ContentType = AdaptiveCard.ContentType,
Name = "Card"
});
message.ChannelId = callbackInfo.channelId;
message.From = botAccount;
message.Recipient = userAccount;
message.Conversation = new ConversationAccount(id: callbackInfo.conversationId);
message.Summary = myData.name;
message.Locale = "en-uk";
MicrosoftAppCredentials.TrustServiceUrl(callbackInfo.serviceUrl);
await connector.Conversations.SendToConversationAsync((Activity)message).ConfigureAwait(false);
The last line is what sends it out to the conversation in ms teams and the adaptive card is displayed. "message" is of type IMessageActivity and contains an adaptive card. This shows as follows in ms teams,
As you can see there is a text field here and so upon entering a value and clicking on "OK", the value is submitted to the api/messages endpoint in my ApiController class that handles the POST request. Now it is in here where Im stuck as the code currently tries to create a new dialog as seen below, However, all that happens is that my prompts shown in the first picture show up again. I can see that "activity" contains the submitted data but Im unable to process this information within the dialog thread as it seems to want a response to the prompts, which is displayed before. I guess my question is is there a way for me to end the conversation so that it doesnt require a choice to be picked from the prompts or if anyone has another bright idea then would be appreciated.
P.S I should add the Dialogs.RootDialog class contains methods I will need to run as it involves collecting data from the context object as show before in the ShowInitOptions() method.
CodePudding user response:
Your MessagesController
class is currently responding to all incoming messages in the same way (check if activity.Type == ActivityTypes.Message
). One possible solution is to first check if the message is a response from your Adaptive Card, and if so to process it differently. Here is an example of inspecting the payload from a Card's submit action, to give you an idea: