I am trying to create channels in Microsoft Teams using the Microsoft Graph Beta API. In the docs, it says that the channel entity has a property IsFavoriteByDefault that indicates
Whether the channel should automatically be marked 'favorite' for all
members of the team. Default: false.
https://learn.microsoft.com/en-us/graph/api/resources/channel?view=graph-rest-beta#properties
However, trying the Graph Beta API (either with custom call or the Graph Explorer) and whatever value I pass to this property true or false, this property remains null.
Is there anything special to do to actually set the value of this property ?
Has anyone found a resolution to this? I added the isFavoritebyDefault but I am seeing this only adds this for the owner or user who runs the flow not for all members of the team. Code is provided below for reference.
{
"requests": [
{
"url": "/teams/{varTeamID}/channels",
"method": "POST",
"id": 1,
"headers": {
"Content-Type": "application/json"
},
"body": {
"displayName": "{varChannelName}",
"description": "This channel is in existence for",
"isFavoriteByDefault": true
}
}
]
}
Now the doc shows as ,
Indicates whether the channel should automatically be marked
'favorite' for all members of the team. Can only be set
programmatically with Create team. Default: false.
That means setting IsFavoriteByDefault to true won't work on create channel api call.
But it will work as part of the create Team API where channel(s) can be added and set as IsFavoriteByDefault as true
Related
My application for Microsoft Teams works as a tab and needs to get the list of the chat members or channel members, depending on where it is installed.
/chats/{chat-id}/members
/teams/{team-id}/channels/{channel-id}/members
To use the APIs, I get the Context object from the client SDK library to get the identifiers required for the APIs. It works fine for chats–both group and one on one (using Context.chatId), and public team channels (using Context.groupId and Context.channelId).
However, nothing I try seems to work for private team channels.
The context object returned for private team channels contains teamId and channelId, but they are equal, and using one value for both ids naturally doesn't work. Here is an example of what is returned for a private team channel by the SDK library 1.11.0 (the latest):
{
"locale": "en-us",
"theme": "default",
"subEntityId": "",
"isFullScreen": false,
"sessionId": "5194fd2b-5c9a-16a7-7411-94ddabffffff",
"chatId": "",
"meetingId": "",
"parentMessageId": "",
"hostClientType": "desktop",
"tenantSKU": "unknown",
"jsonTabUrl": "microsoft-teams-json-tab.azurewebsites.net",
"userLicenseType": "Unknown",
"appSessionId": "7503c11c-d524-409c-b58b-004810ffffff",
"appLaunchId": "c736c663-cc0b-47c3-8824-ba56b7ffffff",
"isMultiWindow": false,
"appIconPosition": 79,
"userClickTime": 1637007245298,
"sourceOrigin": null,
"userFileOpenPreference": "inline",
"osLocaleInfo": {
"platform": "macos",
"regionalFormat": "en-gb",
"longDate": "d MMMM y",
"shortDate": "dd/MM/y",
"longTime": "HH:mm:ss z",
"shortTime": "HH:mm"
},
"frameContext": "settings",
"isTeamArchived": false,
"teamType": 0,
"userTeamRole": 0,
"channelRelativeUrl": "/sites/ffffff/Shared Documents/Devel",
"channelId": "19:0bc109b412d9448bb6b1b3d4d485700b#thread.tacv2",
"channelName": "Devel",
"channelType": "Private",
"defaultOneNoteSectionId": "",
"teamId": "19:0bc109b412d9448bb6b1b3d4d485700b#thread.tacv2",
"teamName": "Devel",
"teamSiteUrl": "https://ffffff.sharepoint.com/sites/worldrtech-Devel",
"teamSiteDomain": "ffffff.sharepoint.com",
"teamSitePath": "/sites/ffffff",
"teamTemplateId": "",
"teamSiteId": "",
"ringId": "general",
"tid": "d158bb9f-f90c-422d-9d0d-0040efffffff",
"loginHint": "ffffff#ffffff.uk",
"upn": "nox#worldr.co.uk",
"userPrincipalName": "ffffff#ffffff.uk",
"userObjectId": "fc5a4a6d-60e2-4370-83bd-aab1baffffff"
}
You can see above that the two are equal:
"channelId": "19:0bc109b412d9448bb6b1b3d4d485700b#thread.tacv2"
"teamId": "19:0bc109b412d9448bb6b1b3d4d485700b#thread.tacv2"
I wonder, whether this is an expected behaviour, or something is broken there... 🤔 As per comment by #Prasad-MSFT, this is normal behaviour for private channels.
There is an answer suggesting that one should first list all the teams the user joined. However, I don't see how I would connect this information to the context data shown above.
Is there a way to list the members of a private team channel? What am I missing?
UPDATE1 16.11:
I did an experiment, but the results got me puzzled. I followed the idea of getting all the teams of the user first. This got me ids of all the teams the user is a member of. I then requested members of for the current private channel for every team: I expected to get errors for all teams but one–that team the channel really belongs to. However, I got members for every request! That's very confusing.
/me/joinedTeams
/teams/{id}/channels/{channel_id}/members for each team received in 1. and channelId received from context.
Each call returned some members, which I did not expect...
UPDATE2 16.11:
This long-winded way gets me channel members in the end:
/me/joinedTeams
/teams/{id}/channels for each team received in 1.
Find the channel with id matching the channelId from my context among those received in 2.
/teams/{id}/channels/{channel_id}/members for the channel found in 3.
Looks like a lot of effort for such a simple thing. 🙄
Update: see the new answer from Nov 1 2022.
Update 2: it's still not fully functional, use both. 🤷♂️
This long-winded way gets me channel members list in the end. Only applies to private team channels because we don't have group id/team id in the Context there. As per #Prasad-MSFT's comment to the original post, there is no other way at the time of writing.
Get /me/joinedTeams
Get /teams/{id}/channels for each team received in #1.
Find the channel with id matching the channelId from the Context among those received in #2.
Get /teams/{id}/channels/{channel_id}/members for the channel found in #3.
Here is a caveat: if you create a private team channel and immediately add your tab to it, there is a chance that your new channel will not be returned by the API. If #3 in the above list of procedures fails, I ask the user to retry in a couple of minutes.
A year later there seem to be some improvements! (Yeah, but not really, see below.)
There is a new property called hostTeamGroupId which appears to contain the correct team id for private channels. The documentation, however, doesn't mention private channels specifically and only tells us about shared channels. Nevertheless, it seems to be working for the purposes of this question.
In #microsoft/teams-js v2 we can use Context.channel.ownerGroupId.
hostTeamGroupId
The property is newly added and describes the host
team’s Azure AD group ID, useful for making Microsoft Graph API calls
to retrieve shared channel membership.
However
This still doesn't work on mobile platforms at the time of writing 08.11.2022. The fields mentioned above are not populated.
So, for mobile platforms, we still need my other answer.
I have embedded a OneNote notebook into a Microsoft Teams Tab. I am trying to get the Notebook Id using Graphi API
I can get the tab id from channels/{{ChannelId}}/messages/delta end point.
Using tabId, I can get tab details from channels/{{ChannelId}}/tabs/{{tabid}} end point.
Tab details end point gives configuration details that has contentUrl and websiteURL.
{
"id": "tabId",
"displayName": "My Contoso Tab - updated",
"configuration": {
"entityId": "2DCA2E6C7A10415CAF6B8AB6661B3154",
"contentUrl": "",
"websiteUrl": "",
"removeUrl": ""
},
"teamsApp": {
"id": "0d820ecd-def2-4297-adad-78056cde7c78",
"externalId": null,
"displayName": "Contoso",
"distributionMethod": "store"
},
"sortOrderIndex": "20",
"webUrl": ""
}
How can I get notebook Id or Section Id or Page Id that is embedded into the tab?
Formally the OneNote tab explicitly has no public documentation regarding its configuration as per :
https://learn.microsoft.com/en-us/graph/teams-configuring-builtin-tabs#onenote-tabs.
You can indeed try to reverse engineer the content or web URLs, and you may very well succeed today.
But you need to understand , and accept responsibility and the associated integration testing potential downtime as that URL format can/will change with no notification whatsoever.
If you can accept that risk & responsibility, using the oneNoteWebUrl= QSP from the contentUrl json node seems to be a decent key.
"configuration": {
"entityId": "00727f3d-df18-43ac-8cc9-698774312f5e",
"contentUrl": "https://www.onenote.com/teams/TabContent?notebookSource=Pick¬ebookSelfUrl=https%3A%2F%2Fwww.onenote.com%2Fapi%2Fv1.0%2FmyOrganization%2Fgroups%0076777f1c-3e3d-44ad-8206-53ba08a44cec%2Fnotes%2Fnotebooks%007-ce5c7935-0960-41f0-a5ce-e82a6d365f45&oneNoteWebUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP%2FSiteAssets%2FTaaP%2520Notebook¬ebookName=TaaP%20Notebook&siteUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP&createdTeamType=Standard&oneNoteClientUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP%2FSiteAssets%2FTaaP%2520Notebook¬ebookIsDefault=true&ui={locale}&tenantId={tid}&upn={userPrincipalName}&groupId={groupId}&theme={theme}&entityId={entityId}&subEntityId={subEntityId}&sessionId={sessionId}&ringId={ringId}&teamSiteUrl={teamSiteUrl}&channelType={channelType}&trackingId={appSessionId}&hostClientType={hostClientType}",
"removeUrl": "https://www.onenote.com/teams/TabRemove?notebookSource=Pick¬ebookSelfUrl=https%3A%2F%2Fwww.onenote.com%2Fapi%2Fv1.0%2FmyOrganization%2Fgroups%2F46777f1c-3e3d-44ad-8206-53ba08a44cec%2Fnotes%2Fnotebooks%2F1-ce5c7935-0960-41f0-a5ce-e82a6d365f45&oneNoteWebUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP%2FSiteAssets%2FTaaP%2520Notebook¬ebookName=TaaP%20Notebook&siteUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP&createdTeamType=Standard&oneNoteClientUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP%2FSiteAssets%2FTaaP%2520Notebook¬ebookIsDefault=true&ui={locale}&tenantId={tid}&upn={userPrincipalName}&groupId={groupId}&theme={theme}&entityId={entityId}&subEntityId={subEntityId}&sessionId={sessionId}&ringId={ringId}&teamSiteUrl={teamSiteUrl}&channelType={channelType}&trackingId={appSessionId}&hostClientType={hostClientType}",
"websiteUrl": "https://www.onenote.com/teams/TabRedirect?redirectUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP%2FSiteAssets%2FTaaP%2520Notebook",
--> `oneNoteWebUrl=https%3A%2F%2Fm365x432007.sharepoint.com%2Fsites%2FTaaP%2FSiteAssets%2FTaaP%2520Notebook'
--> urldecode
https://m365x432007.sharepoint.com/sites/TaaP/SiteAssets/TaaP%20Notebook
The response of channels/{{ChannelId}}/tabs/{{tabid}} will contain details for tab and will not return details for the embedded onenote notebooks and pages. However you can get details for onenote notebooks and pages using https://graph.microsoft.com/v1.0/me/onenote/notebooks
You can refer below document for more information
https://learn.microsoft.com/en-us/graph/integrate-with-onenote
https://learn.microsoft.com/en-us/graph/api/resources/onenote-api-overview?view=graph-rest-1.0
Thanks
I am working with both EWS and the Graph API.
I would like to create events (online meetings with skype/teams) in an calendar that is already available via EWS.
To match the calendar to the one available via Graph API i try to use https://learn.microsoft.com/en-us/graph/api/user-translateexchangeids
The calendar i created has this id when returned by the FindFolder call:
<t:FolderId Id="AAMkAGNiY2YxMjY3LTUxYjgtNGI1Yy1hOTM2LTU4MTM5OTZiNjdjYgAuAAAAAABW2gY0kRG1SqggDTNZN6i8AQAPJkKZ1XJkQ6huFmcVa6XaAAGixNZ3AAA=" ChangeKey="..."/>
<t:DisplayName>Test</t:DisplayName>
I create a request to the graph api:
{
"inputIds": [
"AAMkAGNiY2YxMjY3LTUxYjgtNGI1Yy1hOTM2LTU4MTM5OTZiNjdjYgAuAAAAAABW2gY0kRG1SqggDTNZN6i8AQAPJkKZ1XJkQ6huFmcVa6XaAAGixNZ3AAA="
],
"sourceIdType": "ewsId",
"targetIdType": "restId"}
and get the result
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(microsoft.graph.convertIdResult)",
"value": [
{
"sourceId": "AAMkAGNiY2YxMjY3LTUxYjgtNGI1Yy1hOTM2LTU4MTM5OTZiNjdjYgAuAAAAAABW2gY0kRG1SqggDTNZN6i8AQAPJkKZ1XJkQ6huFmcVa6XaAAGixNZ3AAA=",
"targetId": "AAMkAGNiY2YxMjY3LTUxYjgtNGI1Yy1hOTM2LTU4MTM5OTZiNjdjYgAuAAAAAABW2gY0kRG1SqggDTNZN6i8AQAPJkKZ1XJkQ6huFmcVa6XaAAGixNZ3AAA="
}
]
}
However, if i call https://graph.microsoft.com/v1.0/me/calendars i get a different id
"id": "AAMkAGNiY2YxMjY3LTUxYjgtNGI1Yy1hOTM2LTU4MTM5OTZiNjdjYgBGAAAAAABW2gY0kRG1SqggDTNZN6i8BwBIq5JjIBY-RqWQllrF0GSkAAAAB353AAAPJkKZ1XJkQ6huFmcVa6XaAAGixNowAAA=",
"name": "Test",
Is there a way to match the (ews) calendar i already have to the one returned by the Graph API?
This is a shot in the dark, because I've never dug this deeply into the weeds on the Graph Ids, but you might try calling Graph with the header that selects "immutable ids." I tried to find some details on what this actually means without much luck.
The header is:
request.Header("Prefer", "IdType=\"ImmutableId\"");
HTH, and if not, sorry for guessing.
I'm implementing a search for a user's joined Teams unsing Microsoft Graph. The idea is to make a call to /beta/me/joinedTeams and use a ?$filter=startswith(description,'searchterm') filter.
So for example when I try the request https://graph.microsoft.com/beta/me/joinedTeams?$filter=startswith(description,'Business') in the Microsoft Graph Explorer it ignores the filter and I get these results:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#groups",
"value": [
{
"id": "02bd9fd6-8f93-4758-87c3-1fb73740a315",
"displayName": "HR Taskforce",
"description": "Welcome to the HR Taskforce team.",
"isArchived": false
},
{
"id": "13be6971-79db-4f33-9d41-b25589ca25af",
"displayName": "Business Development",
"description": "Welcome to the BizDev team.",
"isArchived": false
},
{
"id": "8090c93e-ba7c-433e-9f39-08c7ba07c0b3",
"displayName": "X1050 Launch Team",
"description": "Welcome to the team that we've assembled to launch our product.",
"isArchived": false
}
]
}
Am I doing something wrong with my request?
Your request is right, but the joinedTeams does not support filtering or ordering results. So although we pass the filter/orderby parameter, when Microsoft Graph sees a query parameter it doesn't expect, it simply ignores the unknown filter/orderby parameter and returns an unfiltered/default-sorted result.
I have tried the api with odata query parameters for trial O365 account and real account.
https://developer.microsoft.com/en-us/graph/docs/concepts/query_parameters
Not all parameters are supported across all Microsoft Graph APIs, and
support might differ significantly between the v1.0 and beta
endpoints.
The only suggestion for you is to vote up the existing feature request in User Voice or submit a new one.
Thanks for pointing this out. As Seiya points out, /me/joinedTeams does not support the OData query parameters. The documentation suggested otherwise, I've made a doc fix that should propagate in the next day or two.
I try to create a distribution list on Office365 with the Microsoft API Graph.
For that, I do a POST request on "https://graph.microsoft.com/beta/blih.bocal.org/groups" with json parameters :
{
"description": "My description",
"displayName": "testlist",
"groupTypes": ['Unified'],
"mailEnabled": True,
"mailNickname": "testlist",
"securityEnabled": False
}
It creates an office365 group or a security group with some little changes, but impossible to create a distribution list. Via the web, I can do it and when I get it with the API, the parameter "groupTypes" is empty.
What's bad on my request or how to do it (if it's possible) ?
http://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/group_post_groups
You can create Unified Group or Security Group or Dynamic Group alone with this API. Refer the documentation in the above URL.