How to have app send message to Microsoft Teams via Graph API? - node.js

I want to be able to use the graph API to get a list of channels & teams, then have the app send an update to the appropriate channel without the user having to interact with MS Teams. Looking around I see a lot of posts saying this isn't possible yet, but Monday.com and Smartsheet seem to be doing this. Monday.com even specifies its using the beta api and neither are using connectors.
I attempted to do use the api POST /teams/{id}/channels/{id}/messages after authenticating via the way shown in this documentation
First Call for adminconsent
https://login.microsoftonline.com/organizations/v2.0/adminconsent?&client_id={botID}&response_type=code&redirect_uri=https://myoauthCallback&scope=offline_access User.ReadWrite.All Group.ReadWrite.All
After that returns I do an immediate call to get an access token, the above call doesn't seem to return anything I need to put into this request.
POST => /organizations/oauth2/v2.0/token
body = client_id={botId}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={secret}&grant_type=client_credentials
I set the permissions in https://portal.azure.com/#blade/ for the bot to have the same scope as the first request above. Here it doesn't like the scope passed in the same way so I set it to default
I then take the access_token that is returned and attempt the call to POST a message to the channel.
URL: /teams/{TEAM_ID}/channels/{CHANNEL_ID}/messages
body: {
subject: 'test subj',
body: { contentType: 'text', content: 'Test message from app' },
}
This results in an error
statusCode: 401, code: 'UnknownError', message: ''
So how do I get the same functionality of these other apps so I can send a message directly to teams without setting up a connector?

Turns out it was a Office 365 Connector vs the regular "connector" that requires configuration within teams.
https://www.youtube.com/watch?v=EqodWkS5PYM
Edit: Disregard, even with office 365 connectors it requires the user to still interact with MS Teams in some way.
Another Edit: Turns out it is using Proactive Messaging https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bot-conversations/bots-conv-proactive#net-example-from-this-sample
Although technically you cannot actually send a message to the app without a user interacting with the bot first, the installation of the app does trigger a conversationUpdate to which you can reply. So In the end, I can install the Teams app, and send a bot notification all within my web app, without the user having to actually touch Microsoft Teams.

If you look at the "auth" page you linked to, it's talking about creating Application permissions. However, see the "create chatMessage in a channel" graph documentation and under "permissions" near the top it shows that it supports "Delegated" permissions only, so you can't use that particular endpoint with Application permissions unfortunately.
Connectors (Webhooks) will be able to do what you need, but you say you want to avoid that - perhaps you can explain why it's not ideal? I'm not aware of how to create a webhook programmatically, I'm afraid.

Related

How I can get the Call Quality of all teams Calls&Meetings by Graph Api or similar?

