Skip to content

Commit 6063b0b

Browse files
Merge pull request #311250 from NathanJBennett/patch-1
Enhance documentation for querying Resource Accounts
2 parents 428ca7c + f8f2c0c commit 6063b0b

1 file changed

Lines changed: 127 additions & 16 deletions

File tree

articles/communication-services/quickstarts/tpe/teams-phone-extensibility-quickstart.md

Lines changed: 127 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ This article describes how an independent software vendor (ISV) can provision Te
2323
- ISV’s Customer has access to Microsoft 365 Admin Center.
2424
- ISV has access to change Azure Communication Services Resource settings.
2525
- You grant Teams Tenant access to a CCaaS service for Graph API usage.
26-
- ISV is using the .NET, JavaScript or Java ACS Call Automation SDK version 1.5.0 or above (Python version will be released soon).
27-
- ISV is using the JavaScript ACS Client SDK version 1.37 and above.
26+
- ISV uses the .NET, JavaScript, or Java ACS Call Automation SDK version 1.5.0 or above (Python version will be released soon).
27+
- ISV uses the JavaScript ACS Client SDK version 1.37 and above.
2828

2929

3030
## Quick start
3131

32-
The rest of this article describes quick starts for two different personas: CCaaS Developer and Teams Tenant. The CCaaS developer is the ISV persona building the CCaaS service using Azure Communication Services. The Teams Tenant is the persona that is a customer of the ISV that is administering to Teams Phone.
32+
The rest of this article describes quick starts for two different personas: CCaaS Developer and Teams Tenant. The CCaaS developer is the ISV persona building the CCaaS service using Azure Communication Services. The Teams Tenant is the persona that's a customer of the ISV that's administering to Teams Phone.
3333

3434
### CCaaS Developer: Provision the AppID (Application ID)
3535

