OfficeDev / TeamsFx

Developer tools for building Teams apps
Other
427 stars 165 forks source link

Unable to execute action botFramework/create #11100

Closed Naperk closed 3 weeks ago

Naperk commented 1 month ago

Describe the bug When trying to create a Teams App using visual studio toolkit I got the following error: [2024-03-15T12:36:11.123Z] [Error] - Unable to execute action botFramework/create. Error message: API call to Developer Portal failed. Check Output panel for details. [2024-03-15T12:36:11.130Z] [Error] - Failed to Execute lifecycle provision due to failed action: botFramework/create. DeveloperPortalAPIFailedError:API call to Developer Portal failed: AxiosError, Request failed with status code 400, API name: create-bot, X-Correlation-ID: 53f2054f-e1e1-4e42-95da-67cb087cfd39. This may come from some intermittent service error. Please wait for a few minutes and retry the current step. data: "The Microsoft App ID is already registered to another bot application.". Env output: {"TEAMS_APP_ID":"","TEAMS_APP_TENANT_ID":"","BOT_ID":"","SECRET_BOT_PASSWORD":"****"}

Additional context I am debugging the app locally. The bot was already created in Azure Bot Service, I am using the BOT_ID and the SECRET_BOT_PASSWORD.

nliu-ms commented 1 month ago

Hey @Naperk , thanks for reporting this issue. It's duplicate with https://github.com/OfficeDev/TeamsFx/issues/10003, please reference this issue for solution, thanks!

Naperk commented 1 month ago

@nliu-ms It looks like it is not the same issue, in my case the error says: "The Microsoft App ID is already registered to another bot application"

Also, when I remove the bot id, I get the following error:

Unable to execute action botAadApp/create. Error message: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}} [2024-03-19T10:23:41.303Z] [Error] - Failed to Execute lifecycle provision due to failed action: botAadApp/create. HttpClientError:A http client error happened while performing the botAadApp/create task. The error response is: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}}. Env output: {"TEAMS_APP_ID":"","TEAMS_APP_TENANT_ID":""} Summary: (×) Error: Lifecycle stage provision failed. (√) Done: teamsApp/create was executed successfully. (√) Done: Teams app with id ** already exists, skipped creating a new Teams app. (×) Error: botAadApp/create failed. (×) Error: A http client error happened while performing the botAadApp/create task. The error response is: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}}

[Error] - code:botAadAppCreate.HttpClientError, message: A http client error happened while performing the botAadApp/create task. The error response is: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}} Alternatively, you can bypass this step by selecting the 'Debug in Test Tool' option.

When running in debug in test tool it works.

nliu-ms commented 1 month ago

@kuojianlu can you please help to take a look?

kuojianlu commented 1 month ago

@Naperk Can you please remove BOT_ID value from env/.env.local and SECRET_BOT_PASSWORD value from env/.env.local.user, then try F5 in Teams again?

Naperk commented 1 month ago

@kuojianlu I already did that in my previous comment, but I will do it again: image image When running debug in Teams: image

I get the error mentioned above:

Unable to execute action botAadApp/create. Error message: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}} [2024-03-19T10:23:41.303Z] [Error] - Failed to Execute lifecycle provision due to failed action: botAadApp/create. HttpClientError:A http client error happened while performing the botAadApp/create task. The error response is: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}}. Env output: {"TEAMS_APP_ID":"","TEAMS_APP_TENANT_ID":""} Summary: (×) Error: Lifecycle stage provision failed. (√) Done: teamsApp/create was executed successfully. (√) Done: Teams app with id ** already exists, skipped creating a new Teams app. (×) Error: botAadApp/create failed. (×) Error: A http client error happened while performing the botAadApp/create task. The error response is: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}}

[Error] - code:botAadAppCreate.HttpClientError, message: A http client error happened while performing the botAadApp/create task. The error response is: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-03-19T10:23:41","request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473","client-request-id":"a18b86e7-a8f7-475c-9f65-93d4c595c473"}}} Alternatively, you can bypass this step by selecting the 'Debug in Test Tool' option.

When running in debug in test tool it works.

kuojianlu commented 1 month ago

@Naperk It seems that you do not have the permission to create a Microsoft Entra App, can you please check manually if you can create an app with the same M365 account?

Naperk commented 1 month ago

