Genericness
Genericness

Reputation: 31

Create MS Teams chats with MS Graph (or PowerShell)

I'm currently trying to use Microsoft Graph to send a Microsoft Teams Chat message to a specific employee.

The idea behind that is that I want to be able to send chat messages using PowerShell, but for now, I'd be happy to get it done in Microsoft Graph first and build a PowerShell script afterward.

Important: I don't want to post a message to a Channel, only in a 1:1 chat.

What I've tried:

I'm able to get the current chats for my own user by using:

https://graph.microsoft.com/beta/users/{myid}/chats

If, however, I try that with a different user's id, I get a 401 (permission denied) error. I can't even see their current chats even though I have all available permissions.

In the error message, it says the following:

"User Id must match the API caller when called in delegated mode"

... but I don't want to use delegated mode since that'd mean I'm executing the commands as if I would be that user, and therefore couldn't create the chat message which I want in the first place.

It might sound rather confusing, so I hope you get what I mean.

Upvotes: 3

Views: 5679

Answers (2)

Marc LaFleur
Marc LaFleur

Reputation: 33094

The term "Delegated" in this context refers to the type of permissions claims included in the OAuth token. There are two types; Application and Delegated.

There are two key rules when it comes to Application vs. Delegated scopes:

  1. A single token may only contain a single type of scope. In other words, the token itself is either an Application or Delegated token, never a combination of the two.

  2. The type of scopes applied to a Token is determined by the OAuth Grant you used to obtain it:

    • Authorization Code: Delegated
    • Implicit: Delegated
    • Client Credentials: Application

With regard to the List Chats (/chats) endpoint, only Delegated permissions are supported:

  • Delegated (work or school account): Chat.Read, Chat.ReadWrite
  • Delegated (personal Microsoft account): Not supported.
  • Application: Not supported.

There is a general rule of thumb when it comes to permissions in Microsoft Graph (I use 'general' here since there are a couple of exceptions in older endpoints): Delegated scopes that only apply to the current user end in Read or ReadWrite while those that apply to any user end in .All.

Since these two scopes (Chat.Read and Chat.ReadWrite) do not end in .All, and only Delegated scopes are supported, this tells you that the only Chats you are able to access are those owned by the currently authenticated User. In other words, you cannot read another User's chat messages via the API.

If you think about it, this makes a lot of sense. If you didn't have an authenticated User, who would the Chat message you sent be "from"? A chat message requires both a Sender and a Recipient.


For your scenario, there are a couple of possible workarounds from a Teams ChatBot to simply setting up a new User that you authenticate as and send messages to other Users from.

Upvotes: 0

Hilton Giesenow
Hilton Giesenow

Reputation: 10804

To my knowledge, there's no way to send a message directly to the user without some kind of context. The problem becomes, for instance, where would the message appear, and who would it be from?

If you could deal with it being inside a Channel instead, then PowerShell is fine as you can set up a webhook to do this. I've done the same, from PS -> Teams a few years ago, so I assume it should still work. This article should help.

Alternatively, if you really want a "1-1" conversation, so to speak, you need to create and register a Bot, so that the message comes "from someone" to the user. This concept is called Pro-active Messaging and I've posted more about it here. However, coming purely from PowerShell it's going to be a LOT of work:

  1. Create a Bot in Azure to get the App ID and Password. Technically this would be a non-existent Bot as there's no implementation, which means if the user were to reply it would go nowhere. This might be ok? You could possibly try build an Azure Function Bot in PowerShell, but not something I've done myself so can't advise (I've only used C# for Bots thus far)
  2. Create a Conversation ID, and save it for later - again, a bunch of work.
  3. Convert the code (e.g. from my post above) into PowerShell, referencing the relevant NuGet packages.

So, I'd recommend trying to find an approach using a Teams Channel rather, and messaging the user there, if you can manage that in your use case?

Unless all of this is irrelevant if you're trying to send on behalf of another user?

Upvotes: 2

Related Questions