Using Graph API to create Teams 1:1 chat and send message via app (not user)
I am looking to create a notification application which the company will use for e.g. reminders or incidents. The goal is to send the messages to 1:1 chat in Teams and I have already:
- Registered the app in MS Entra
- Gotten the following Graph API permissions:
|Chat.Create|Application|Create chats|Yes||| |Chat.ReadWrite.All|Application|Read and write all chat messages|Yes||| |ChatMessage.Send|Delegated|Send user chat messages|No||| |User.Read|Delegated|Sign in and read user profile|No||| |User.ReadBasic.All|Application|Read all users' basic profiles|Yes||
I have put together some Java code but to be able to create a chat (which is implied possible by the Chat.create permission for an Application ) I am having problem with what ID I can use for the application? It seems like it is limited to user:user but not user:application, but according to https://learn.microsoft.com/en-us/answers/questions/1400755/send-direct-message-to-a-user-via-ms-teams-program Application should be able to send to user in Teams.
public String createChat(String usersId) throws Exception {
String accessToken = getAccessToken();
HttpClient client = HttpClient.newHttpClient();
String payload = GraphApiHelper.createChatPayload(usersId);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://graph.microsoft.com/v1.0/chats"))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + accessToken)
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Chat create Response body: " + response.body());
return extractChatIdFromResponse(response.body());
}
public static String createChatPayload(String userId) {
String appId = "PLACEHOLDER_FOR_QUESTION";
Map<String, Object> member1 = Map.of(
"@odata.type", "#microsoft.graph.aadUserConversationMember",
"roles", List.of("owner"),
"user@odata.bind", "https://graph.microsoft.com/v1.0/users('" + userId + "')"
);
Map<String, Object> member2 = Map.of(
"@odata.type", "#microsoft.graph.aadUserConversationMember",
"roles", List.of("owner"),
"user@odata.bind", "https://graph.microsoft.com/v1.0/users('" + appId + "')"
);
Map<String, Object> chat = Map.of(
"chatType", "oneOnOne",
"members", List.of(member1, member2)
);
return createJsonPayload(chat);
}
Chat create Response body: {"error":{"code":"Forbidden","message":"AclCheckFailed","innerError":{"code":"40400","message":"RosterCreationNotAllowed-Create Thread: One or more members cannot be added to the unique roster thread","date":"2024-03-27T09:04:40","request-id":"XXXXXXXXX","client-request-id":"XXXXXXXXXXXXX"}}}
The above works fine if I replace the appID with user id of another user in Teams.