Teams message extension - Dialog with an embedded web view NOT shown after returned by OnTeamsMessagingExtensionFetchTaskAsync

dong weiyan 0 Reputation points
2025-04-09T07:54:07.75+00:00

We have a demo teams app which has tab, bot and message extension using vs2022 and teams toolkit. According to https://learn.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/action-commands/create-task-module?source=recommendations&tabs=dotnet, A custom dialog will be shown after click message extension of one message,actually in local debug we got error “Unable to reach app. Please try again.” and Chrome develope console show error "Failed to load resource: the server responded with a status of 502 (https://teams.microsoft.com/api/chatsvc/apac/v1/agents/28:cdfb6399-ea8d-485d-aa12-64160b54589c/invoke)".

2

The following is the content of manifest.json:

{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
  "manifestVersion": "1.16",
  "version": "1.0.0",
  "id": "${{TEAMS_APP_ID}}",
  "packageName": "com.microsoft.teams.extension",
  "developer": {
    "name": "Teams App, Inc.",
    "websiteUrl": "https://www.example.com",
    "privacyUrl": "https://www.example.com/privacy",
    "termsOfUseUrl": "https://www.example.com/termsofuse"
  },
  "icons": {
    "color": "color.png",
    "outline": "outline.png"
  },
  "name": {
    "short": "TabMod${{APP_NAME_SUFFIX}}",
    "full": "Full name for TabMod"
  },
  "description": {
    "short": "Short description of TabMod",
    "full": "Full description of TabMod"
  },
  "accentColor": "#FFFFFF",
  "bots": [
    {
      "botId": "${{BOT_ID}}",
      "scopes": [
        "personal",
        "team"
      ],
      "supportsFiles": false,
      "isNotificationOnly": false,
      "commandLists": [
        {
          "scopes": [
            "personal",
            "team"
          ],
          "commands": [
            {
              "title": "Login",
              "description": "Login your Tungsten Account"
            },
            {
              "title": "Logout",
              "description": "Logout your Tungsten Account"
            }
          ]
        }
      ]
    }
  ],
  "composeExtensions": [
    {
      "botId": "${{BOT_ID}}",
      "commands": [
        {
          "id": "createCard",
          "context": [
            "compose"
          ],
          "description": "Command to run action to create a Card from Compose Box",
          "title": "TabMod Create Card",
          "type": "action",
          "parameters": [
            {
              "name": "title",
              "title": "Card title",
              "description": "Title for the card",
              "inputType": "text"
            },
            {
              "name": "subTitle",
              "title": "Subtitle",
              "description": "Subtitle for the card",
              "inputType": "text"
            },
            {
              "name": "text",
              "title": "Text",
              "description": "Text for the card",
              "inputType": "textarea"
            }
          ]
        },
        {
          "id": "collaborate",
          "context": [
            "message"
          ],
          "description": "Command to run action to create a Card from Compose Box",
          "title": "TabMod Collaborate",
          "type": "action",
          "fetchTask": true
        }
      ]
    }
  ],
  "configurableTabs": [
    {
      "configurationUrl": "${{TAB_ENDPOINT}}/config",
      "canUpdateConfiguration": true,
      "scopes": [
        "team",
        "groupchat"
      ]
    }
  ],
  "staticTabs": [
    {
      "entityId": "index",
      "name": "Personal Tab",
      "contentUrl": "${{TAB_ENDPOINT}}/tab",
      "websiteUrl": "${{TAB_ENDPOINT}}/tab",
      "scopes": [
        "personal"
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "${{TAB_DOMAIN}}"
  ],
  "webApplicationInfo": {
    "id": "${{AAD_APP_CLIENT_ID}}",
    "resource": "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}"
  }
}

The following is the content of teamsapp.local.yml:

# yaml-language-server: $schema=https://aka.ms/teams-toolkit/1.1.0/yaml.schema.json
# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file
# Visit https://aka.ms/teamsfx-actions for details on actions
version: 1.1.0
provision:
  # Creates a new Microsoft Entra app to authenticate users if
  # the environment variable that stores clientId is empty
  - uses: aadApp/create
    with:
      # Note: when you run aadApp/update, the Microsoft Entra app name will be updated
      # based on the definition in manifest. If you don't want to change the
      # name, make sure the name in Microsoft Entra manifest is the same with the name
      # defined here.
      name: TabMod
      # If the value is false, the action will not generate client secret for you
      generateClientSecret: true
      # Authenticate users with a Microsoft work or school account in your
      # organization's Microsoft Entra tenant (for example, single tenant).
      signInAudience: AzureADMyOrg
    # Write the information of created resources into environment file for the
    # specified environment variable(s).
    writeToEnvironmentFile:
      clientId: AAD_APP_CLIENT_ID
      # Environment variable that starts with `SECRET_` will be stored to the
      # .env.{envName}.user environment file
      clientSecret: SECRET_AAD_APP_CLIENT_SECRET
      objectId: AAD_APP_OBJECT_ID
      tenantId: AAD_APP_TENANT_ID
      authority: AAD_APP_OAUTH_AUTHORITY
      authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST
  # Creates a Teams app
  - uses: teamsApp/create
    with:
      # Teams app name
      name: TabMod${{APP_NAME_SUFFIX}}
    # Write the information of created resources into environment file for
    # the specified environment variable(s).
    writeToEnvironmentFile:
      teamsAppId: TEAMS_APP_ID
  # Set TAB_DOMAIN and TAB_ENDPOINT for local launch
  - uses: script
    with:
      run:
        echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302";
        echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302";
  #BOT #1
  # Create or reuse an existing Microsoft Entra application for bot.
  - uses: botAadApp/create
    with:
      # The Microsoft Entra application's display name
      name: Echo${{APP_NAME_SUFFIX}}
    writeToEnvironmentFile:
      # The Microsoft Entra application's client id created for bot.
      botId: BOT_ID
      # The Microsoft Entra application's client secret created for bot.
      botPassword: SECRET_BOT_PASSWORD
  # Generate runtime appsettings to JSON file
  - uses: file/createOrUpdateJsonFile
    with:
      target: ../appsettings.Development.json
      content:
        TeamsFx:
          Authentication:
            ClientId: ${{AAD_APP_CLIENT_ID}}
            ClientSecret: ${{SECRET_AAD_APP_CLIENT_SECRET}}
            InitiateLoginEndpoint: ${{TAB_ENDPOINT}}/auth-start.html
            OAuthAuthority: ${{AAD_APP_OAUTH_AUTHORITY}}
        BOT_ID: ${{BOT_ID}}
        BOT_PASSWORD: ${{SECRET_BOT_PASSWORD}}
  #BOT #2
  # Create or update the bot registration on dev.botframework.com
  - uses: botFramework/create
    with:
      botId: ${{BOT_ID}}
      name: Echo
      messagingEndpoint: ${{BOT_ENDPOINT}}/api/messages
      description: ""
      channels:
        - name: msteams
  # Apply the Microsoft Entra manifest to an existing Microsoft Entra app. Will use the object id in
  # manifest file to determine which Microsoft Entra app to update.
  - uses: aadApp/update
    with:
      # Relative path to this file. Environment variables in manifest will
      # be replaced before apply to Microsoft Entra app
      manifestPath: ./aad.manifest.json
      outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json
  # Validate using manifest schema
  - uses: teamsApp/validateManifest
    with:
      # Path to manifest template
      manifestPath: ./appPackage/manifest.json
  # Build Teams app package with latest env value
  - uses: teamsApp/zipAppPackage
    with:
      # Path to manifest template
      manifestPath: ./appPackage/manifest.json
      outputZipPath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip
      outputJsonPath: ./appPackage/build/manifest.${{TEAMSFX_ENV}}.json
  # Validate app package using validation rules
  - uses: teamsApp/validateAppPackage
    with:
      # Relative path to this file. This is the path for built zip file.
      appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip
  # Apply the Teams app manifest to an existing Teams app in
  # Teams Developer Portal.
  # Will use the app id in manifest file to determine which Teams app to update.
  - uses: teamsApp/update
    with:
      # Relative path to this file. This is the path for built zip file.
      appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip
  # Extend your Teams app to Outlook and the Microsoft 365 app
  - uses: teamsApp/extendToM365
    with:
      # Relative path to the build app package.
      appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip
    # Write the information of created resources into environment file for
    # the specified environment variable(s).
    writeToEnvironmentFile:
      titleId: M365_TITLE_ID
      appId: M365_APP_ID

And the following is the code return dialog:

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(

        ITurnContext<IInvokeActivity> turnContext,

        MessagingExtensionAction action,

        CancellationToken cancellationToken)

{

    return new MessagingExtensionActionResponse

    {

        Task = new TaskModuleContinueResponse

        {

            Value = new TaskModuleTaskInfo

            {

                Height = "800",

                Width = "900",

                Title = "Collaborat PDF",

                Url = "https://localhost:44302/tab"

            },

        },

    };

}

If a adaptive card was returned using the folowing code, it was shown correctly.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(

        ITurnContext<IInvokeActivity> turnContext,

        MessagingExtensionAction action,

        CancellationToken cancellationToken)

{
    string message = "TEST MESSGAE";

	var cardTemplate = await File.ReadAllTextAsync(_noAttachInMsgAdaptiveCardFilePath, cancellationToken);
	var cardContent = new AdaptiveCardTemplate(cardTemplate).Expand
	(
		new
		{
			Description = message,
		}
	);

	return new MessagingExtensionActionResponse
	{
		Task = new TaskModuleContinueResponse
		{
			Value = new TaskModuleTaskInfo
			{
				Card = new Microsoft.Bot.Schema.Attachment
				{
					ContentType = "application/vnd.microsoft.card.adaptive",
					Content = JsonConvert.DeserializeObject(cardContent),
				},
				Height = "small",
				Width = "small",
			},
		},
	};
}

Microsoft Visual Studio Enterprise 2022 (64-bit) Version 17.10.3 was used and Teams toolkit command Prepare Teams App Dependency was ok.

Thanks for any suggestion.

Microsoft Teams Development
{count} votes

2 answers

Sort by: Most helpful
  1. dong weiyan 0 Reputation points
    2025-04-10T01:39:51.1433333+00:00

    I checked the output window of visual studio and find the following:

    TabMod Error: 0 : Error refreshing OpenId configuration: System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://login.botframework.com/v1/.well-known/openidconfiguration'. Will retry at '1/1/0001 12:00:00 AM +00:00'. Exception: 'System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://login.botframework.com/v1/.well-known/openidconfiguration'.
     ---> System.Net.Http.HttpRequestException: No such host is known. (login.botframework.com:443)
     ---> System.Net.Sockets.SocketException (11001): No such host is known.
       at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
       at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
       at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|285_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
       at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
       --- End of inner exception stack trace ---
       at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
       at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
       at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
       at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
       at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
       at System.Net.Http.HttpConnectionPool.HttpConnectionWaiter`1.WaitForConnectionWithTelemetryAsync(HttpRequestMessage request, HttpConnectionPool pool, Boolean async, CancellationToken requestCancellationToken)
       at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
       at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
       at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
       at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
       at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.SendAndRetryOnNetworkErrorAsync(HttpClient httpClient, Uri uri)
       at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
       --- End of inner exception stack trace ---
       at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
       at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
       at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)'.
    
    

    I noticed

    No such host is known. (login.botframework.com:443)
    
    

    Maybe it is dns lookup problem, i tried "nslookup login.botframework.com" and "nslookup login.botframework.com:443" in command line.

    3

    It looks like "login.botframework.com:443" is not a valid domain name, but i can't find the define in the project. Maybe it is defined otherwhere and i tried to rediect the domain name to the right ip address in hosts file, but it didnot work.


  2. Yimin Jin 0 Reputation points Microsoft Employee
    2025-04-10T07:03:06.8666667+00:00

    This appears to be an issue with the BotFramework SDK. You might consider raising this question in the BotFramework SDK repository: https://github.com/microsoft/botframework-sdk.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.