@@ -112,7 +112,7 @@ Connect-MicrosoftTeams
112112
Update-Module MicrosoftTeams
113113
```
114114

115-
Use the [New-CsOnlineApplicationInstance (MicrosoftTeamsPowerShell)](/powershell/module/teams/new-csonlineapplicationinstance) cmdlet to create a Resource Account. There's no change for Teams Phone extensibility in this command. The ApplicationId parameter is your third party bot ID. Don't use the Teams first person Application IDs defined in [Set-CsOnlineApplicationInstance (MicrosoftTeamsPowerShell)](/powershell/module/teams/set-csonlineapplicationinstance#-applicationid) because they don't work for Teams Phone extensibility. It's up to the CCaaS developer on how to communicate the Application ID to the Teams Tenant.
115+
Use the [New-CsOnlineApplicationInstance (MicrosoftTeamsPowerShell)](/powershell/module/teams/new-csonlineapplicationinstance) cmdlet to create a Resource Account. There's no change for Teams Phone extensibility in this command. The ApplicationId parameter is your third party bot ID. Don't use the Teams first person Application identifiers (IDs) defined in [Set-CsOnlineApplicationInstance (MicrosoftTeamsPowerShell)](/powershell/module/teams/set-csonlineapplicationinstance#-applicationid) because they don't work for Teams Phone extensibility. It's up to the CCaaS developer on how to communicate the Application ID to the Teams Tenant.
116116

117117
Example:
118118

@@ -192,14 +192,31 @@ Once you grant the Microsoft Entra application appropriate Graph permissions, th
192192
193193
The CCaaS Admin also needs elevated permissions to access Teams Resource Account information. The Graph API is getting Teams Resource Account information and that information is an asset owned by Teams Admin, so it requires privileged access as a Teams Admin. For more information, see [Permissions for Managing Resource Accounts](/microsoftteams/manage-resource-accounts#assign-permissions-for-managing-a-resource-account).
194194
195-
Query definition:
195+
196+
### Querying Teams Resource Accounts with Filtering and Paging
197+
198+
The Teams Resource Accounts API supports **OData filtering**, **server‑side paging**, and **cursor-based continuation** via the `@odata.nextLink` field.
199+
This capability enables CCaaS developers to efficiently retrieve Resource Accounts associated with their Azure Communication Services (ACS) resources.
200+
201+
#### Query definition
202+
196203
197204
> https://graph.microsoft.com/beta/admin/teams/resourceAccounts
198205
199-
Example request URI (RURI) to get Resource Accounts with a filter on appId:
206+
You can extend the base query with OData options such as:
207+
208+
- `$filter`—filter Resource Accounts by fields such as `appId` or `acsResourceId`
209+
- `$top`—limit the number of results returned per page
210+
- `@odata.nextLink`—Graph-provided URL for retrieving subsequent pages
211+
212+
---
213+
214+
### Filter by ACS Resource ID
215+
216+
The following example returns only Resource Accounts that are associated with a specific ACS Resource ID:
200217
201218
```rest
202-
GET https://graph.microsoft.com/beta/admin/teams/resourceAccounts?$filter=appid eq 'aa123456-1234-1234-1234-aaa123456789'
219+
GET https://graph.microsoft.com/beta/admin/teams/resourceAccounts?$filter=acsResourceId eq 'aa123456-1234-1234-1234-aaa123456789'
203220
```
204221

205222
Successful response:
@@ -208,15 +225,109 @@ Successful response:
208225
{
209226
"@odata.context": "https://graph.microsoft.com/beta/$metadata#admin/teams/resourceAccounts",
210227
"value": [
211-
{
212-
"id": "cc123456-5678-5678-1234-ccc123456789",
228+
{
229+
"id": "aa123456-1234-1234-1234-aaa123456789",
213230
"userPrincipalName": "[email protected]",
214-
"appId": "aa123456-1234-1234-1234-aaa123456789",
215231
"displayName": "My RA Name",
232+
"appId": "aa123456-1234-1234-1234-aaa123456789",
216233
"phoneNumber": "tel:+1234567890",
217-
"acsResourceId": "bb567890-1234-1234-1234-bbb123456789"
218-
}]
219-
}
234+
"acsResourceId": "aa123456-1234-1234-1234-aaa123456789"
235+
}
236+
]
237+
}
238+
```
239+
240+
### Paging with $top
241+
242+
You can use $top to specify the maximum number of results per page:
243+
244+
```rest
245+
GET https://graph.microsoft.com/beta/admin/teams/resourceAccounts?$top=5
246+
```
247+
248+
If more than five Resource Accounts exist, Microsoft Graph returns an @odata.nextLink value for the next page:
249+
250+
```rest
251+
252+
{
253+
"value": [
254+
{
255+
"id": "...",
256+
"displayName": "...",
257+
"acsResourceId": "..."
258+
}
259+
],
260+
"@odata.nextLink":
261+
"https://graph.microsoft.com/beta/admin/teams/resourceAccounts?$top=5&$skiptoken=abc123..."
262+
}
263+
```
264+
To continue paging, call the URL in the @odata.nextLink field until it's no longer present.
265+
266+
### Combined paging and filtering
267+
268+
Developers can combine $top and $filter to retrieve a filtered, paginated list:
269+
270+
```rest
271+
GET https://graph.microsoft.com/beta/admin/teams/resourceAccounts?$top=5&$filter=acsResourceId eq 'aa123456-1234-1234-1234-aaa123456789'
272+
```
273+
This query returns up to five Resource Accounts that match the specified ACS Resource ID.
274+
275+
### C# Example—Filtering + Paging
276+
The following C# sample demonstrates how to:
277+
278+
1. Query Teams Resource Accounts
279+
2. Filter by acsResourceId
280+
3. Limit results to 5 per page
281+
4. Follow @odata.nextLink for full pagination
282+
283+
```csharp
284+
using System;
285+
using System.Collections.Generic;
286+
using System.Net.Http;
287+
using System.Net.Http.Headers;
288+
using System.Threading.Tasks;
289+
using Newtonsoft.Json.Linq;
290+
291+
public static async Task<List<JObject>> GetResourceAccountsAsync(
292+
string acsResourceId,
293+
string accessToken)
294+
{
295+
var results = new List<JObject>();
296+
297+
string requestUrl =
298+
$"https://graph.microsoft.com/beta/admin/teams/resourceAccounts" +
299+
$"?$top=5&$filter=acsResourceId eq '{acsResourceId}'";
300+
301+
string nextUrl = requestUrl;
302+
303+
while (!string.IsNullOrEmpty(nextUrl))
304+
{
305+
var request = new HttpRequestMessage(HttpMethod.Get, nextUrl);
306+
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
307+
308+
using (var client = new HttpClient())
309+
{
310+
var response = await client.SendAsync(request);
311+
response.EnsureSuccessStatusCode();
312+
313+
var json = await response.Content.ReadAsStringAsync();
314+
var page = JObject.Parse(json);
315+
316+
if (page["value"] is JArray items)
317+
{
318+
foreach (var item in items)
319+
{
320+
results.Add((JObject)item);
321+
}
322+
}
323+
324+
// Continue to the next page if returned
325+
nextUrl = (string)page["@odata.nextLink"];
326+
}
327+
}
328+
329+
return results;
330+
}
220331
```
221332

