Tomasz Przetacki
Tomasz Przetacki

Reputation: 63

Create MS Teams team in C# - AddAsync returns null

Context:

I am creating new MS Teams team using MS Graph API in C#

My code:

var newTeam = new Team()
{
    DisplayName = model.DisplayName,
    Description = model.Description,
    AdditionalData = new Dictionary<string, object>
    {
        ["[email protected]"] = $"{graph.BaseUrl}/teamsTemplates('standard')",
        ["members"] = owners.ToArray()
    }
};

var team = await graph.Teams.Request().AddAsync(newTeam);

Problem:

The team is created fine but I can't get it's id. Return type of AddAsync method is Task<Team> but it always returns null. I have checked server response using Fiddler and found out that the id of created team is returned in response headers.

Content-Location: /teams('cbf27e30-658b-4021-a8c6-4002b9adaf41')

Unfortunately I don't know how to access this information.

Upvotes: 2

Views: 1171

Answers (3)

Sara-bocchan
Sara-bocchan

Reputation: 1

In case anyone else is struggeling to get this done in Graph SDK version 5.x, this is what worked for us:

var nativeResponseHandler = new NativeResponseHandler();
var createTeamRequestInformation = applicationClient.Teams.ToPostRequestInformation(team);
createTeamRequestInformation.SetResponseHandler(nativeResponseHandler);

await applicationClient.RequestAdapter.SendAsync(createTeamRequestInformation, TeamCreatedEventMessageDetail.CreateFromDiscriminatorValue);
using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage;
var location = responseMessage.Headers.Location.ToString();

var locationParts = location.Split(new[] { '\'', '/', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
var teamId = locationParts[1];
var operationId = locationParts[3];

inspired by this answer to another question: https://stackoverflow.com/a/75721864

Upvotes: 0

Stefan Born
Stefan Born

Reputation: 750

Luckily this is quite easy to achieve by using the requests base class BaseRequest and sending it yourself. With the received HttpResponseMessage you get the headers as documented here which contains the id of your new team.

The code also includes how to wait for the team creation to finish using a busy wait – which is not considered as best practice, but makes the sample easier. A better approach would be to store the team id and periodically query the creation status.

var newTeam = new Team()
{
    DisplayName = model.DisplayName,
    Description = model.Description,
    AdditionalData = new Dictionary<string, object>
    {
        ["[email protected]"] = $"{graph.BaseUrl}/teamsTemplates('standard')",
        ["members"] = owners.ToArray()
    }
};

// we cannot use 'await client.Teams.Request().AddAsync(newTeam)'
// as we do NOT get the team ID back (object is always null) :(
BaseRequest request = (BaseRequest)graph.Teams.Request();
request.ContentType = "application/json";
request.Method = "POST";

string location;
using (HttpResponseMessage response = await request.SendRequestAsync(newTeam, CancellationToken.None))
    location = response.Headers.Location.ToString();

// looks like: /teams('7070b1fd-1f14-4a06-8617-254724d63cde')/operations('c7c34e52-7ebf-4038-b306-f5af2d9891ac')
// but is documented as: /teams/7070b1fd-1f14-4a06-8617-254724d63cde/operations/c7c34e52-7ebf-4038-b306-f5af2d9891ac
// -> this split supports both of them
string[] locationParts = location.Split(new[] { '\'', '/', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
string teamId = locationParts[1];
string operationId = locationParts[3];

// before querying the first time we must wait some secs, else we get a 404
int delayInMilliseconds = 5_000;
while (true)
{
    await Task.Delay(delayInMilliseconds);

    // lets see how far the teams creation process is
    TeamsAsyncOperation operation = await graph.Teams[teamId].Operations[operationId].Request().GetAsync();
    if (operation.Status == TeamsAsyncOperationStatus.Succeeded)
        break;

    if (operation.Status == TeamsAsyncOperationStatus.Failed)
        throw new Exception($"Failed to create team '{newTeam.DisplayName}': {operation.Error.Message} ({operation.Error.Code})");

    // according to the docs, we should wait > 30 secs between calls
    // https://learn.microsoft.com/en-us/graph/api/resources/teamsasyncoperation?view=graph-rest-1.0
    delayInMilliseconds = 30_000;
}

// finally, do something with your team...

Upvotes: 3

VaraPrasad-MSFT
VaraPrasad-MSFT

Reputation: 93

You will get your teamId by calling the GET joined Teams, it will get the team id ,name and description

Upvotes: 2

Related Questions