msgraph-sdk-go icon indicating copy to clipboard operation
msgraph-sdk-go copied to clipboard

Unable to get ID of a newly created Teams team

Open HorizonNet opened this issue 1 year ago • 12 comments

I'm following the documentation to create a team in Teams by using the following code:

newTeam := graphmodels.NewTeam()
displayName := "Test team"
newTeam.SetDisplayName(&displayName)
newTeam.SetAdditionalData(map[string]interface{}{
    "[email protected]": "https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
})

// Set the owner of the team
conversationMember := graphmodels.NewAadUserConversationMember()
roles := []string{"owner"}
conversationMember.SetRoles(roles)
conversationMember.SetAdditionalData(map[string]interface{}{
    "[email protected]": "https://graph.microsoft.com/v1.0/users('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')",
})
membersToAdd := []graphmodels.ConversationMemberable{
    conversationMember,
}
newTeam.SetMembers(membersToAdd)

teams, err := client.Teams().Post(context.Background(), newTeam, nil)

if err != nil {
fmt.Println(err)
}

fmt.Println(teams.GetId())

In the TAC I can see that the team was created successfully, but when trying to get the ID of the newly created team at the end (for further processing) I receive an invalid memory address or nil pointer dereference.

Based on the documentation I would assume that's due to the expected HTTP 202 received from the POST and that the creation of the team takes a little bit in the background. Am I missing something? I wasn't able to find something related in the documentation pointing me to a solution.

HorizonNet avatar May 25 '24 22:05 HorizonNet

Hi @HorizonNet , as you correctly mentioned, this is a long running api that does not respond immediately with the team id. We do have an issue tracking design and development to support such API's. In the meantime from the example in docs, you there is aLocation value in the header that can be retrieved using the nethttplibrary.NewHeadersInspectionOptions()

rkodev avatar May 27 '24 10:05 rkodev

@rkodev Thanks for the hint. Can you please share the example in docs link again? This seems to be typical ATP Safelink.

HorizonNet avatar May 27 '24 11:05 HorizonNet

@HorizonNet I've updated the correct link. Here is sample code to get the Location from the header after adding header introspection


	// introspect headers
	headerOptions := nethttplibrary.NewHeadersInspectionOptions()
	headerOptions.InspectResponseHeaders = true
	
	requestConfig := &teams.TeamsRequestBuilderPostRequestConfiguration{
		Options: []abstractions.RequestOption{
			headerOptions,
		},
	}

	teams, err := client.Teams().Post(context.Background(), newTeam, requestConfig)
	
	// get the location from header value
	locations := headerOptions.GetResponseHeaders().Get("Location")

rkodev avatar May 27 '24 12:05 rkodev

@rkodev Thanks a lot! I'm going to give it a try soon. Am I getting it right that the Location and Content-Location contains the ID, which will be assigned for the team? If that's the case I could use a simple polling on client.Teams(). ByTeamId("xxx").

HorizonNet avatar May 27 '24 12:05 HorizonNet

@HorizonNet Welcome. That should be the case. Once you try the solution you can update the issue.

rkodev avatar May 27 '24 12:05 rkodev

@rkodev I gave it a try and the response headers are empty. I'm using the following snippet after the one from my initial post.

headerOptions := nethttplibrary.NewHeadersInspectionOptions()
headerOptions.InspectResponseHeaders = true

requestConfig := &teams.TeamsRequestBuilderPostRequestConfiguration{
    Options: []abstractions.RequestOption{
	headerOptions,
    },
}

_, err = client.Teams().Post(context.Background(), newTeam, requestConfig)

if err != nil {
   fmt.Println(err)
}

locations := headerOptions.GetResponseHeaders().Get("Location")

I'm working against a M365 Developer tenant. Based on other working things I would assume that there should not be a difference to a regular tenant. Is there anything missing?

HorizonNet avatar May 27 '24 20:05 HorizonNet

@HorizonNet Can you check the value of Content-Location i.e locations := headerOptions.GetResponseHeaders().Get("Content-Location")

rkodev avatar Jun 03 '24 10:06 rkodev

@rkodev I also tried this one and it's empty as well.

HorizonNet avatar Jun 03 '24 11:06 HorizonNet

@HorizonNet could you kindly share the response headers you get when using graph explorer

rkodev avatar Jun 03 '24 12:06 rkodev

@rkodev When using Graph Explorer on the same tenant the location header is returned, where I can see the ID assigned to the team. Let me share the whole snippet to check if I'm missing something between the lines.

newTeam := graphmodels.NewTeam()
displayName := "Test team"
newTeam.SetDisplayName(&displayName)
newTeam.SetAdditionalData(map[string]interface{}{
    "[email protected]": "https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
})

// Set the owner of the team
conversationMember := graphmodels.NewAadUserConversationMember()
roles := []string{"owner"}
conversationMember.SetRoles(roles)
conversationMember.SetAdditionalData(map[string]interface{}{
    "[email protected]": "https://graph.microsoft.com/v1.0/users('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')",
})
membersToAdd := []graphmodels.ConversationMemberable{
    conversationMember,
}
newTeam.SetMembers(membersToAdd)

headerOptions := nethttplibrary.NewHeadersInspectionOptions()
headerOptions.InspectResponseHeaders = true

requestConfig := &teams.TeamsRequestBuilderPostRequestConfiguration{
    Options: []abstractions.RequestOption{
        headerOptions,
    },
}

_, err = client.Teams().Post(context.Background(), newTeam, requestConfig)

if err != nil {
    fmt.Println(err)
}

locations := headerOptions.GetResponseHeaders().Get("location")

HorizonNet avatar Jun 03 '24 19:06 HorizonNet

Hi @HorizonNet, looking at your code again, this should be working. Could you attempt to print all the headers using this snippet

	for _, key := range headerOptions.GetResponseHeaders().ListKeys() {
		fmt.Println(key, headerOptions.GetResponseHeaders().Get(key))	
	}

rkodev avatar Jun 12 '24 11:06 rkodev

@rkodev There are no headers, resulting into []. I tested it also against an actual tenant to rule out that it's something related to the developer tenant, but the result remains the same.

HorizonNet avatar Jun 13 '24 21:06 HorizonNet