222333
### CCaaS Developer: Receive and answer incoming call
@@ -237,12 +348,12 @@ The following steps demonstrate how to receive and answer an incoming Teams call
237348
1. Complete client and server consent as defined in [Access a user's Teams Phone separate from their Teams client](https://github.com/Azure/communication-preview/blob/master/Teams%20Phone%20Extensibility/teams-phone-extensibility-access-teams-phone.md).
238349

239350
> [!NOTE]
240-
> For the Azure Communication Services resource, ensure the data location matches the Teams Tenant location to comply with data boundary regulations. You can retrieve programmatically details about tenant organisation via [Get organization](/graph/api/organization-get)
351+
> For the Azure Communication Services resource, ensure the data location matches the Teams Tenant location to comply with data boundary regulations. You can retrieve programmatically details about tenant organization via [Get organization](/graph/api/organization-get)
241352
>
242353
243354
#### Setup and host your Azure dev tunnels
244355

245-
Azure dev tunnels enable you to share local web services hosted on the internet. Run the commands to connect your local development environment to the public internet. Dev tunnels creates a persistent endpoint URL and which enables anonymous access. We use this endpoint to notify your application about calling events from the Azure Communication Services Call Automation service.
356+
Azure dev tunnels enable you to share local web services hosted on the internet. Run the commands to connect your local development environment to the public internet. Dev tunnels create a persistent endpoint URL that enables anonymous access. We use this endpoint to notify your application about calling events from the Azure Communication Services Call Automation service.
246357

247358
```dotnetcli
248359
devtunnel create --allow-anonymous
@@ -401,7 +512,7 @@ this._teamsCallAgent = await this._callClient.createTeamsCallAgent(this.tokenCre
401512

402513
### CCaaS Client Developer: How to place an outbound OBO call
403514

404-
Developers need to get the on behalf of (OBO) identity (ID) Resource Account that the call needs to be placed on behalf of. The following articles describe how to place an outbound OBO call.
515+
Developers need to get the on-behalf-of (OBO) Resource Account identity that the call needs to be placed on behalf of. The following articles describe how to place an outbound OBO call.
405516

406517
Once the OBO identity is acquired, you need to set the `onBehalfOfOptions` in the `StartTeamsGroupCallOptions()` or `StartTeamsCallOptions()` method. For more information, see [StartTeamsGroupCallOptions interface](/javascript/api/azure-communication-services/@azure/communication-calling/startteamsgroupcalloptions) or [StartTeamsCallOptions interface](/javascript/api/azure-communication-services/@azure/communication-calling/startteamscalloptions).
407518

0 commit comments

Comments
 (0)