Search code examples
c#botframeworkmicrosoft-teamsadaptive-cards

Using Bot Framework Emulator (v4) updating an already sent adaptive card doesn't work for me


I try to update an already sent message/adaptive card... or more or less exchange the already sent adaptive card with another one. Therefore I'm using the UpdateActivityAsync() function. In the documentation (https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/update-and-delete-bot-messages?tabs=dotnet) the suggested way to update an already sent message or update a card is the following:

To update an existing message, pass a new Activity object with the existing activity ID to the UpdateActivityAsync method of the TurnContext class. For more information, see TurnContextClass.

var newActivity = MessageFactory.Text("The new text for the activity");
newActivity.Id = activityId; await
turnContext.UpdateActivityAsync(newActivity, cancellationToken);

To update existing card on a button selection, pass a new Activity object with updated card and ReplyToId as activity ID to the UpdateActivityAsync method of the TurnContext class. See TurnContextClass.

var activity = MessageFactory.Attachment(card.ToAttachment());
activity.Id = turnContext.Activity.ReplyToId; await
turnContext.UpdateActivityAsync(activity, cancellationToken);

And this is exactly what i am trying to do. In the OnMembersAddedAsync() function I send message containing a specific card. The corresponding message/activity id is saved in the class member _msgID. Then, after the user presses a submit button on that card, the OnMessageActivityAsync() function is called and in there a new message/activity is created. Setting the id of the new message to the stored old on (_msgId) and calling the update function, nothing happens... not even the error message "The bot encountered an error or bug." or so...

private static string _msgID = "";

protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
  var cardAttachment = CreateAdaptiveCardAttachment(Path.Combine(".", "Resources", "FeelingsCard.json"));
  var oldActivity = MessageFactory.Attachment(cardAttachment);
  await turnContext.SendActivityAsync(oldActivity, cancellationToken);

  _msgID = oldActivity.Id;
}

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
  var newActivity = MessageFactory.Attachment(CreateAdaptiveCardAttachment(Path.Combine(".", "Resources", "EmotionsCard.json")));
  newActivity.Id = _msgID;
                    
  await turnContext.UpdateActivityAsync(newActivity, cancellationToken);
}

private static Attachment CreateAdaptiveCardAttachment(string filePath)
{
  var adaptiveCardJson = File.ReadAllText(filePath);
  var adaptiveCardAttachment = new Attachment()
  {
    ContentType = "application/vnd.microsoft.card.adaptive",
    Content = JsonConvert.DeserializeObject(adaptiveCardJson),
  };
  return adaptiveCardAttachment;
}

Am I doing something wrong or what am I missing?

Thanks a lot for the help!


Solution

  • The Emulator is a Direct Line client. UpdateActivityAsync will work on Teams, but not on Emulator (Webchat/Directline).

    https://learn.microsoft.com/en-us/azure/bot-service/bot-service-channels-reference?view=azure-bot-service-4.0#message-update

    To test; you will have to use Teams and Ngrok.