Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does Teams Notification Bot need MS Graph Permissions? #7920

Closed
Aaron0176 opened this issue Jan 18, 2023 · 59 comments
Closed

Does Teams Notification Bot need MS Graph Permissions? #7920

Aaron0176 opened this issue Jan 18, 2023 · 59 comments
Assignees
Labels
teams-developer-support Question related to extensibility (Bot, ME, Tab) would be marked under this label

Comments

@Aaron0176
Copy link

I just completed the below tutorial on notification bots.
One question on this one when it comes to authorizations:

When I deploy my app to Azure - do I need to grant MS graph permissions to the bot so it can send chat messages?

If yes, is there a list of permissions which is needed for the below tutorial?
In my case its a daemon application, so I'm thinking about application permission like 'Chat.ReadWrite.WhereInstalled'.


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

@ghost
Copy link

ghost commented Jan 18, 2023

Hi AaronSchwarzSAP! Thank you for bringing this issue to our attention. We will investigate and if we require further information we will reach out in one business day. Please use this link to escalate if you don't get replies.

Best regards, Teams Platform

@ghost ghost added the needs-triage 🔍 label Jan 18, 2023
@ghost ghost added this to Needs triage in Teams App Development Jan 18, 2023
@ghost ghost added the teams-developer-support Question related to extensibility (Bot, ME, Tab) would be marked under this label label Jan 18, 2023
@Prasad-MSFT Prasad-MSFT self-assigned this Jan 19, 2023
@Prasad-MSFT
Copy link
Collaborator

@AaronSchwarz0176 - No, you don't need to grant any MS graph permissions to the bot. Just need to follow this step-by-step guide.

@Aaron0176
Copy link
Author

Aaron0176 commented Jan 19, 2023

Sounds good, but unfortunately my bot is not sending notifications in the deployed state.

So I'm trying to debug it with sideloading. But when starting the Debug session in VSC I get the following error:
× AadCreateAppError: Failed to create an app in Azure Active Directory.
But actually I want to reuse an existing AAD app.

I tried with the following config:

  1. in config.dev.json & config.local.json I added the following:
