Build apps for anonymous users

Anonymous users don't have a Microsoft Entra identity and aren't federated with a tenant. The anonymous participants are external users but their identity isn't shown in the meeting. An anonymous user can be a presenter or an attendee but can't be an organizer. You can build bots, messaging extensions, cards, and dialogs (referred as task modules in TeamsJS v1.x) in your app to engage with anonymous meeting participants.

Note

  • Apps for anonymous users are supported in the new Teams desktop and mobile clients for Windows and Mac.
  • Meeting apps for anonymous users are only supported in Microsoft Edge and Chrome.

For anonymous users to interact with the apps in Teams meetings, ensure to:

  1. Update your app manifest.
  2. Enable the anonymous user app interaction in Teams admin center.

App manifest update for anonymous users

Note

The supportsAnonymousGuestUsers property in the app manifest schema v1.16 is supported only in new Teams client.

To allow anonymous users to interact with the tab app, update the supportsAnonymousGuestUsers property to true in your app manifest schema v1.16 or later. Following is an example of the manifest:

"meetingExtensionDefinition": {
    "supportsAnonymousGuestUsers": true
}

For more information, see app manifest schema.

Anonymous user authentication flow

Anonymous users can't be authenticated through Microsoft Entra authentication or getAuthToken from the client SDK as they aren't Microsoft Entra accounts. getAuthToken fails for anonymous users by returning the error useGetAuthToken: Failed with error - User is not authenticated. If you need to authenticate anonymous users, your app must identify anonymous users and provide an alternative authentication experience in the meetings. You can determine if a user is anonymous by validating user's context.

Admin setting for anonymous user app interaction

Teams admins can use the Teams admin center to enable or disable anonymous user app interaction for the entire tenant. If your app needs to be accessed by anonymous users, ensure that the tenant admins enable the anonymous user app interaction. This setting is enabled by default. For more information, see allow anonymous users to interact with apps in meetings.

To test your apps experience for anonymous users, select the URL in the meeting invite and join the meeting from a private browser window.

In-Meeting getContext from Teams client library

Apps receive the following information for an anonymous user when they call the getContext API from the shared app stage. You can recognize anonymous users by checking for a userLicenseType value of Anonymous.

import * as microsoftTeams from "@microsoft/teams-js";

microsoftTeams.app.getContext().then((context) => {
    if (context.user.licenseType === "Anonymous") {
        // Add your custom logic here
    }
});
Property name Description
userObjectId Empty string for anonymous user.
userLicenseType Anonymous represents anonymous user.
loginHint Empty string for anonymous user.
userPrincipalName Empty string for anonymous user.

For more information on getContext, see get context by using the Microsoft Teams JavaScript library.

Bot activities and APIs

With a few differences, the activities sent to your bot and the responses that it receives from bot APIs are consistent between anonymous and non-anonymous meeting participants.

Get members and get single member APIs

The get members and get single member APIs return limited information for anonymous users:

{ 
  "id": "<GUID1>", 
  "name": "<AnonTest (Guest)>",  
  "tenantId": "<GUID2>", 
  "userRole": "anonymous" 
}
Property name Description
id Unique generated value for the anonymous user.
name Name provided by the anonymous user when joining the meeting.
tenantId Tenant ID of the meeting organizer.
userRole anonymous, represents anonymous user.

ConversationUpdate activity MembersAdded and MembersRemoved

MembersAdded

protected override async Task OnTeamsMembersAddedAsync(IList<TeamsChannelAccount> membersAdded, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
  {
     foreach (var teamMember in membersAdded)
     {
         // If UserRole == "anonymous", it indicates an anonymous user
         if (teamMember.UserRole == "anonymous" )
          {
             // Add your custom logic here
          }
          else
          {
           // Add your custom logic here
          }
     }
  }

MembersRemoved

protected override async Task OnTeamsMembersRemovedAsync(IList<TeamsChannelAccount> membersRemoved, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
   foreach (var member in membersRemoved)
   {
      // If AadObjectId is null, it indicates an anonymous user
       if (member.AadObjectId == null)
       {
           // Add your custom logic here
       }
       else
       {
           // Add your custom logic here
       }
   }

Note

When an anonymous user joins or leaves a meeting, the from object in the payload always has the ID of the meeting organizer, even if the action was taken by someone else.

Create Conversation API

Bots aren't allowed to initiate a one-on-one conversation with an anonymous user. If a bot calls the Create Conversation API with the user ID of an anonymous user, it receives a 400 Bad Request status code and the following error response:

var conversationParameters = new ConversationParameters
    {
       IsGroup = false,
       Bot = turnContext.Activity.Recipient,
       Members = new ChannelAccount[] { teamMember },
       TenantId = turnContext.Activity.Conversation.TenantId,
    };
    
    await ((CloudAdapter)turnContext.Adapter).CreateConversationAsync(
    conversationParameters,
    async (t1, c1) =>
    {
       conversationReference = t1.Activity.GetConversationReference();
       await ((CloudAdapter)turnContext.Adapter).ContinueConversationAsync(
       _appId,
       conversationReference,
       async (t2, c2) =>
       {
         await t2.SendActivityAsync(proactiveMessage, c2);
        },
        cancellationToken);
    },
cancellationToken);
{ 
  "error": {
    "code": "BadArgument",
    "message": "Bot cannot create a conversation with an anonymous user"
  }
} 

Adaptive Cards

Anonymous users can view and interact with Adaptive Cards in the meeting chat. Adaptive Card actions behave the same way for anonymous and non-anonymous users. For more information, see Card actions.

Known issues and limitations

  • Apps for anonymous users aren't supported on live event, Virtual desktop infrastructure (VDI), and Linux platforms.

  • Apps for anonymous users aren't supported on Firefox and Safari browsers.

  • Apps for anonymous users aren't supported in Teams channel meetings.

  • Currently, the getContext API doesn't return a user ID for the anonymous user though the bot APIs do and it's not possible to correlate the anonymous user between these two APIs.

  • Anonymous users see a generic app icon on bot messages and cards, instead of the app's actual icon.

    Screenshot shows how the app icon displays for anonymous user.

Code sample

Sample name Description .NET Node.js
Anonymous user support Sample app to show anonymous user support in meeting apps. View View

Next step

See also