Using Graph API to create Teams 1:1 chat and send message via app (not user)

Haraldur Blöndal Kristjansson 0 Reputation points
2024-03-28T09:14:31.58+00:00

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.

Microsoft Teams
Microsoft Teams
A Microsoft customizable chat-based workspace.
9,034 questions
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,530 questions
{count} votes