"bot": {
        "appId":  clientID
        "appPassword": clientSecret
        "objectId": objectID
    },
    "auth": {
        "clientId": clientID
        "clientSecret": clientSecret,
        "objectId": objectID
        }
  1. In provision parameters I added this:
 "provisionParameters": {
      "value": {
        "botAadAppClientId": clientID
        "botAadAppClientSecret":  clientSecret,
        "teamsAppTenantId": "tenantID"
...
      }
  1. Executed "Provision to cloud"
  2. Executed "Deploy to cloud"

But it still seems to be trying to register a new AAD app... Any ideas?

One other thing I don't understand yet:
I'm deploying my bot to the cloud, but I can publish my bot as well to Teams.
How are these two deployments related? Are they completely independent?

@Prasad-MSFT
Copy link
Collaborator

Prasad-MSFT commented Jan 20, 2023

@AaronSchwarz0176 - You should not use your existing app id. It will create a new AAD app by its own.
In Azure AD, app provisioning refers to automatically creating copies of user identities in the applications that users need access to, for applications that have their own data store, distinct from Azure AD or Active Directory.

@Aaron0176
Copy link
Author

But when deploying to Azure I was able to reuse my AAD app. Why is it not possible while sideloading?

One other thing I don't understand yet:
I'm deploying my bot to Azure, but I can publish my bot as well to Teams.
How are these two deployments related? Are they completely independent?

I recognized once I deploy a new version to Azure, my teams app seems as well updated.
But in which case do I need to publish to Teams then? Is it only a one-time operation for the initial provisioning and after that its sufficient to deploy to Azure?

@Prasad-MSFT
Copy link
Collaborator

Prasad-MSFT commented Jan 23, 2023

We followed this guide and the sample worked properly.
Please refer below document which explains provisioning and publishing bot in Azure.
https://learn.microsoft.com/en-us/azure/bot-service/provision-and-publish-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Ccsharp
To update the app, in the left navigation of the Microsoft Teams admin center, go to Teams apps > Manage apps. select the app name, and then select Update. Updating the app replaces the existing app, and all app permission policies and app setup policies remain enforced for the updated app.

@Aaron0176
Copy link
Author

Thats not really answering my question.

Whats the difference between "deploy to the cloud" and "publish to teams"?

@ChetanSharma-msft
Copy link
Collaborator

ChetanSharma-msft commented Jan 23, 2023

Hello @AaronSchwarz0176 -
Hope you are doing well!!

Deploy to the cloud: Teams Toolkit helps to deploy or upload the front-end and back-end code in your app to your provisioned cloud resources in Azure. Your App's business logic runs in these deployed Azure resources. You redeploy your code to cloud whenever business logic is changed.

Publish to teams: Allows you to Publish a custom app by uploading an app package. When you publish a custom Teams app, it's available to users in your organization's app store. You publish your app one time and re-publish only when you edit your manifest.json file (like adding new tab or updating display name of your app).

Teams doesn't host your app. When a user installs your app in Teams, they install an app package that contains only a configuration file (also known as an app manifest) and your app's icons. The app's logic and data storage are hosted elsewhere, such as on localhost during development and Azure Web Services. Teams accesses these resources via HTTPS.
image

Please let me know if you have any more questions.

@Aaron0176
Copy link
Author

Aaron0176 commented Jan 23, 2023

@Wajeed-msft Thanks, that helped.

So deploying the App to Cloud/Azure is the right approach for updating business logic,
Publishing to teams is only updating metadata like version-number, app-name etc?

I guess the connection between these two is the teamsAppId in state.dev.json?

One more question:

My app is constantly showing 0 Bot-Installations, although I deployed/published/installed the latest version.

Any chance how this can happen? Is there some kind of caching when a new version is published? Any chance to debug/reset this bot-installations?

@Aaron0176
Copy link
Author

Aaron0176 commented Jan 23, 2023

I tried things like, deleting the app from teams app-store, de-installing the app, redeploying, republishing, but still no Bot installations found (await bot.notification.installations())

Might it be related to the storage? I'm still using the local one so far.

@Aaron0176
Copy link
Author

I read here that the notifications connections should be stored at this place, when the bot is deployed:

${process.env.TEMP}/.notification.localstore.json, if process.env.RUNNING_ON_AZURE is set to 1.

How can I access this file?

@Prasad-MSFT
Copy link
Collaborator

Okay, @AaronSchwarz0176 - We are checking on it. We will get back to you if there is any update.

@Aaron0176
Copy link
Author

I added a Azure blob storage now, as described here.

My container is created successfully and I don't see error, but container stays empty and no bot installations seem to be persisted.

@Aaron0176
Copy link
Author

Any Update on this?

I would like to go-live with my bot next month and at the moment I can't use it at all due to the missing persistence of the installations.

@ChetanSharma-msft
Copy link
Collaborator

Hello @AaronSchwarz0176 - Sorry for delay in response.
Could you please share the error logs if any, so that we can investigate further on your issue?

@Aaron0176
Copy link
Author

So far I did not see any error logs, the storage is just never filled.

If there would be logs, where would I find them?

@ChetanSharma-msft
Copy link
Collaborator

If you have deployed your application, could you please check if you see any log in your azure application insights?

@Aaron0176
Copy link
Author

image

Which table do you need? Exceptions is empty

@ChetanSharma-msft
Copy link
Collaborator

ChetanSharma-msft commented Jan 27, 2023

Generally we see Exceptions table, but as per the above screeshots, it's returning result code as 401 which means unauthorized.

We will also try it from our end and let you know the updates.

Just one query:
Where exactly you are seeing 0 Bot-Installations?
Could you please share a short video or screenshot?

@Aaron0176
Copy link
Author

Aaron0176 commented Jan 27, 2023

image

Sorry the screenshot was a bit misleading.

As you can see the post-requests to /api/notification return status 200.
/api/messages is not used/implemented.

Why I believe there are no bot installations:

  • blob storage is empty

image

- Post-Requests returns Code 200, and 0 Installations

image

- Coding:

image

  • App is installed:

image

@ChetanSharma-msft
Copy link
Collaborator

Thanks for sharing the details.
We are trying it from our end and let you know the updates.

@Aaron0176
Copy link
Author

@ChetanSharma-msft Any update on this?

@ChetanSharma-msft
Copy link
Collaborator

Hello @AaronSchwarz0176 - We have tried this sample but unfortunately facing issue while executing Windows PowerShell Command:
Invoke-Webrequest -Method POST -URI http://localhost:3978/api/notification 

PS C:\WINDOWS\system32> Invoke-Webrequest -Method POST -URI http://localhost:3978/api/notification
Invoke-Webrequest : Unable to connect to the remote server

So, we are looking into it and once it is resolved we will let you know the further updates.

@Aaron0176
Copy link
Author

Thanks for the effort.

Can you foresee when you can provide a solution?
We are currently planning the go-live of our notification-bot and currently we are fully blocked due to this.

@ChetanSharma-msft
Copy link
Collaborator

ChetanSharma-msft commented Feb 3, 2023

Hello @AaronSchwarz0176 - Could you please confirm whether your app is working locally and getting notifications with or without using storage connection?

Also, could you please try to install the app for different users and let us know if it's working or not?

@Aaron0176
Copy link
Author

Aaron0176 commented Feb 10, 2023

Public blob storage is currently prohibited by my org policy...

But as I'm accessing through an connection-string, I think it should not need a public access, right?

I'm getting my connection-string from "Access keys" of my storage account, is that correct? Or do I need a shared access signtature (SAS)?

@ChetanSharma-msft
Copy link
Collaborator

Hello @AaronSchwarz0176 - This is the correct way of getting storage connection string.
Sorry for the delay, we are still checking on it from our end and let you know the updates.

@ChetanSharma-msft
Copy link
Collaborator

Hello @AaronSchwarz0176 - We are also experiencing the behaviour where storage is always empty.

We will check other bot framework samples and let you know the updates.

@Prasad-MSFT
Copy link
Collaborator

@AaronSchwarz0176 - We tried this bot-builder sample locally and noticed that user and conversation data in bot is getting stored in Azure blob storage.

var storage = new AzureBlobStorage("<blob-storage-connection-string>", "bot-state");

We will check your issue with engineering team, and we will inform you if there is any update. Thanks!

@Aaron0176
Copy link
Author

Thanks, that sounds promising.

so is that implementation something I can try for my notification bot as well?

@ChetanSharma-msft
Copy link
Collaborator

Hello @AaronSchwarz0176 - We are checking the issue with engineering team.
Meanwhile, you can try to implement the notification bot.

@Aaron0176
Copy link
Author

okay, I can't find the source of the AzureBlobStorage class and it is csharp, can't use that ...

So waiting for the engineering team, thanks.

@Prasad-MSFT
Copy link
Collaborator

@AaronSchwarz0176 - This is in node JS. Please have a look.
https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/45.state-management

@Aaron0176
Copy link
Author

Unfortunately I don't see how I can apply this to my project...

When can we expect answer from the engineering team?

@ChetanSharma-msft
Copy link
Collaborator

Hello @AaronSchwarz0176 - We are checking with engineering team and let you know the updates.

@hund030
Copy link

hund030 commented Feb 24, 2023

@AaronSchwarz0176 You get 401 when post api/messages, which means your bot is not setup correctly. I think that's why you can't receive notification from bot.
That's usually caused by wrong botId & botPassword. Could you check your app service app setting? The BOT_ID should be the client id of your AAD app, and the BOT_PASSWORD should be the client secret.
image

@Aaron0176
Copy link
Author

@hund030 BOT_ID and BOT_PASSWORD are matching clientID and clientSecret of my AAD app registration.

What is this api/messages endpoint supposed to do? Do I really need it for sending notifications?

I did not implement anything here, my code is listening to /api/notification.
image

These post-requests seemed to be automatically triggered, not by me.

When I send a POST request with a valid access token and a empty JSON to /api/messages it returns Code 400 Bad Request "Error: validateAndFixActivity(): missing activity type."

Do you have sample payload for this endpoint to verify if it will return 401 as well?

@swatDong
Copy link
Collaborator

@AaronSchwarz0176 /api/messages, BOT_ID, and BOT_PASSWORD are used to connect your bot code with Teams bot app. So 401 means your bot is not correctly connected.

As you mentioned you reuse an existing AAD app, do you also reuse the bot registration (Azure Bot Service)? If so, please make sure following IDs have the same value:

  • The bots.botId in your teams app manifest.json
  • The Microsoft App ID in your Azure Bot Service's configuration
  • The BOT_ID in your app service app settings

In addition, you can directly log the request header/body of /api/messages to get sample payload:

server.post("/api/messages", async (req, res) => {
  /// add log here... e.g., req.header..., req.body...

  await bot.requestHandler(req, res);
});

You can manually trigger "/api/messages" by entering anything in the Teams chat with your bot.

cc @hund030

@Aaron0176
Copy link
Author

Aaron0176 commented Feb 28, 2023

@swatDong thanks for the input.

I can verify that bots.botid, microsoft app id and bot_Id all have the same value.

One more detail: I added my Azure IDP as authentication config in the app service:
Bildschirm­foto 2023-02-28 um 10 41 14

When I disable this config, the requests to /api/messages/ are returning 200, however then my requests to /api/notifications are failing with the following error:

"Error: Get Token request returned http error: 400 and server response: {"error":"unauthorized_client","error_description":"AADSTS700016: Application with identifier '2e4(...)' 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."

When I re-enable the auth config the error stays the same now ... not sure if its cached and takes some time..

Any ideas?

@Aaron0176
Copy link
Author

Aaron0176 commented Feb 28, 2023

I changed my app config to "multitenant" (as described here) and now the notifications are sent!

image

My admin told me that multi-tenant is not supported in general - Is it really mandatory for the bot to work?

@swatDong
Copy link
Collaborator

swatDong commented Mar 1, 2023

@AaronSchwarz0176

For the authentication part - it seems your authentication config on app service applies to both /api/messages and /api/notification APIs. I'd suggest to only add auth to /api/notification, not to /api/messages.

  • /api/messages has its own auth logic in Bot Framework SDK, so your auth config may impact it.
  • /api/notification by default is anonymous and you can add any auth config to it.

For the multi-tenant part - now bot supports both single-tenant and multi-tenant, but you need to update your code as well.
If your project is generated by latest Teams Toolkit, there should be a MultiTenant value in initialize.js|ts, and you need to update that value as well.
For example, our sample has the similar code - https://github.com/OfficeDev/TeamsFx-Samples/blob/dev/stocks-update-notification-bot/bot/src/internal/initialize.ts#L11
And change it to:

  adapterConfig: {
    MicrosoftAppId: process.env.BOT_ID,
    MicrosoftAppPassword: process.env.BOT_PASSWORD,
    //MicrosoftAppType: "MultiTenant",
    MicrosoftAppType: "SingleTenant",
    MicrosoftAppTenantId: "your-tenant-id"
  },

Or, if your project is generated earlier, it only supports multi-tenant. Since old bot SDK only supports multi-tenant. More doc can be found at https://learn.microsoft.com/azure/bot-service/bot-service-quickstart-registration

@Aaron0176
Copy link
Author

Aaron0176 commented Mar 1, 2023

I adapted the config in initialize.js to SingleTenant and switched the Azure AD App to SingleTenant and re-deployed. Getting unauthorized_client again. I gave the tenantID of my Azure AD directory, correct? Do I need to re-provision again?

Which version is supporting single tenancy?
I'm running with the following versions currently:
"@microsoft/teamsfx": "^2.0.0",
"botbuilder": "^4.18.0"

@swatDong
Copy link
Collaborator

swatDong commented Mar 1, 2023

The "botbuilder": "^4.18.0" supports single tenant.

Yep you need to re-provision again, to make sure all resources are configured as single tenant:

  • Your AAD app config (already done)
  • Your bot code (already done)
  • Your Azure Bot Service's configuration has Bot Type: SingleTenant

image

Also, to ensure your Teams app is up-to-date, better to uninstall the app then re-add the app to Team again.

@Aaron0176
Copy link
Author

Aaron0176 commented Mar 1, 2023

image

I can't even see that bot type setting?!

Can I set it in the coding?

Currently its still showing the error.

@swatDong
Copy link
Collaborator

swatDong commented Mar 1, 2023

Tenant was set at the bot creation time, so you may need to re-create the Azure Bot Service.

If your Azure Bot Service was created via provision:

  • Delete the Azure Bot Service
  • Update templates/azure/provision/botService.bicep to add msaAppType and msaAppTenantId
  properties: {
    displayName: botDisplayName
    endpoint: uri(botEndpoint, '/api/messages')
    msaAppId: botAadAppClientId
    msaAppType: 'SingleTenant'
    msaAppTenantId: 'your-tenant-id'
  }
  • Re-provision to re-create Azure Bot Service

In addition, after reinstall the teams app, please also clear old notification connections from your storage if you have your own storage. (Or restart the app service to make sure the temp storage is cleared as well)

@Aaron0176
Copy link
Author

Aaron0176 commented Mar 1, 2023

Now we are back at the initial problem again, bot is not returning any installations, storage is empty.

I deleted the bot service, updated the .bicep file, "SingleTenant" is now visible in Azure Portal.

I re-provisioned, redeployed, republished, reinstalled teams app, restarted the app service, cleared the storage.

Any ideas?

@Aaron0176
Copy link
Author

Aaron0176 commented Mar 1, 2023

I disabled my app service auth config - now I get the unauthorized_client again as earlier...Happy to jump on a call if that makes things easier

@swatDong
Copy link
Collaborator

swatDong commented Mar 2, 2023

Per my test, unauthorized_client occurs when "SingleTenant" is not correctly set in the code initialize.js.
To support single tenant, need to use CloudAdapter and set MicrosoftAppType: "SingleTenant". E.g.,

const { BotBuilderCloudAdapter } = require("@microsoft/teamsfx");
const ConversationBot = BotBuilderCloudAdapter.ConversationBot;
...

// Create bot.
const bot = new ConversationBot({
  // The bot id and password to create CloudAdapter.
  // See https://aka.ms/about-bot-adapter to learn more about adapters.
  adapterConfig: {
    MicrosoftAppId: config.botId,
    MicrosoftAppPassword: config.botPassword,
    MicrosoftAppType: "SingleTenant",
    MicrosoftAppTenantId: "{{your-tenant-id}}"
  },
...

Fine to have a call on this. Is it convenient to contact you on Teams? (I did not find any contact info from your github profile)

@Aaron0176
Copy link
Author

After upgrading to "@microsoft/teamsfx": "^2.2.0" this did the trick for me :)

Thanks a lot for the great support @swatDong!

@Prasad-MSFT
Copy link
Collaborator

We are closing this issue for now. Please feel free to reopen if required. Thanks!

Teams App Development automation moved this from Needs triage to Closed Mar 27, 2023
@ghost
Copy link

ghost commented Mar 27, 2023

Tell us about your experience!

Hi AaronSchwarz0176! This issue is closed in our system. We would like your feedback on your experience with our support team and Platform.

Best regards,
Teams Platform

@ghost ghost locked as resolved and limited conversation to collaborators Apr 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
teams-developer-support Question related to extensibility (Bot, ME, Tab) would be marked under this label
Projects
Development

No branches or pull requests

5 participants