+ );
+};
+
+export default ShareView;
diff --git a/samples/bot-tab-interoperability/csharp/ClientApp/src/index.css b/samples/bot-tab-interoperability/csharp/ClientApp/src/index.css
new file mode 100644
index 0000000000..c919e21658
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/ClientApp/src/index.css
@@ -0,0 +1,102 @@
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.header {
+ height: 10rem;
+}
+
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
+
+.fui-FluentProvider {
+ display: contents;
+}
+
+.container {
+ color: black;
+ padding:1rem;
+}
+
+/* Custom styles */
+* {
+ box-sizing: border-box;
+}
+
+/* Create two equal columns that floats next to each other */
+.column {
+ float: left;
+ width: 50%;
+ padding: 10px;
+ height: 300px; /* Should be removed. Only for demonstration */
+}
+
+/* Clear floats after the columns */
+.row:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.circle_gray {
+ height: 150px;
+ width: 150px;
+ background-color: #bbb;
+ border-radius: 50%;
+ display: inline-block;
+}
+
+.circle_red {
+ height: 150px;
+ width: 150px;
+ background-color: rgb(221, 68, 68);
+ border-radius: 50%;
+ display: inline-block;
+ color: rgb(221, 68, 68);
+ ;
+}
+
+.circle_blue {
+ height: 150px;
+ width: 150px;
+ background-color: rgb(68, 68, 176);
+ border-radius: 50%;
+ display: inline-block;
+ color: rgb(68, 68, 176);
+}
+
+.circle_green {
+ height: 150px;
+ width: 150px;
+ background-color: rgb(68, 109, 68);
+ border-radius: 50%;
+ display: inline-block;
+ color: rgb(68, 109, 68);
+}
+
+input[type=text] {
+ width: 20%;
+ padding: 12px 20px;
+ margin: 8px 0;
+ box-sizing: border-box;
+}
+
+button {
+ padding: 12px 20px;
+ margin: 8px 8px;
+ box-sizing: border-box;
+}
+
+label {
+ font-size: x-large;
+}
+
+
+
diff --git a/samples/bot-tab-interoperability/csharp/ClientApp/src/index.js b/samples/bot-tab-interoperability/csharp/ClientApp/src/index.js
new file mode 100644
index 0000000000..b6820c4576
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/ClientApp/src/index.js
@@ -0,0 +1,16 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+import { FluentProvider, teamsLightTheme } from '@fluentui/react-components';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import { AppRoute } from './router/router';
+
+ReactDOM.render(
+
+
+ , document.getElementById('root')
+);
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/ClientApp/src/router/router.js b/samples/bot-tab-interoperability/csharp/ClientApp/src/router/router.js
new file mode 100644
index 0000000000..7efb5efff0
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/ClientApp/src/router/router.js
@@ -0,0 +1,39 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+import React, { useEffect } from 'react';
+import { BrowserRouter, Route, Routes } from "react-router-dom";
+import App from "../components/app-in-meeting";
+import Configure from "../components/configure";
+import ShareToMeeting from "../components/share-to-meeting";
+import * as microsoftTeams from "@microsoft/teams-js";
+import ShareView from "../components/shareview";
+import FacebookAuthEnd from "../components/facebook-auth-end";
+import AuthStart from "../components/auth-start";
+import AuthEnd from "../components/auth-end";
+export const AppRoute = () => {
+
+ useEffect(() => {
+ (async function () {
+ await microsoftTeams.app.initialize();
+ })();
+ }, []);
+
+ return (
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/Controllers/BotController.cs b/samples/bot-tab-interoperability/csharp/Controllers/BotController.cs
new file mode 100644
index 0000000000..e02b61b415
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Controllers/BotController.cs
@@ -0,0 +1,37 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Bot.Builder;
+using Microsoft.Bot.Builder.Integration.AspNet.Core;
+
+namespace AnonymousUsers.Controllers
+{
+ // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
+ // implementation at runtime. Multiple different IBot implementations running at different endpoints can be
+ // achieved by specifying a more specific type for the bot constructor argument.
+ [Route("api/messages")]
+ [ApiController]
+ public class BotController : ControllerBase
+ {
+ private readonly IBotFrameworkHttpAdapter Adapter;
+ private readonly IBot Bot;
+
+ public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
+ {
+ Adapter = adapter;
+ Bot = bot;
+ }
+
+ [HttpPost]
+ public async Task PostAsync()
+ {
+ // Delegate the processing of the HTTP POST to the adapter.
+ // The adapter will invoke the bot.
+ await Adapter.ProcessAsync(Request, Response, Bot);
+ }
+ }
+}
diff --git a/samples/bot-tab-interoperability/csharp/Controllers/WebSocketController.cs b/samples/bot-tab-interoperability/csharp/Controllers/WebSocketController.cs
new file mode 100644
index 0000000000..02c562e878
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Controllers/WebSocketController.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Net.WebSockets;
+using Microsoft.AspNetCore.Http;
+using System.Threading.Tasks;
+using System.Threading;
+using Microsoft.AspNetCore.Mvc;
+using System.Text;
+using System.Text.Json;
+using Microsoft.Bot.Connector;
+using Microsoft.Bot.Schema;
+
+namespace AnonymousUsers.Controllers;
+
+public class WebSocketController : ControllerBase
+{
+
+ [HttpGet("/ws")]
+ public async Task Get()
+ {
+ if (HttpContext.WebSockets.IsWebSocketRequest)
+ {
+ using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
+ await Echo(webSocket);
+ }
+ else
+ {
+ HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
+ }
+ }
+
+ private static async Task Echo(WebSocket webSocket)
+ {
+ var buffer = new byte[1024 * 4];
+ var receiveResult = await webSocket.ReceiveAsync(
+ new ArraySegment(buffer), CancellationToken.None);
+
+ while (!receiveResult.CloseStatus.HasValue)
+ {
+ await webSocket.SendAsync(
+ new ArraySegment(buffer, 0, receiveResult.Count),
+ receiveResult.MessageType,
+ receiveResult.EndOfMessage,
+ CancellationToken.None);
+
+ string receivedMessage = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
+ if (receivedMessage != null)
+ {
+ string inputValue = "";
+ string threadId = "";
+ string appID = "";
+ string appPassword = "";
+ using (JsonDocument document = JsonDocument.Parse(receivedMessage))
+ {
+ JsonElement root = document.RootElement;
+ if (root.TryGetProperty("threadId", out JsonElement threadIdElement))
+ {
+ threadId = threadIdElement.GetString();
+ }
+ if (root.TryGetProperty("inputValue", out JsonElement inputValueElement))
+ {
+ inputValue = inputValueElement.GetString();
+ }
+ if (root.TryGetProperty("appID", out JsonElement appIDElement))
+ {
+ appID = appIDElement.GetString();
+ }
+ if (root.TryGetProperty("appPassword", out JsonElement appPasswordElement))
+ {
+ appPassword = appPasswordElement.GetString();
+ }
+ // Send the received message to the bot
+ if (threadId != null)
+ {
+ await SendProactiveMessage(inputValue, threadId, appID, appPassword);
+ }
+ }
+ }
+
+ receiveResult = await webSocket.ReceiveAsync(
+ new ArraySegment(buffer), CancellationToken.None);
+ }
+
+ await webSocket.CloseAsync(
+ receiveResult.CloseStatus.Value,
+ receiveResult.CloseStatusDescription,
+ CancellationToken.None);
+ }
+
+
+
+ private static async Task SendProactiveMessage(string message, string threadId,string appID, string appPassword)
+ {
+ var connector = new ConnectorClient(new Uri("https://smba.trafficmanager.net/amer/"), appID, appPassword);
+ var conversationReference = new ConversationReference
+ {
+ Conversation = new ConversationAccount(id: threadId)
+ };
+
+ var activity = Activity.CreateMessageActivity();
+ activity.Text = message;
+
+ await connector.Conversations.SendToConversationAsync(
+ conversationReference.Conversation.Id,
+ (Activity)activity);
+ }
+
+}
diff --git a/samples/bot-tab-interoperability/csharp/Helper/AuthHelper.cs b/samples/bot-tab-interoperability/csharp/Helper/AuthHelper.cs
new file mode 100644
index 0000000000..6a92dcce92
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Helper/AuthHelper.cs
@@ -0,0 +1,59 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Primitives;
+using Microsoft.Identity.Client;
+using Microsoft.IdentityModel.Tokens;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace AnonymousUsers.Helper
+{
+ public class AuthHelper
+ {
+ ///
+ /// Get token using client credentials flow
+ ///
+ /// IConfiguration instance.
+ /// IHttpClientFactory instance.
+ /// IHttpContextAccessor instance.
+ /// App access token on behalf of user.
+ public static async Task GetAccessTokenOnBehalfUserAsync(IConfiguration configuration, IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContextAccessor)
+ {
+ var tenantId = configuration["AzureAd:TenantId"];
+ IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(configuration["AzureAd:MicrosoftAppId"])
+ .WithClientSecret(configuration["AzureAd:MicrosoftAppPassword"])
+ .WithAuthority($"https://login.microsoftonline.com/{tenantId}")
+ .Build();
+
+ try
+ {
+ var httpContext = httpContextAccessor.HttpContext;
+ httpContext.Request.Headers.TryGetValue("Authorization", out StringValues assertion);
+
+ var idToken = assertion.ToString().Split(" ")[1];
+ UserAssertion assert = new UserAssertion(idToken);
+ List scopes = new List
+ {
+ "User.Read"
+ };
+
+ var responseToken = await app.AcquireTokenOnBehalfOf(scopes, assert).ExecuteAsync();
+
+ return responseToken.AccessToken.ToString();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ return null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/Helper/FacebookHelper.cs b/samples/bot-tab-interoperability/csharp/Helper/FacebookHelper.cs
new file mode 100644
index 0000000000..f6300303ca
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Helper/FacebookHelper.cs
@@ -0,0 +1,117 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using Newtonsoft.Json;
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace AnonymousUsers.Helper
+{
+ ///
+ /// Entity Class to store the User Profile information
+ ///
+ public class FacebookProfile
+ {
+ ///
+ /// Assign facebook username name value in this Name property
+ ///
+ [JsonProperty(PropertyName = "name")]
+ public string Name { get; set; }
+
+ ///
+ /// Assign facebook picture in this ProfilePicture property
+ ///
+ [JsonProperty(PropertyName = "picture")]
+ public Picture ProfilePicture { get; set; }
+
+ ///
+ /// Create a class named "Data" with a property url
+ /// Assgin facebook image in this url property.
+ ///
+ public class Data
+ {
+ public string url { get; set; }
+ }
+
+ ///
+ /// Create a class named "Picture" with a property data
+ /// Aassgin facebook Picture information in this data property.
+ ///
+ public class Picture
+ {
+ public Data data { get; set; }
+ }
+ }
+
+ ///
+ /// Retrieved from facebook profile information after a successful authentication process.
+ ///
+ public class FacebookHelper
+ {
+ ///
+ /// Get the User Profile information using valid Access Token
+ ///
+ ///
+ ///
+ public static async Task GetFacebookProfileName(string accessToken)
+ {
+ var uri = GetUri("https://graph.facebook.com/v2.6/me",
+ Tuple.Create("fields", "name,picture"),
+ Tuple.Create("access_token", accessToken));
+
+ var userProfileInfo = await FacebookRequest(uri);
+
+ return userProfileInfo;
+ }
+
+ ///
+ /// Purpose of this request is to process the Api Calls
+ ///
+ ///
+ ///
+ ///
+ public static async Task FacebookRequest(Uri uri)
+ {
+ string json;
+ using (HttpClient client = new HttpClient())
+ {
+ json = await client.GetStringAsync(uri).ConfigureAwait(false);
+ }
+
+ try
+ {
+ var result = JsonConvert.DeserializeObject(json);
+
+ return result;
+ }
+ catch (JsonException ex)
+ {
+ throw new ArgumentException("", ex);
+ }
+ }
+
+ ///
+ /// Helper method to create URL
+ ///
+ ///
+ ///
+ ///
+ public static Uri GetUri(string endPoint, params Tuple[] queryParams)
+ {
+ var queryString = HttpUtility.ParseQueryString(string.Empty);
+ foreach (var queryparam in queryParams)
+ {
+ queryString[queryparam.Item1] = queryparam.Item2;
+ }
+
+ var builder = new UriBuilder(endPoint);
+ builder.Query = queryString.ToString();
+
+ return builder.Uri;
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/Helper/SimpleGraphClient.cs b/samples/bot-tab-interoperability/csharp/Helper/SimpleGraphClient.cs
new file mode 100644
index 0000000000..fb45848937
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Helper/SimpleGraphClient.cs
@@ -0,0 +1,56 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using System;
+using System.Net.Http.Headers;
+using System.Threading.Tasks;
+using Microsoft.Graph;
+
+namespace AnonymousUsers.Helper
+{
+ // This class is a wrapper for the Microsoft Graph API
+ // See: https://developer.microsoft.com/en-us/graph
+ public class SimpleGraphClient
+ {
+ private readonly string _token;
+
+ public SimpleGraphClient(string token)
+ {
+ if (string.IsNullOrWhiteSpace(token))
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ _token = token;
+ }
+
+ // Get information about the user.
+ public async Task GetMeAsync()
+ {
+ var graphClient = GetAuthenticatedClient();
+ var me = await graphClient.Me.Request().GetAsync();
+ return me;
+ }
+
+ // Get an Authenticated Microsoft Graph client using the token issued to the user.
+ private GraphServiceClient GetAuthenticatedClient()
+ {
+ var graphClient = new GraphServiceClient(
+ new DelegateAuthenticationProvider(
+ requestMessage =>
+ {
+ // Append the access token to the request.
+ requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", _token);
+
+ // Get event times in the current time zone.
+ requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");
+
+ return Task.CompletedTask;
+ }));
+
+ return graphClient;
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/Models/UserData.cs b/samples/bot-tab-interoperability/csharp/Models/UserData.cs
new file mode 100644
index 0000000000..8080e9e5f0
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Models/UserData.cs
@@ -0,0 +1,16 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+//
+ /// User data model class.
+ ///
+ public class UserData
+ {
+ public User User { get; set; }
+ }
+}
diff --git a/samples/bot-tab-interoperability/csharp/Program.cs b/samples/bot-tab-interoperability/csharp/Program.cs
new file mode 100644
index 0000000000..c4b11c2438
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Program.cs
@@ -0,0 +1,89 @@
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+//
+
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Bot.Builder;
+using Microsoft.Bot.Builder.Integration.AspNet.Core;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Bot.Connector.Authentication;
+using Microsoft.BotBuilderSamples;
+using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
+using System;
+using AnonymousUsers;
+using AnonymousUsers.Bots;
+using Microsoft.AspNetCore.Http;
+using System.Net.WebSockets;
+using System.Threading.Tasks;
+using System.Threading;
+using AnonymousUsers.Controllers;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddHttpClient().AddControllers().AddNewtonsoftJson(options =>
+{
+ options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth;
+});
+
+// In production, the React files will be served from this directory
+builder.Services.AddSpaStaticFiles(configuration =>
+{
+ configuration.RootPath = "ClientApp/build";
+});
+
+// Create the Bot Framework Authentication to be used with the Bot Adapter.
+builder.Services.AddSingleton();
+
+// Create the Bot Adapter with error handling enabled.
+builder.Services.AddSingleton();
+
+// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
+builder.Services.AddTransient();
+
+builder.Services.AddSingleton();
+
+builder.Services.AddSignalR();
+
+var app = builder.Build();
+
+//
+var webSocketOptions = new WebSocketOptions
+{
+ KeepAliveInterval = TimeSpan.FromMinutes(2)
+};
+
+app.UseWebSockets(webSocketOptions);
+//
+
+
+// Configure the HTTP request pipeline.l
+if (app.Environment.IsDevelopment())
+{
+ app.UseDeveloperExceptionPage();
+}
+
+app.UseDefaultFiles()
+ .UseStaticFiles()
+ .UseRouting()
+ .UseAuthorization()
+ .UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ //endpoints.MapHub("/chatHub");
+ });
+
+app.UseSpa(spa =>
+{
+ spa.Options.SourcePath = "ClientApp";
+
+ if (app.Environment.IsDevelopment())
+ {
+ spa.Options.StartupTimeout = TimeSpan.FromSeconds(120);
+ spa.UseReactDevelopmentServer(npmScript: "start");
+ }
+});
+
+app.Run();
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/Properties/launchSettings.json b/samples/bot-tab-interoperability/csharp/Properties/launchSettings.json
new file mode 100644
index 0000000000..5481ab482d
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Properties/launchSettings.json
@@ -0,0 +1,28 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:56806",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ ".NET Core": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:3978",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/samples/bot-tab-interoperability/csharp/Readme.md b/samples/bot-tab-interoperability/csharp/Readme.md
new file mode 100644
index 0000000000..77994b94a7
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Readme.md
@@ -0,0 +1,302 @@
+---
+page_type: sample
+description: This sample shows anonymous users support in meeting apps.
+products:
+- office-teams
+- office
+- office-365
+languages:
+- csharp
+extensions:
+ contentType: samples
+ createdDate: "08-02-2023 10:00:01"
+urlFragment: officedev-microsoft-teams-samples-app-anonymous-users-csharp
+
+---
+
+## Anonymous User Support
+
+This sample shows anonymous users support in meeting apps.
+
+**Interaction with app**
+![appanonymoususersGif](Images/anonymoususersupport.gif)
+
+## Prerequisites
+
+- [.NET Core SDK](https://dotnet.microsoft.com/download) version 6.0
+
+ determine dotnet version
+ ```bash
+ dotnet --version
+ ```
+- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunnelling solution.
+- [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account
+
+## Setup
+
+> Note these instructions are for running the sample on your local machine.
+
+1. Run ngrok - point to port 3978
+
+ ```bash
+ ngrok http 3978 --host-header="localhost:3978"
+ ```
+
+ Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below:
+
+ ```bash
+ devtunnel host -p 3978 --allow-anonymous
+ ```
+
+2. Setup
+
+ ### Register you app with Azure AD.
+
+ 1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal.
+ 2. Select **New Registration** and on the *register an application page*, set following values:
+ * Set **name** to your app name.
+ * Choose the **supported account types** (any account type will work)
+ * Leave **Redirect URI** empty.
+ * Choose **Register**.
+ 3. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You’ll need those later when updating your Teams application manifest and in the appsettings.json.
+ 4. Under **Manage**, select **Expose an API**.
+ 5. Select the **Set** link to generate the Application ID URI in the form of `api://{base-url}/botid-{AppID}`. Insert your fully qualified domain name (with a forward slash "/" appended to the end) between the double forward slashes and the GUID. The entire ID should have the form of: `api://fully-qualified-domain-name/botid-{AppID}`
+ * ex: `api://%ngrokDomain%.ngrok-free.app/botid-00000000-0000-0000-0000-000000000000`.
+ 6. Select the **Add a scope** button. In the panel that opens, enter `access_as_user` as the **Scope name**.
+ 7. Set **Who can consent?** to `Admins and users`
+ 8. Fill in the fields for configuring the admin and user consent prompts with values that are appropriate for the `access_as_user` scope:
+ * **Admin consent title:** Teams can access the user’s profile.
+ * **Admin consent description**: Allows Teams to call the app’s web APIs as the current user.
+ * **User consent title**: Teams can access the user profile and make requests on the user's behalf.
+ * **User consent description:** Enable Teams to call this app’s APIs with the same rights as the user.
+ 9. Ensure that **State** is set to **Enabled**
+ 10. Select **Add scope**
+ * The domain part of the **Scope name** displayed just below the text field should automatically match the **Application ID** URI set in the previous step, with `/access_as_user` appended to the end:
+ * `api://[ngrokDomain].ngrok-free.app/botid-00000000-0000-0000-0000-000000000000/access_as_user.
+ 11. In the **Authorized client applications** section, identify the applications that you want to authorize for your app’s web application. Each of the following IDs needs to be entered:
+ * `1fec8e78-bce4-4aaf-ab1b-5451cc387264` (Teams mobile/desktop application)
+ * `5e3ce6c0-2b1f-4285-8d4b-75ee78787346` (Teams web application)
+ 12. Navigate to **API Permissions**, and make sure to add the follow permissions:
+ - Select Add a permission
+ - Select Microsoft Graph -\> Delegated permissions.
+ - `User.Read` (enabled by default)
+ - Click on Add permissions. Please make sure to grant the admin consent for the required permissions.
+ 13. Navigate to **Authentication**
+ If an app hasn't been granted IT admin consent, users will have to provide consent the first time they use an app.
+ - Set a redirect URI:
+ * Select **Add a platform**.
+ * Select **Single-page application**.
+ * Enter the **redirect URI** for the app in the following format: `https://{Base_Url}/auth-end` and `https://{Base_Url}/auth-start`.
+ 14. Navigate to the **Certificates & secrets**. In the Client secrets section, click on "+ New client secret". Add a description(Name of the secret) for the secret and select “Never” for Expires. Click "Add". Once the client secret is created, copy its value, it need to be placed in the appsettings.json.
+
+ 15. Create a Bot Registration
+ - Register a bot with Azure Bot Service, following the instructions [here](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration?view=azure-bot-service-3.0).
+ - Ensure that you've [enabled the Teams Channel](https://docs.microsoft.com/en-us/azure/bot-service/channel-connect-teams?view=azure-bot-service-4.0)
+ - While registering the bot, use `https:///api/messages` as the messaging endpoint.
+
+16. To test facebook auth flow [create a facebookapp](FacebookAuth/README.md) and get client id and secret for facebook app.
+ Now go to your bot channel registartion -> configuration -> Add OAuth connection string
+ - Provide connection Name : for eg `facebookconnection`. You'll use this name in your bot in the appsettings.json file.
+ - Select service provider ad `facebook`
+ - Add clientid and secret of your facebook app that was created using Step 16.
+
+3. Clone the repository
+
+ ```bash
+ git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git
+ ```
+
+4. Run the app from a terminal or from Visual Studio, choose option A or B.
+
+ A) From a terminal, navigate to `samples/app-anonymous-users/csharp`
+
+ ```bash
+ # run the app
+ dotnet run
+ ```
+ B) Or from Visual Studio
+
+ - Launch Visual Studio
+ - File -> Open -> Project/Solution
+ - Navigate to `samples/app-anonymous-users/csharp` folder
+ - Select `AnonymousUsers.sln` file
+ - Press `F5` to run the project
+
+5. In a terminal, navigate to `samples/app-anonymous-users/csharp/ClientApp`
+
+ - Inside ClientApp folder execute the below command.
+
+ ```bash
+ # npm install
+ ```
+
+ 6) Modify the `/appsettings.json` and fill in the following details:
+ Modify the `appsettings.json` and fill in the following details:
+ - `{{Microsoft-App-id}}` - Generated from Step 1 (Application (client) ID)is the application app id
+ - `{{TenantId}}` - Generated from Step 1(Directory (tenant) ID) is the tenant id
+ - `{{MicrosoftAppPassword}}` - Generated from Step 1.14, also referred to as Client secret
+ - `{{domain-name}}` - Your application's base url. E.g. https://12345.ngrok-free.app if you are using ngrok and if you are using dev tunnels, your URL will be like: https://12345.devtunnels.ms.
+ - `{{FacebookAppId}} and {{FacebookAppPassword}}`- Generated from step 16.
+
+ 7) Modify the .env file in your project folder (or in Visual Studio) and fill in below details:
+ - `{{Microsoft-App-id}}` - Generated from Step 1 (Application (client) ID)is the application app id
+ - `{{FacebookAppId}}`- Generated from step 16.
+
+ 7. __*This step is specific to Teams.*__
+
+- **Edit** the `manifest.json` contained in the `AppManifest` folder to replace your Microsoft App Id `<>` (that was created when you registered your bot earlier) *everywhere* you see the place holder string `<>` (depending on the scenario the Microsoft App Id may occur multiple times in the `manifest.json`)
+
+- **Edit** the `manifest.json` for `{{domain-name}}` with base Url domain. E.g. if you are using ngrok it would be `https://1234.ngrok-free.app` then your domain-name will be `1234.ngrok-free.app` and if you are using dev tunnels then your domain will be like: `12345.devtunnels.ms`.
+
+- **Zip** up the contents of the `AppManifest` folder to create a `manifest.zip` (Make sure that zip file does not contains any subfolder otherwise you will get error while uploading your .zip package)
+
+- **Upload** the `manifest.zip` to Teams (In Teams Apps/Manage your apps click "Upload an app". Browse to and Open the .zip file. At the next dialog, click the Add button.)
+
+- Add the app to team/groupChat scope (Supported scopes).
+
+**Note:**
+- If you are facing any issue in your app, [please uncomment this line](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/app-anonymous-users/csharp/AdapterWithErrorHandler.cs#L27) and put your debugger for local debug.
+
+## Running the sample
+
+You can interact with Teams Tab meeting sidepanel.
+
+**Install app:**
+
+![InstallApp ](Images/InstallApp.png)
+
+**Add to a meeting:**
+
+![AddMeetingInstall ](Images/AddMeetingInstall.png)
+
+**Select meeting:**
+
+![AddToMeeting ](Images/AddToMeeting.png)
+
+**Add app in a meeting tab:**
+
+![MeetingTab ](Images/MeetingTab.png)
+
+**Select vote:**
+
+![Vote0 ](Images/Vote0.png)
+
+**Vote UI:**
+
+![VotePage1 ](Images/VotePage1.png)
+
+**Submit vote:**
+
+![SubmitVote2 ](Images/SubmitVote2.png)
+
+**Select CreateConversation:**
+
+![CreateConversation3 ](Images/CreateConversation3.png)
+
+**All message have been send and user count:**
+
+![SendConver7 ](Images/SendConver7.png)
+
+**Send user conversation mmessage:**
+
+![SendAllUserConver5 ](Images/SendAllUserConver5.png)
+
+**Click the "Share Invite" button, copy the URL, open the URL in a new tab, and set up a guest account:**
+
+![CopyMeetingLink8 ](Images/CopyMeetingLink8.png)
+
+**Accept guest user:**
+
+![AccepetGuestUser10 ](Images/AccepetGuestUser10.png)
+
+**CreateConversation guest user:**
+
+![CreateConverAnoUser11 ](Images/CreateConverAnoUser11.png)
+
+**Add app:**
+
+![AddApp12 ](Images/AddApp12.png)
+
+**Share to stage view:**
+
+![SharePage14 ](Images/SharePage14.png)
+
+**Click share to stage view:**
+
+![UserOneSharing15 ](Images/UserOneSharing15.png)
+
+**Screen visible anonymous users:**
+
+![AnoUserSharing16 ](Images/AnoUserSharing16.png)
+
+**Click sign-in button**
+
+![Clicksigninbutton ](Images/Clicksigninbutton.png)
+
+**Click sign-in button anonymous users:**
+
+![ClicksigninbuttonAnoUser ](Images/ClicksigninbuttonAnoUser.png)
+
+**Anonymous user success page:**
+
+![AnoUsersigninucess ](Images/AnoUsersigninucess.png)
+
+**Click submit vote button:**
+
+![SubmitVote ](Images/SubmitVote.png)
+
+**Anonymous user showing the count:**
+
+![AnoUserpage ](Images/AnoUserpage.png)
+
+**Click submit vote button anonymous users:**
+
+![submitVoteAno ](Images/submitVoteAno.png)
+
+**User showing the count:**
+
+![Resultscreen ](Images/Resultscreen.png)
+
+**Anonymous user showing the count:**
+
+![Resultscreenano ](Images/Resultscreenano.png)
+
+**Remove guest user:**
+
+![RemoveGuestuser21 ](Images/RemoveGuestuser21.png)
+
+**Confirm message:**
+
+![RemovePop22 ](Images/RemovePop22.png)
+
+**The anonymous user was removed from team:**
+
+![SuccessRemovedMessage23 ](Images/SuccessRemovedMessage23.png)
+
+**Remove tenant user:**
+
+![RemoveNormalUser24 ](Images/RemoveNormalUser24.png)
+
+**The tenant user was removed from team:**
+
+![UserRemoverSuccess25 ](Images/UserRemoverSuccess25.png)
+
+**Add users:**
+
+![Adduser26 ](Images/Adduser26.png)
+
+**Welcome to the team:**
+
+![SuccessAddUser27 ](Images/SuccessAddUser27.png)
+
+
+## Further reading
+
+- [Build apps for anonymous users](https://learn.microsoft.com/en-us/microsoftteams/platform/apps-in-teams-meetings/build-apps-for-anonymous-user?branch=pr-en-us-7318&tabs=javascript)
+- [Authentication basics](https://docs.microsoft.com/microsoftteams/platform/concepts/authentication/authentication)
+- [Create facebook app for development](https://developers.facebook.com/docs/development/create-an-app/)
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/Resources/VoteCard.json b/samples/bot-tab-interoperability/csharp/Resources/VoteCard.json
new file mode 100644
index 0000000000..6f591f76a3
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/Resources/VoteCard.json
@@ -0,0 +1,32 @@
+{
+ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
+ "type": "AdaptiveCard",
+ "version": "1.5",
+ "body": [
+ {
+ "type": "Input.ChoiceSet",
+ "id": "requiredExpandedId",
+ "style": "expanded",
+ "label": "Are you interested in playing online chess tournaments?",
+ "isMultiSelect": false,
+ "isRequired": true,
+ "errorMessage": "This is a required input",
+ "choices": [
+ {
+ "title": "Yes",
+ "value": "1"
+ },
+ {
+ "title": "No",
+ "value": "2"
+ }
+ ]
+ }
+ ],
+ "actions": [
+ {
+ "type": "Action.Submit",
+ "title": "Submit Vote"
+ }
+ ]
+}
diff --git a/samples/bot-tab-interoperability/csharp/appsettings.Development.json b/samples/bot-tab-interoperability/csharp/appsettings.Development.json
new file mode 100644
index 0000000000..e203e9407e
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/samples/bot-tab-interoperability/csharp/appsettings.json b/samples/bot-tab-interoperability/csharp/appsettings.json
new file mode 100644
index 0000000000..5cd0c564db
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/appsettings.json
@@ -0,0 +1,17 @@
+{
+ "MicrosoftAppId": "",
+ "MicrosoftAppPassword": "",
+ "MicrosoftAppTenantId": "",
+ "ApplicationBaseUrl": "",
+ "FacebookAppId": "{{FacebookAppId}}",
+ "FacebookAppPassword": "{{Facebook App Password}}",
+ "AzureAd": {
+ "Instance": "https://login.microsoftonline.com/",
+ "TenantId": "",
+ "MicrosoftAppId": "",
+ "MicrosoftAppPassword": "",
+ "ApplicationIdURI": "",
+ "AuthUrl": "/oauth2/v2.0/token",
+ "ValidIssuers": "https://login.microsoftonline.com/tenantId/v2.0,https://sts.windows.net/tenantId/"
+ }
+}
diff --git a/samples/bot-tab-interoperability/csharp/assets/sample.json b/samples/bot-tab-interoperability/csharp/assets/sample.json
new file mode 100644
index 0000000000..45ab67f277
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/assets/sample.json
@@ -0,0 +1,68 @@
+[
+ {
+ "name": "officedev-microsoft-teams-samples-app-anonymous-users-csharp",
+ "source": "officeDev",
+ "title": "Anonymous User Support",
+ "shortDescription": "This sample app shows anonymous users support in Teams meeting apps.",
+ "url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/app-anonymous-users/csharp",
+ "longDescription": [
+ "This sample app shows anonymous users support in Teams meeting apps. It also supports Azure AD and Facebook authentications."
+ ],
+ "creationDateTime": "2023-02-06",
+ "updateDateTime": "2023-02-08",
+ "products": [
+ "Teams"
+ ],
+ "metadata": [
+ {
+ "key": "TEAMS-SAMPLE-SOURCE",
+ "value": "OfficeDev"
+ },
+ {
+ "key": "TEAMS-SERVER-LANGUAGE",
+ "value": "csharp"
+ },
+ {
+ "key": "TEAMS-SERVER-PLATFORM",
+ "value": "netframework"
+ },
+ {
+ "key": "TEAMS-FEATURES",
+ "value": "bot"
+ }
+ ],
+ "thumbnails": [
+ {
+ "type": "image",
+ "order": 100,
+ "url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/app-anonymous-users/csharp/Images/anonymoususersupport.gif",
+ "alt": "Solution UX showing anonymous user support in Teams meeting apps."
+ }
+ ],
+ "authors": [
+ {
+ "gitHubAccount": "OfficeDev",
+ "pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4",
+ "name": "OfficeDev"
+ }
+ ],
+ "references": [
+ {
+ "name": "Teams developer documentation",
+ "url": "https://aka.ms/TeamsPlatformDocs"
+ },
+ {
+ "name": "Teams developer questions",
+ "url": "https://aka.ms/TeamsPlatformFeedback"
+ },
+ {
+ "name": "Teams development videos from Microsoft",
+ "url": "https://aka.ms/sample-ref-teams-vids-from-microsoft"
+ },
+ {
+ "name": "Teams development videos from the community",
+ "url": "https://aka.ms/community/videos/m365powerplatform"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/samples/bot-tab-interoperability/csharp/wwwroot/default.html b/samples/bot-tab-interoperability/csharp/wwwroot/default.html
new file mode 100644
index 0000000000..fcd594fec9
--- /dev/null
+++ b/samples/bot-tab-interoperability/csharp/wwwroot/default.html
@@ -0,0 +1,292 @@
+
+
+
+
+
+
+ Anonymous User Support
+
+
+
+
+
+
+
+
+
Anonymous User Support
+
+
+
+
+
Your bot is ready!
+
+ You can now test your bot in Teams.
+
+ Visit
+ Azure
+ Bot Service
+ to register your bot and add it to the
+ Teams channel. The bot's endpoint URL typically looks
+ like this:
+