Search code examples
c#restazure-active-directorymicrosoft-graph-apimicrosoft-teams

Graph API: sending message to a channel fails as Forbidden (Thread is not marked for import)


I need to use the Graph API to send a chat message to a MS Teams channel, documented here.

I retrieve a token from an App Registration that owns the required permissions:

  • ChannelMessage.Send (Delegated)
  • ChannelMessage.Send (Application)

Permissions have Admin Consent.

This the code C# that gets the token:

var scopes = new[] {
    "https://graph.microsoft.com/.default",
};
var tenantId = "602*********************************";
var clientId = "634*********************************";
var clientSecret = "DfV*************************************";
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);

var token = clientSecretCredential.GetToken(new TokenRequestContext(scopes)).Token;

I use Postman to better inspect the response. This is the URL of the POST request:

https://graph.microsoft.com/v1.0/teams/991*********************************/channels/19%3a9*********************************%40thread.tacv2/messages

The Authorization header is set with the token obtained by C# code and the payload is the following:

{
  "createdDateTime": "2022-03-07T17:47:11.7429830Z",
  "from": {
    "user": {
      "id": "2a7*********************************",
      "displayName": "User display name",
      "userIdentityType": "aadUser"
    }
  },
  "body": {
    "contentType": "html",
    "content": "Hello Teams!"
  }
}

This REST API call perfectly works with Graph Explorer when logged as a tenant user (using only the body property). With the App Registration token and additional properties I get the following response with HTTP status code 403 Forbidden:

{
    "error": {
        "code": "Forbidden",
        "message": "{\"errorCode\":209,\"message\":\"{\\r\\n  \\\"subCode\\\": \\\"MessageWritesBlocked\\\",\\r\\n  \\\"details\\\": \\\"Thread is not marked for import\\\",\\r\\n  \\\"errorCode\\\": null,\\r\\n  \\\"errorSubCode\\\": null\\r\\n}\"}",
        "innerError": {
            "date": "2022-03-07T17:47:34",
            "request-id": "e0ab5c7b-b64b-4c44-81e3-cc91b344403c",
            "client-request-id": "e0ab5c7b-b64b-4c44-81e3-cc91b344403c"
        }
    }
}

I don't understand how to satisfy Thread is not marked for import.

I'll appreciate any help on how to succeed in this call. If not possible: any other way to send a message using the Graph API with App Registration token.


Solution

  • Application permissions are only supported for migration.

    Please follow below steps.

    1. Create new team in migration state.

    POST https://graph.microsoft.com/v1.0/teams
    
    Content-Type: application/json
    {
      "@microsoft.graph.teamCreationMode": "migration",
      "template@odata.bind": "https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
      "displayName": "My Sample Team",
      "description": "My Sample Team’s Description",
      "createdDateTime": "2020-03-14T11:22:17.043Z"
    }
    

    2. Create New Channel in migration state

    POST https://graph.microsoft.com/v1.0/teams/{team-id}/channels
    
    Content-Type: application/json
    {
      "@microsoft.graph.channelCreationMode": "migration",
      "displayName": "Architecture Discussion",
      "description": "This channel is where we debate all future architecture plans",
      "membershipType": "standard",
      "createdDateTime": "2020-03-14T11:22:17.047Z"
    }
    

    3. Execute graph query for import messages

    POST https://graph.microsoft.com/v1.0/teams/team-id/channels/channel-id/messages
    
    {
       "createdDateTime":"2019-02-04T19:58:15.511Z",
       "from":{
          "user":{
             "id":"id-value",
             "displayName":"Joh Doe",
             "userIdentityType":"aadUser"
          }
       },
       "body":{
          "contentType":"html",
          "content":"Hello World"
       }
    }
    

    Ref Doc: https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/import-messages/import-external-messages-to-teams