microsoft / microsoft/AdaptiveCards

[Bug]: Adaptive cards not sending payload data from iOS Teams Mobile app

Open
#9,330 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area-Renderers Bug
Dominant language
C#
Stars
2k
Forks
595
Avg merge
1d 19h
Merged PRs (30d)
1

Description

Target Platforms

iOS

SDK Version

3.1.0

Application Name

Microsoft Teams (IOS mobile)

Problem Description

I have a MS Teams chat bot that utilises adaptive cards for visualisation and data collection.
The feature having the issue is a subscription configuration card that recently started writing null values to the database for fields that should not be null as the are required.
These null values started appearing from December 16th.
No change in the card payload or data model occurred prior to the issue being noticed.
Desktop version in Windows and Mac OS works as expected with no null values

App Versions

  • Desktop - 25198.1112.3855.290, Windows 11 Enterprise, Version 23H2
  • Desktop - MAC OS Tahoe
  • Mobile - 7.22.2, iOS 26.2
  • Adaptive card schema version v1.3

Packages

  • "AdaptiveCards": "3.1.0",
  • "AdaptiveCards.Templating": "2.0.5",
  • "Microsoft.Bot.Builder.Azure": 4.23.0,
  • "Microsoft.Bot.Builder.Dialogs": 4.23.0
  • "Microsoft.Bot.Builder.Integration.AspNet.Core": 4.23.0
Screenshots
Image

App insights exception tracking of rest data from mobile clients

Image
Card JSON
{
  "type": "AdaptiveCard",
  "version": "1.3",
  "body": [
    {
      "type": "TextBlock",
      "text": "ViDA Messaging Configuration",
      "horizontalAlignment": "Center",
      "weight": "Bolder",
      "size": "Medium"
    },
    {
      "type": "TextBlock",
      "text": "${name}",
      "weight": "Bolder",
      "horizontalAlignment": "Center"
    },
    {
      "id": "notificationoptions",
      "type": "Input.ChoiceSet",
      "choices": [
        {
          "title": "Insights",
          "value": "insights"
        },
        {
          "title": "Live Faults",
          "value": "livefaults"
        }
      ],
      "isMultiSelect": true,
      "label": "Notifications",
      "value": "${NotificationOptions}",
      "style": "expanded"
    },
    {
      "type": "Input.ChoiceSet",
      "placeholder": "Placeholder text",
      "choices": [
        {
          "title": "Tuesday",
          "value": "tuesday"
        },
        {
          "title": "Wednesday",
          "value": "wednesday"
        },
        {
          "title": "Thursday",
          "value": "thursday"
        },
        {
          "title": "Friday",
          "value": "friday"
        },
        {
          "title": "Saturday",
          "value": "saturday"
        }
      ],
      "style": "expanded",
      "value": "${lowpriority}",
      "id": "lowpriority",
      "isMultiSelect": true,
      "label": "<redacted>",
      "spacing": "Medium"
    },
    {
      "type": "Input.ChoiceSet",
      "choices": [
        {
          "title": "<redacted>",
          "value": "all"
        },
        {
          "title": "<redacted>",
          "value": "option1"
        }
      ],
      "value": "${style}",
      "id": "style",
      "placeholder": "Not Set",
      "isRequired": true,
      "errorMessage": "<redacted>",
      "label": "<redacted>",
      "spacing": "Medium"
    },
    {
      "type": "Input.Text",
      "placeholder": "<redacted>",
      "isMultiline": true,
      "separator": true,
      "id": "<redacted>",
      "value": "${m}",
      "isRequired": true,
      "errorMessage": "<redacted>",
      "label": "<redacted>",
      "spacing": "Medium"
    },
    {
      "type": "Input.ChoiceSet",
      "errorMessage": "<redacted>",
      "choices": [
        {
          "title": "None",
          "value": "None"
        },
        {
          "title": "<redacted>",
          "value": "<redacted>"
        },
        {
          "title": "<redacted>",
          "value": "<redacted>"
        }
      ],
      "label": "<redacted>",
      "id": "<redacted>",
      "value": "<redacted>",
      "isRequired": true
    },
    {
      "type": "Input.ChoiceSet",
      "placeholder": "select a timezone",
      "choices": [
        {
          "title": "GMT-8\tPacific Standard Time (PST)",
          "value": "-8"
        },
        {
          "title": "GMT-6\tCentral Standard Time (CST)",
          "value": "-6"
        },
        {
          "title": "GMT-5\tEastern Standard Time (EST)",
          "value": "-5"
        },
        {
          "title": "GMT+0\tGreenwich Mean Time (GMT)",
          "value": "0"
        },
        {
          "title": "GMT +1\tCentral European Time (CET)",
          "value": "1"
        },
        {
          "title": "GMT +3\tMoscow Time (MSK)",
          "value": "+3"
        },
        {
          "title": "GMT +5.5\tIndia Standard Time (IST)",
          "value": "5.5"
        },
        {
          "title": "GMT +8\tChina Standard Time (CST)",
          "value": "8"
        },
        {
          "title": "GMT +9\tJapan Standard Time (JST)",
          "value": "9"
        },
        {
          "title": "GMT +12\tNew Zealand Standard Time (NZST)",
          "value": "12"
        }
      ],
      "value": "${timezone}",
      "id": "timezone",
      "isRequired": true,
      "errorMessage": "Your time zone is required",
      "label": "Your Time Zone",
      "spacing": "Medium"
    },
    {
      "type": "Input.ChoiceSet",
      "placeholder": "Not Set",
      "choices": [
        {
          "title": "6.30AM",
          "value": "6.30AM"
        },
        {
          "title": "7.30AM",
          "value": "7.30AM"
        },
        {
          "title": "8.30AM",
          "value": "8.30AM"
        }
      ],
      "id": "sendtime",
      "value": "${sendingtime}",
      "isRequired": true,
      "errorMessage": "Your send time is required",
      "label": "Sending Time",
      "spacing": "Medium"
    },
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.ShowCard",
          "title": "?",
          "card": {
            "type": "AdaptiveCard",
            "version": "1.3",
            "body": [
              {
                "type": "TextBlock",
                "text": "<redacted>",
                "wrap": true,
                "horizontalAlignment": "Left"
              },
              {
                "type": "TextBlock",
                "text": "**<redacted>",
                "wrap": true,
                "horizontalAlignment": "Left"
              },
              {
                "type": "TextBlock",
                "text": "**<redacted>",
                "wrap": true,
                "horizontalAlignment": "Left"
              },
              {
                "type": "TextBlock",
                "text": "<redacted>",
                "wrap": true,
                "horizontalAlignment": "Left"
              },
              {
                "type": "TextBlock",
                "text": "<redacted>",
                "wrap": true,
                "horizontalAlignment": "Left"
              },
              {
                "type": "TextBlock",
                "text": "**Your Time Zone:** \n\r  Select the nearest TimeZone/GMT offset of your location",
                "wrap": true,
                "horizontalAlignment": "Left"
              },
              {
                "type": "TextBlock",
                "text": "**Sending Time:** \n\r Requested email send time, used in conjunction with Timezone information",
                "wrap": true,
                "horizontalAlignment": "Left"
              }
            ],
            "$schema": "https://adaptivecards.io/schemas/adaptive-card.json"
          },
          "style": "positive"
        }
      ]
    },
    {
      "type": "TextBlock",
      "text": "<redacted>",
      "wrap": true,
      "isSubtle": true
    },
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.Submit",
          "title": "${submit}",
          "data": {
            "Update_Config": "true"
          },
          "associatedInputs": "auto"
        }
      ]
    }
  ],
  "$schema": "https://adaptivecards.io/schemas/adaptive-card.json"
}
Sample Code Language