Yes, I don't have permissions to do so, therefore, I asked the admin to create one for me. I am using the client id as the bot id, and the client secret as the bot password. That was created following this guide: https://github.com/OfficeDev/TeamsFx/wiki/Using-existing-Microsoft-Entra-app-in-TeamsFx-project

By doing so, I fixed that problem, I was able to run debug on teams (Edge) and upload the app, but now when sending a message to the bot in Teams, I see this error on the terminal:

` [onTurnError] unhandled error: ServerError: unauthorized_client: 700016 - [2024-03-21 13:55:00Z]: AADSTS700016: Application with identifier '**' was 
not found in the directory 'Bot Framework'. This can happen if the application has not been 
installed by the administrator of the tenant or consented to by any user in the tenant. You 
may have sent your authentication request to the wrong tenant. Trace ID: 5969aab8-6582-463c-8d8e-cbfe15f12000 Correlation ID: 3ee8dca8-e0c4-4c7c-8291-d134c429e009 Timestamp: 2024-03-21 13:55:00Z - Correlation ID: 3ee8dca8-e0c4-4c7c-8291-d134c429e009 - Trace ID: 5969aab8-6582-463c-8d8e-cbfe15f12000
ServerError: unauthorized_client: 700016 - [2024-03-21 13:55:00Z]: AADSTS700016: Application with identifier '**' was not found in the directory 'Bot 
Framework'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant. Trace ID: 27f2a16f-7f85-474e-a7c7-d5ea09bc1e00 Correlation ID: 87d4e973-f009-45bd-aa84-2e1159829952 Timestamp: 2024-03-21 13:55:00Z - Correlation ID: 87d4e973-f009-45bd-aa84-2e1159829952 - Trace ID: 27f2a16f-7f85-474e-a7c7-d5ea09bc1e00
    at ServerError.AuthError [as constructor] (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\src\error\AuthError.ts:49:9)
    at new ServerError (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\src\error\ServerError.ts:14:9)
    at ResponseHandler.validateTokenResponse (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\src\response\ResponseHandler.ts:119:19)
    at ClientCredentialClient.<anonymous> (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\src\client\ClientCredentialClient.ts:173:25)
    at step (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\dist\index.cjs.js:79:23)
    at Object.next (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\dist\index.cjs.js:60:53)
    at fulfilled (C:\Users\nicol\TeamsApps\t4\node_modules\@azure\msal-common\dist\index.cjs.js:50:58)
    at processTicksAndRejections (node:internal/process/task_queues:95:5) {
  errorCode: 'unauthorized_client',
  errorMessage: "700016 - [2024-03-21 13:55:00Z]: AADSTS700016: Application with identifier 
'**' was not found in the directory 'Bot Framework'. This 
can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the 
wrong tenant. Trace ID: 27f2a16f-7f85-474e-a7c7-d5ea09bc1e00 Correlation ID: 87d4e973-f009-45bd-aa84-2e1159829952 Timestamp: 2024-03-21 13:55:00Z - Correlation ID: 87d4e973-f009-45bd-aa84-2e1159829952 - Trace ID: 27f2a16f-7f85-474e-a7c7-d5ea09bc1e00",
  subError: ''
}`