I worked on a solution for getting all teams audio & video communication quality in the company.
https://learn.microsoft.com/de-de/learn/modules/msgraph-changenotifications-trackchanges/5-exercise-change-notifications
On Runtime-Ecxceptions I use the old version the videos are created. older sources
That should solved later but it should no reason for getting onl some notifications not all.
I tried to get the callrecords by change notification and it worked partly, but I get not all notifications, and the endpoint handler work more than a half day (12, 14 or 16 h i think).
If I understand it correct. All cloud communication audio-/Video Call was accessed with https://graph.microsoft.com/beta/communications/callRecords/
If the CallRecord is an meeting type the the joinWebURL is set and must be added to the filter-clause to get the corresponding meeting.
All online meetings are missing
some group calls direct routing calls
and PSTN-Calls I have not tested it.
My Created subscription:
{
"changeType": "created,updated",
"notificationUrl": "https://a283-178-27-237-107.ngrok.io/api/notifications",
"resource": "/communications/callRecords",
"expirationDateTime": "2021-08-29T11:00:00.0000000Z"
}
I took on every creation or renewing the subscription the max time 4230, but I tried it with short timespawn and periodically renewing the subscription.
My setting in the registered App
// add permissions to registered app
CallRecord-PstnCalls.Read.All
CallRecords.Read.All
Calls.AccessMedia.All
Directory.Read.All
OnlineMeetings.Read.All
OnlineMeetings.ReadWrite.All
Reports.Read.All
User.Read.All
(OnlineMeetings is only a short time added)
I set the application access policy for this app with powershell.
Then I tried to get the Callrecords through the Callrecords History of teams Admin Center.
But the Id's there worked party an with the user who created the Meeting or call.
I got the messages Forbidden, invalid token,... so it seems the app works on with delgate permission, but I set App permission.That could clarify why i cannot all CallRedcords.if Icreated a subscription for a app which has appermision, the webook should called on ever Call.
So have 2 big problem:
Why there are not all notifications send?
How can i get an valid access token which works with app permissions and not with delegate permissions?
Update:
Now it seems i get all notifications, point 1 & 2 or irrelvant?
not use postman accessing subscriptions, i get no valid token for postman what ever I tried (Oauth2 Authentification copying token from the notificationurl handler), it seems the effect of the applicatiobn access policy.
Has anybody a solution for that?
Update 15.09.2021:
CallRecords Records seems to work fine, there was an error on postman enviroment.
I ignored other manuals and followed the steps to use postman from microsoft for that (see https://learn.microsoft.com/de-de/graph/use-postman). Creating subscription with the application permission and it seems I get all notifications.
So getting all notification seems to work. So I will close it now.
CallRecords Records seems to work fine, there was an error on postman enviroment. I ignored other manuals and followed the steps to use postman from microsoft for that (see https://learn.microsoft.com/de-de/graph/use-postman). Creating subscription with the application permission and it seems I get all notifications.
So getting all notification seems to work.
So I could close it generally, beacuse concerning question in this context needs own questions.
A controll check if I get all notification is the onyl open point on this question.
So I wait a few days, if there is no answer I close this question.

Node and Microsoft Teams API

I'm building a Node only application that reads logs in the background and based on an event being read will send a message to a Teams channel directly.
I've been having quite a few issues getting a Graph API access token valid through Username and password.
I have been able to get a Graph API access token with client secret and tenant id which represents access
"without a user". Now that does not allow me to post a message in a channel as I would need to have access "on behalf of a user".
API => https://graph.microsoft.com/v1.0/teams/{team-id}/channels/{channel-id}/messages .
Would there be another way of achieving this? Webhook/Connectors?
Thank you!
There's a few different ways you can post to a teams channel, you can set up like you said an http webhook, where you could call it to post into a channel https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using
You can use power automate (flow) or logic apps to post messages as the flowbot, or you can write a bot/ use the bot framework to register a bot that can post to teams, called proactive messaging: https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bot-conversations/bots-conv-proactive
As for trying to use graph with application permissions, that's not possible, at least for the moment.

OAuth2 authentication for Microsoft Graph using service account credentials

I would like to create a webservice capable of automatically sending messages in Microsoft Teams. I tried authenticating as an application, but currently Microsoft does not support granting application permissions to send messages in Teams, so the only choice here is to authenticate using a service account with real credentials (Unless there is another way?). This method only specifies using user interaction to log in as a user.
I would like to use a service account teamchatbot#domain.com to authenticate with Microsoft Graph in order to send messages on Microsoft Teams. (similar to this but since I'm not accessing a resource it is a little different.) Is there a way I can silently obtain an access token on behalf of the service account in order to send messages?
It seems that you have a misunderstanding.
Your scene is actually the same as this post.
You should use Resource Owner Password Credentials to call Microsoft Graph API to send messages.
Based on permissions, you need the Group.ReadWrite.All delegated permission. So you need to add this permission into your Azure AD app firstly.
Don't forget to click on "Grant admin consent for {your tenant}" after you add this permission.
Then you can get an access token like this:
You can see that https://graph.microsoft.com/Group.ReadWrite.All has been included in the response.
Now you could use this access token to call POST /teams/{id}/channels/{id}/messages.
There are a few other ways I can think of.
1) One is that you can create a Bot using the Microsoft Bot Framework, and once that bot is installed to the particular team, it can send "pro-active" messages (i.e. not a message in response to a user's message, but rather whenever you need).
Essentially, when you bot is added to the team, you get access to a specific event in your bot (OnMembersAdded for a general bot, and there's now a new event just for Teams). See more on this in my answer on Detect bot application open event. In this event, you get the information you need for later, which you can store in a database or wherever, and then create the message as if it's your bot posting to the channel. You can see more on that at Programmatically sending a message to a bot in Microsoft Teams.
This option above is a lot of work, but useful if there's other functionality you want from a bot (e.g. the ability to receive messages from the users)
2) Another, and even more simple way, is to create an incoming webhook directly to the channel. Here's a post on doing this using PowerShell, so you can do that for simple testing and extrapolate from there for Node.
Of course, things like Flow (Power Automate) are an option too, but you're already writing code so one of the above is probably easier.
Hope that helps

Microsoft Teams - read out channel messages (ReactJS, NodeJS)

in Microsoft Teams we have a Team called "BD" and this team has a channel named "Global".
Now I have a ReactJS app with a NodeJS backend and I would like to
display all the messages that are written in the Global Channel of the Team "BD"
I only need to show which messages are written in the channel (so readonly would be sufficient).
What is the easiest way to achieve this ? Even an iFrame would be ok, if somehow possible.
Please take a look at List channel messages Graph API. First try these APIs in Graph Explorer.
To implement this in a code, you need to follow either Get access on behalf of a user or Get access without a user
Before calling this API with application permissions (access without a user), you must request access. For details, see Protected APIs in Microsoft Teams.

Instagram webhook not activating

My goal is to use the Facebook webhooks to get a notification whenever an IG user mentions my IG account. For that I have followed these steps:
I have created a Facebook page and connected it with an Instagram business account.
I have created a Facebook app (which is now live) and added the product "webhooks".
I have connected my app with my page.
I have created a webhook and subscribed to the mentions event.
I have tested the webhook, using the tools provided by Facebook and it works.
The problem I'm facing is that I can't get my app to work with real data. I have tried to mention my business IG account from my IG personal account, but nothing happens. My callback url is not getting called.
My app doesn't need users to login, so I'm not sure if I need to send my app for review. Do I need a special permission?
I had the same problem. For my case, when I installed the app via graph api explorer, the page token I was using didn't have the instagram_manage_insights permission. So I granted that permission, got a new token, re did the POST request to the {page-id}/subscribed_apps again with the new token and that fixed the problem. Just for the record, I used a system user token from the business manager.
Did you verified your Facebook app via app review? If not, you won't get production data via a webhook callback for the Instagram. I had the same issue and asked the Facebook support and got following response:
However, this is not the same for instagram or pages. This is just how the product teams have decided to implement it. For app review, you can show a mock process of the flow, using either the test webhook or your own process. The app review is less about technical implementation steps, but just a way to make sure that your app is going to use the permission in a way that follows our guidelines, so mocking the procedure should be fine. The reviewers understand that you do not receive webhooks in dev mode and should take this into consideration.
For more information check out following links:
Why is the Instagram Graph API webhook not working
https://developers.facebook.com/support/bugs/495933900986533/
I just figure it out of this problem.
There is a mistake in the official Instagram webhook guide:
With Graph API version 3.2, the /{page-id}/subscribed_apps edge now requires the subscribed_fields parameter, which currently does not support Instagram webhooks fields. To get around this, use your app's dashboard to subscribe.
https://developers.facebook.com/docs/instagram-api/guides/webhooks/#install-app
However, the app's dashboard subscribe is another function. You need your page to subscribe to some field to receive webhooks
Just POST /{your-instagram-connected-page-id}/subscribed_apps?subscribed_fields=feed&access_token={your-instagram-connected-page-token}
Then you will receive webhooks in live mode.

Resources