C#

Sample Code

Send card

var user = await Database.GetConfiguration(cancellationToken, member.Email.ToLower());

ConfResult displayableConfig = user != null ? new ConfResult(user) : new ConfResult(member.Email);
string card = await File.ReadAllTextAsync(@"Cards\Configuration.json", cancellationToken);

// Add delete button dynamically
if (user != null)
{
var button =
$@"{{""type"":""Action.Submit"",""title"":""Delete Subscription"",""data"":{{""Delete_Config"":""true""}},""mode"":""secondary"",""style"":""destructive""}}";
var parsedJson = JObject.Parse(card);
var parsedButton = JObject.Parse(button);
parsedJson["body"]?.Last["actions"].Last.AddAfterSelf(parsedButton);
card = parsedJson.ToString();
}

var dat = JsonConvert.SerializeObject(displayableConfig);
var transformer = new AdaptiveCardTemplate(card);
var adaptiveCardJson = transformer.Expand(dat);

var cardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};

await turnContext.SendActivityAsync(MessageFactory.Attachment(cardAttachment), cancellationToken);

Receive card data

var user = new User(new ConfResult(rest), member.Email)
{
Name = $"{member.GivenName} {member.Surname}",
GivenName = member.GivenName,
Surname = member.Surname,
Conversation = turnContext.Activity.GetConversationReference(),
Locale = turnContext.Activity.Locale,
TimeZoneOffset = timeZoneOffset.ToString()
};

if(user.SubscribedDistrict == null)
{
#if !DEBUG
await turnContext.DeleteActivityAsync(turnContext.Activity.ReplyToId, cancellationToken);
#endif
await turnContext.SendActivityAsync($"Configuration Update FAILED! - if using mobile device, try using desktop Teams application or contact support");
return;
}
#if !DEBUG
user.UserPrinciple = member.UserPrincipalName;
await turnContext.DeleteActivityAsync(turnContext.Activity.ReplyToId, cancellationToken);
#endif
var success = await Database.UpdateSubscriberItemAsync(turnContext, cancellationToken, user);
if (success)
await turnContext.SendActivityAsync($"Configuration Updated", cancellationToken: cancellationToken);
else
await turnContext.SendActivityAsync("Fault updating subscription, try again or contact support", cancellationToken: cancellationToken);
}
catch (Exception e)
{
#if !DEBUG
IDictionary<string, string> properties = new Dictionary<string, string>
{
["Type"] = "Updating User configuration",
["UserEmail"] = member.Email,
["UserName"] = $"{member.GivenName} {member.Surname}",
["rest"] = rest.ToString(),
["activityvalue"] = JsonConvert.SerializeObject(turnContext.Activity.Value)
};
AzureTelemetry.TelemetryClient.TrackException(e, properties);
#endif
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with Cards\Configuration.json and the send/receive card code in the report, then reproduce the subscription update in iOS Teams and compare its activity value with desktop Teams. Done means required card inputs arrive with their selected values rather than null, while the existing desktop behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, ios
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.