I do see the bot id in the botframework page under my bots (https://dev.botframework.com/bots/)

It caught my attention that it shows issues in the webchat, not in Teams, when sending a message:

image

kuojianlu commented 1 month ago

@Naperk This may be because your Microsoft App is single-tenant, but the bot app in your code is configured with multi-tenant. You can check that. Make sure they are consistent. The bot app is configured may be in src/internal/initialize.js, like https://github.com/OfficeDev/TeamsFx/blob/dev/templates/js/command-and-response/src/internal/initialize.js#L15.

Or you can create a new Microsoft App for Teams Bot with Multitenant. You can follow below steps to create one.

  1. Go to the Azure Portal and select "Microsoft Entra".
  2. Select "App Registrations" and click on "New registration" to create a new Microsoft Entra app:
    • Name: The name of your configuration app.
    • Supported account types: Select "Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant)"
    • Leave the "Redirect URL" field blank for now.
    • Click on the "Register" button.
  3. When the app is registered, you'll be taken to the app's "Overview" page. Copy the Application (client) ID we will need it later.
  4. Go to app's "Certificates & secrets" page, select "Client Secret" and Click on "New client secret".
    • Description: The descirption of your client secret.
    • Expires: The expire time of your client secret.
    • Click on the "Add" button.
  5. When the client secret is added, press the copy button under the "Value" column to copy the Client Secret.

When the Microsoft App is created, paste the Application (client) ID into env/.env.local:

BOT_ID=<your-app-id>

Paste the Client Secret into env/.env.local.user:

SECRET_BOT_PASSWORD=<your-client-secret>

Then debug again.

Naperk commented 1 month ago

@kuojianlu I changed the setting in the index.ts file, replaced by SingleTenant, and included the Tenant ID: image

But now, I get this error:

[onTurnError] unhandled error: RestError: Authorization has been denied for this request. RestError: Authorization has been denied for this request. { "name": "RestError", "statusCode": 401, "request": { "streamResponseStatusCodes": {}, "url": "https://smba.trafficmanager.net/amer/v3/conversations/a%3A14LuhOINCt8VHYi8pmSvZpCqu0OUBNZvAkPon_K7dwneAqazrwZxharRZwgtFSVmnQyAT0GiUDC4ER-K0A8pjA96dl6Jt6DStiGf4z24kKC4vaPTLD1AlXmQn6ZuMSYZc/activities/1711103917800", "method": "POST", "headers": { "_headersMap": { "content-type": "application/json; charset=utf-8", "x-ms-conversation-id": "REDACTED", "accept": "/", "user-agent": "Microsoft-BotFramework/3.1 botframework-connector/4.22.1 core-http/3.0.4 Node/v18.19.1 OS/(x64-Windows_NT-10.0.19045)", "authorization": "REDACTED" } }, "withCredentials": false, "timeout": 0, "requestId": "adfff1e6-7e30-487e-816c-0247cf7c9339" }, "details": { "message": "Authorization has been denied for this request." }, "message": "Authorization has been denied for this request." } Running with Message Activity.

[onTurnError] unhandled error: RestError: Authorization has been denied for this request.
RestError: Authorization has been denied for this request. { "name": "RestError", "statusCode": 401, "request": { "streamResponseStatusCodes": {}, "url": "https://smba.trafficmanager.net/amer/v3/conversations/a%3A14LuhOINCt8VHYi8pmSvZpCqu0OUBNZvAkPon_K7dwneAqazrwZxharRZwgtFSVmnQyAT0GiUDC4ER-K0A8pjA96dl6Jt6DStiGf4z24kKC4vaPTLD1AlXmQn6ZuMSYZc/activities/1711103917800", "method": "POST", "headers": { "_headersMap": { "content-type": "application/json; charset=utf-8", "x-ms-conversation-id": "REDACTED", "accept": "/", "user-agent": "Microsoft-BotFramework/3.1 botframework-connector/4.22.1 core-http/3.0.4 Node/v18.19.1 OS/(x64-Windows_NT-10.0.19045)", "authorization": "REDACTED" } }, "withCredentials": false, "timeout": 0, "requestId": "4fd3151a-c12e-4e9e-af48-8f7695f7c504" }, "details": { "message": "Authorization has been denied for this request." }, "message": "Authorization has been denied for this request." }

[onTurnError] unhandled error: RestError

[onTurnError] unhandled error: RestError

kuojianlu commented 1 month ago

@Naperk Sorry about that, I just verified that the bot created by botFramework/create is always multi-tenant even if your Microsoft App is single-tenant. You can check https://dev.botframework.com/bots/settings?id=<your-bot-id> to see this. image

So the fix can be one of the followings:

First option: Create a new multi-tenant Microsoft App.

Second option: If you indeed want to use single-tenant app:

  1. Create a new single-tenant Microsoft App.
  2. Create a new bot via here: https://dev.botframework.com/bots/new.
    • Bot handle should be the Microsoft App client id.
    • App type should be single-tenant.
    • Schema Transformation Version should be V1.3
Naperk commented 1 month ago

@kuojianlu Thank you very much! I followed the Single Tenant steps and it is working now. Is there any guide for the deployment? I need to ask the admin to create the resources, I can't just run deploy in the Toolkit

kuojianlu commented 1 month ago

@Naperk For deployment, the most convenient way is asking your admin to run the bicep files to create the azure resources.

First, ask your admin to:

  1. Create a new Microsoft App.
  2. Run the bicep file ./infra/azure.bicep with the parameter file ./infra/azure.parameters.json. Remember to replace the placeholders in ./infra/azure.parameters.json with the real values.

After that, you can set the information of the azure resources in env/.env.dev and env/.env.dev.user.

Naperk commented 1 month ago

Thanks @kuojianlu! By creating a new Microsoft App you mean a Microsoft Entra App as the one created before, right? A new app is needed or could I reuse the existing one?

kuojianlu commented 1 month ago

@Naperk Yes, a new Microsoft Entra App. For deployment, the bot is created in Azure, i.e., Azure Bot Service, rather than created in Bot Framework Portal (https://dev.botframework.com). Since a new bot should be created, a new Microsoft Entra App should be created as well.

Naperk commented 1 month ago

Thanks @kuojianlu ! Would it be better to set the Microsoft Entra App as Multitenant, right? Since the App would be created by the admin, would the step Create Access As User Scope for Microsoft Entra app from the guide https://github.com/OfficeDev/TeamsFx/wiki/Using-existing-Microsoft-Entra-app-in-TeamsFx-project be required? Or is there a better way? Is the infra folder, with the updated azure.parameters.json all the admin needs for creating the resources?

Naperk commented 1 month ago

@kuojianlu The admin was able to run the azure.bicep file, but we didn't find any of the output variables after running it:

[Error] - Failed to Execute lifecycle deploy due to failed action: azureAppService/zipDeploy. IllegalResourceId:resourceId is invalid with value: **

I read the output is shown in .env.{envName}, but the admin only used the infra folder to run the bicep file.

xzf0587 commented 1 month ago

@Naperk, it seems that the admin run the azure.bicep to provision resource directly, not using the Teams Toolkit command Provision right? It will not write the output of bicep provision into related env files if not using Teams Tooklit.

The outputs of bicep provision can be found in the bicep file as following. You can get the values from the provisioned resource and write them to the related env files. image

Ideally, to executing the deploy command, the .env.{envName} should include the value about the keys BOT_AZURE_APP_SERVICE_RESOURCE_ID=xxx BOT_DOMAIN=xxx

Naperk commented 1 month ago

Thanks @xzf0587 ! So, does the admin need to install teams toolkit and have run provision with the whole app? We just found inside the json of the app services (web app) the values for the app service resource id and bot domain: image image

After filling the values in dev environment files and running deploy, using teams toolkit, I got the following error message:

[2024-03-28T17:48:02.137Z] [Info] - Get Microsoft Entra token successfully. Upload zip package through AAD Auth mode. [2024-03-28T17:48:03.552Z] [Error] - Upload zip file failed with response status code: 403, message: "" [2024-03-28T17:48:03.568Z] [Error] - Failed to Execute lifecycle deploy due to failed action: azureAppService/zipDeploy. DeployZipPackageError:Unable to deploy zip package to endpoint ** in Azure due to error: {"stack":"Error: status code: 403, message: \"\"\n\tat AzureZipDeployImpl.zipDeployPackage

Suggestions:

  1. Verify that your Azure account has the necessary permissions to access the API.
  2. Verify that the endpoint is properly configured in Azure and that the required resources have been provisioned.
  3. Ensure that the zip package is valid and free of errors.
  4. If the error message specifies the reason, such as an authentication failure or a network issue, fix the error and try again.
  5. If the error still persists, you can attempt to deploy the package manually following the guidelines in this link: 'https://learn.microsoft.com/azure/app-service/deploy-zip?tabs=cli'. Env output: {}

Do I need any permission? Or it is not possible for me to deploy the app?

xzf0587 commented 1 month ago

@Naperk , there is no need for the admin to run the provision command. Based on your reply message, the deploy failed for not enough permission. It means the toolkit tried to deploy the source code to the target app service but failed. So the Azure resource seems provisioned successfully but the Azure account the toolkit logined has no enough permission to upload the zip file to the service. You can try to add some proper permissions for the Azure account to achieve the deploy action.

In addition, can you please share the teamsapp.yml content(without sensitive information) to help us know more about your app?

Naperk commented 1 month ago

Thanks @xzf0587 ! Is there any guide to set the permissions? Yes, sure I share the content of teamsapp.yml:

# yaml-language-server: $schema=https://aka.ms/teams-toolkit/1.0.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.0.0

environmentFolderPath: ./env

# Triggered when 'teamsapp provision' is executed
provision:
  # Creates a Teams app
  - uses: teamsApp/create
    with:
      # Teams app name
      name: botllmfinance0327${{APP_NAME_SUFFIX}}
    # Write the information of created resources into environment file for
    # the specified environment variable(s).
    writeToEnvironmentFile:
      teamsAppId: TEAMS_APP_ID

  # Create or reuse an existing Microsoft Entra application for bot.
  - uses: botAadApp/create
    with:
      # The Microsoft Entra application's display name
      name: botllmfinance0327${{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

  - uses: arm/deploy # Deploy given ARM templates parallelly.
    with:
      # AZURE_SUBSCRIPTION_ID is a built-in environment variable,
      # if its value is empty, TeamsFx will prompt you to select a subscription.
      # Referencing other environment variables with empty values
      # will skip the subscription selection prompt.
      subscriptionId: ${{AZURE_SUBSCRIPTION_ID}}
      # AZURE_RESOURCE_GROUP_NAME is a built-in environment variable,
      # if its value is empty, TeamsFx will prompt you to select or create one
      # resource group.
      # Referencing other environment variables with empty values
      # will skip the resource group selection prompt.
      resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}}
      templates:
        - path: ./infra/azure.bicep # Relative path to this file
          # Relative path to this yaml file.
          # Placeholders will be replaced with corresponding environment
          # variable before ARM deployment.
          parameters: ./infra/azure.parameters.json
          # Required when deploying ARM template
          deploymentName: Create-resources-for-bot
      # Teams Toolkit will download this bicep CLI version from github for you,
      # will use bicep CLI in PATH if you remove this config.
      bicepCliVersion: v0.9.1

  # 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

# Triggered when 'teamsapp deploy' is executed
deploy:
  # Run npm command
  - uses: cli/runNpmCommand
    name: install dependencies
    with:
      args: install
  - uses: cli/runNpmCommand
    name: build app
    with:
      args: run build --if-present
  # Deploy your application to Azure App Service using the zip deploy feature.
  # For additional details, refer to https://aka.ms/zip-deploy-to-app-services.
  - uses: azureAppService/zipDeploy
    with:
      # Deploy base folder
      artifactFolder: .
      # Ignore file location, leave blank will ignore nothing
      ignoreFile: .webappignore
      # The resource id of the cloud resource to be deployed to.
      # This key will be generated by arm/deploy action automatically.
      # You can replace it with your existing Azure Resource id
      # or add it to your environment variable file.
      resourceId: ${{BOT_AZURE_APP_SERVICE_RESOURCE_ID}}

# Triggered when 'teamsapp publish' is executed
publish:
  # 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
  # Publish the app to
  # Teams Admin Center (https://admin.teams.microsoft.com/policies/manage-apps)
  # for review and approval
  - uses: teamsApp/publishAppPackage
    with:
      appPackagePath: ./appPackage/build/appPackage.${{TEAMSFX_ENV}}.zip
    # Write the information of created resources into environment file for
    # the specified environment variable(s).
    writeToEnvironmentFile:
      publishedAppId: TEAMS_APP_PUBLISHED_APP_ID
projectId: d6c41e0d-4996-441a-abae-df4070b024a3

For now, just to test, I created it using the AI Chatbot template.

Naperk commented 1 month ago

@xzf0587 I got permissions and I was able to deploy and run a couple of sample bots in JS, thank you very much!. But now, I would need to integrate a python bot, I found some examples in teams ai library in python, but when deploying they don't work. I found there are other parameters set in the azure.bicep, for example python and its version, is there a way to update the resources based on the other file, or do i need to set up everithing again, and ask for a new provision? I mean, do we need to set up a new entra app, key, set scopes and create new resources or is there a faster way to update them?

xzf0587 commented 1 month ago

@Naperk can you share the azure.bicep and azure.parameters.json in the python project. Actually, you can update the setting in Azure portal for the existing resource without new provision.

frankqianms commented 1 month ago

@xzf0587 I got permissions and I was able to deploy and run a couple of sample bots in JS, thank you very much!. But now, I would need to integrate a python bot, I found some examples in teams ai library in python, but when deploying they don't work. I found there are other parameters set in the azure.bicep, for example python and its version, is there a way to update the resources based on the other file, or do i need to set up everithing again, and ask for a new provision? I mean, do we need to set up a new entra app, key, set scopes and create new resources or is there a faster way to update them?

Hi @Naperk ,

If you want to use Python bot, I'm afraid that you have to create a new web app bot service for your Python app. It is because that Python container for bot service can only be supported by linux os in Azure, which is different from Windows os for JS template. We need different web app service resources for different languages. If you want to customize your runtime stack Python version, you can also configure it in azure.parameters.json like this template before provision. You can also compare the bicep file with JS's. There are several differences. https://github.com/OfficeDev/TeamsFx/blob/5622b6f2c40ee349bb755b67e7f8ad7dd05358ea/templates/python/custom-copilot-basic/infra/azure.parameters.json.tpl#L37

You can quickly scaffold a custom-copilot-basic chat bot template python app with latest pre-release Teams Toolkit to have a try. By the way, teams-ai library is only supported by Python 3.8 to 3.11 now.

Thanks~

Naperk commented 1 month ago

@frankqianms Thank you very much! For the openai api keys, or any other password I want to store and use, Is it mandatory to set it in the bicep and json files or could I set them in the web app config after it is created?

Naperk commented 1 month ago

@frankqianms I found it is possible to change some settings in the Azure Portal, the template that you shared had the following property: appCommandLine: 'gunicorn --bind 0.0.0.0 --worker-class aiohttp.worker.GunicornWebWorker --timeout 600 app:app'

I replaced the last part app:app by api:api, since I had used as template the basic Python echo bot, which has a different naming: https://github.com/microsoft/teams-ai/tree/9199d2bfd191a96ce2f1efd5c85203428a07cbc3/python/samples/01.messaging.a.echoBot By doing so I was able to successfully deploy the Python echo bot.

But, I included some code to use langchain and connect to a db, in order to answer questions, I debugged it locally and it is working as expected, but it does not in the web app hosted in Azure services, is there some way to debug it apart from checking the application logs?

I went to diagnose and solve problems in Azure Portal and I found this:

image

And this is what I see in application logs: image

A detail of the logs:

2024-04-05T01:05:30.549499580Z Traceback (most recent call last):
2024-04-05T01:05:30.549506180Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/arbiter.py", line 609, in spawn_worker
2024-04-05T01:05:30.549511180Z     worker.init_process()
2024-04-05T01:05:30.549538280Z   File "/tmp/8dc55089770b81c/antenv/lib/python3.11/site-packages/aiohttp/worker.py", line 51, in init_process
2024-04-05T01:05:30.549544281Z     super().init_process()
2024-04-05T01:05:30.549548181Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/workers/base.py", line 134, in init_process
2024-04-05T01:05:30.549552181Z     self.load_wsgi()
2024-04-05T01:05:30.549556281Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
2024-04-05T01:05:30.549560381Z     self.wsgi = self.app.wsgi()
2024-04-05T01:05:30.549564081Z                 ^^^^^^^^^^^^^^^
2024-04-05T01:05:30.549567881Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/app/base.py", line 67, in wsgi
2024-04-05T01:05:30.549571781Z     self.callable = self.load()
2024-04-05T01:05:30.549575581Z                     ^^^^^^^^^^^
2024-04-05T01:05:30.549579281Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
2024-04-05T01:05:30.549583181Z     return self.load_wsgiapp()
2024-04-05T01:05:30.549586981Z            ^^^^^^^^^^^^^^^^^^^
2024-04-05T01:05:30.549590781Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
2024-04-05T01:05:30.549594881Z     return util.import_app(self.app_uri)
2024-04-05T01:05:30.549598681Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-04-05T01:05:30.549602482Z   File "/opt/python/3.11.7/lib/python3.11/site-packages/gunicorn/util.py", line 371, in import_app
2024-04-05T01:05:30.549606382Z     mod = importlib.import_module(module)
2024-04-05T01:05:30.549610182Z           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-04-05T01:05:30.549614982Z   File "/opt/python/3.11.7/lib/python3.11/importlib/__init__.py", line 126, in import_module
2024-04-05T01:05:30.549619482Z     return _bootstrap._gcd_import(name[level:], package, level)
2024-04-05T01:05:30.549623282Z            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-04-05T01:05:30.549627082Z   File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
2024-04-05T01:05:30.549631482Z   File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
2024-04-05T01:05:30.549635382Z   File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
2024-04-05T01:05:30.549639382Z   File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
2024-04-05T01:05:30.549643282Z   File "<frozen importlib._bootstrap_external>", line 940, in exec_module
2024-04-05T01:05:30.549647182Z   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
2024-04-05T01:05:30.549653082Z   File "/tmp/8dc55089770b81c/api.py", line 14, in <module>
2024-04-05T01:05:30.549657382Z     from bot import app
2024-04-05T01:05:30.549666083Z   File "/tmp/8dc55089770b81c/bot.py", line 20, in <module>
2024-04-05T01:05:30.549670183Z     import unidecode
2024-04-05T01:05:30.549673983Z ModuleNotFoundError: No module named 'unidecode'

It looks like it didn't installed unidecode successfully, but I had poetry already installed when installing the packages in the environment, Should I do something else to handle the dependencies? Are there any steps or guide to follow?

Some other context comments, but I don't think they are useful:

This is what I see in the platform logs: image

(I am using only OpenAI API, not Azure OpenAI)

The output of the deployment looks good:

[2024-04-05T00:37:26.607Z] [Info] - Executing deploy 

Lifecycle stage: deploy(2 step(s) in total). The following actions will be executed: 
(1/2) Action script
(2/2) Action azureAppService/zipDeploy: deploy the project to the Azure App Service.

[2024-04-05T00:37:26.607Z] [Info] - Executing lifecycle deploy
[2024-04-05T00:37:27.418Z] [Warning] -  [script stderr] Warning: poetry-plugin-export will not be installed by default in a future version of Poetry.
In order to avoid a breaking change and make your automation forward-compatible, please install poetry-plugin-export explicitly. See https://python-poetry.org/docs/plugins/#using-plugins for details on how to install a plugin.
To disable this warning run 'poetry config warnings.export false'.

[2024-04-05T00:37:27.745Z] [Info] - Get Microsoft Entra token successfully. Upload zip package through AAD Auth mode.
[2024-04-05T00:40:13.976Z] [Info] - Deploying to Azure App Service takes a long time. Consider referring to this document to optimize your deployment: https://aka.ms/teamsfx-config-run-from-package
[2024-04-05T00:40:13.979Z] [Info] - Finished Executing lifecycle deploy. Result: {}
[2024-04-05T00:40:13.981Z] [Info] - Execution summary:

Summary:
(√) Done: Lifecycle stage deploy was executed successfully.
  (√) Done: script was executed successfully.
    (√) Done: Successfully executed command poetry export --without-hashes --format=requirements.txt --output=src/requirements.txt

  (√) Done: azureAppService/zipDeploy was executed successfully.
    (√) Done: Successfully deployed `**` to Azure App Service.
xzf0587 commented 1 month ago

@frankqianms Thank you very much! For the openai api keys, or any other password I want to store and use, Is it mandatory to set it in the bicep and json files or could I set them in the web app config after it is created?

@Naperk Yes. You can set them in any ways after provision. The toolkit prefers to set them in bicep because the manual settings will lose after re-provision. If the resource will not be re-provisioned or you can set them after every provision. It could be OK.

Naperk commented 1 month ago

Thank you very much @xzf0587 ! I am having some issues with the dependencies, teams ai requires a different version of tik token than langchain-openai. In my local environment it is working, it looks like somehow the constrain for teams-ai is not considered when running (I have tiktoken 0.6.0 installed), but I am not being able to replicate the environment in the web app using Poetry or the requirements file, do you know of any workaround?

frankqianms commented 1 month ago

Hi @Naperk,

As far as I know, you have to write all the dependencies in a requirements.txt and include it in your deployed zip package. Remember to set SCM_DO_BUILD_DURING_DEPLOYMENT to 'true'. This property enables remote container to auto pip install dependencies according to your requirements.txt after zip deployment.

You can refer to this doc for more informatin: https://learn.microsoft.com/en-us/azure/app-service/configure-language-python#customize-build-automation

Thank you very much~

Naperk commented 1 month ago

Thank you very much for all the help! I was able to get the bot running. Just one more question, do you know how could I include the context, I mean the chat or conversation history?

xzf0587 commented 1 month ago

Thank you very much for all the help! I was able to get the bot running. Just one more question, do you know how could I include the context, I mean the chat or conversation history?

Teams bot is driven by event. In the context, you can get the conversation message. Please refer to bots-conversations. Especially, the bot in chat/channel can only get the messages mentioned it. For the conversation history, you need to call corresponding Graph API to get and search, which can not be found in context. Please refer to channel-list-messages API and other similar APIs. For bot scenario, RSC permission is easier to use than AAD app permission. Please refer to RSC permission for it.

microsoft-github-policy-service[bot] commented 3 weeks ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

Naperk commented 3 weeks ago

Thank you very much @xzf0587! I was able to find the field to set the conversation history