Advance your Data & AI career with 50 days of live learning, dataviz contests, hands-on challenges, study groups & certifications and more!
Get registeredJoin us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM. Register now.
Hi. I am currently trying to extract Teams call information using Graph API. I've managed to get information about the call organizer as well as duration of teh call etc. Afterwards, for each call ID, i can get the participant information. What i need to do now is for each of the Call ID's, i need to extract participants information. I've tried doing in Azure Data Factory. I am not sure how i can iterate through each call and extract the participant information. All of this should then be stored in a dataset.
Solved! Go to Solution.
If you create a new ADF dataset and call the dataset Graph_Teams_ListParticipant, you can past the code below to get an idea of how to configure the dataset.
Dataset code:
{"name": "Graph_Teams_ListParticipant", "properties": {"annotations": [], "linkedServiceName": {"referenceName": "GraphAPI", "type": "LinkedServiceReference"}, "parameters": {"call_id": {"type": "string"}}, "schema": {}, "type": "Json", "typeProperties": {"location": {"relativeUrl": {"type": "Expression", "value": "\"/communications/calls/@{dataset().call_id}/participants\""}, "type": "HttpServerLocation"}}}}
If you create a new ADF pipeline and call it pipeline1, you can past the code below to get an idea of how to configure the pipeline to loop through each call and get the participants. With the Copy data action correctly configured to retreive the API participants data, it should be able to sink it into a table and let the action create a destination table.
Pipeline code:
{"name": "pipeline1", "properties": {"activities": [{"dependsOn": [], "name": "Set call ouput variable", "policy": {"secureInput": false, "secureOutput": false}, "type": "SetVariable", "typeProperties": {"value": {"type": "Expression", "value": "@json(variables('call_example')).value"}, "variableName": "calls"}, "userProperties": []}, {"dependsOn": [{"activity": "Set call ouput variable", "dependencyConditions": ["Succeeded"]}], "name": "ForEach call ID", "type": "ForEach", "typeProperties": {"activities": [{"dependsOn": [{"activity": "Set call_id variable", "dependencyConditions": ["Succeeded"]}], "inputs": [{"parameters": {"call_id": {"type": "Expression", "value": "@variables('call_id')"}}, "referenceName": "Graph_Teams_ListParticipant", "type": "DatasetReference"}], "name": "Copy data1", "onInactiveMarkAs": "Succeeded", "policy": {"retry": 0, "retryIntervalInSeconds": 30, "secureInput": false, "secureOutput": false, "timeout": "0.12:00:00"}, "state": "Inactive", "type": "Copy", "typeProperties": {"enableStaging": false, "source": {"formatSettings": {"type": "JsonReadSettings"}, "storeSettings": {"requestMethod": "GET", "type": "HttpReadSettings"}, "type": "JsonSource"}}, "userProperties": []}, {"dependsOn": [], "name": "Set call_id variable", "policy": {"secureInput": false, "secureOutput": false}, "type": "SetVariable", "typeProperties": {"value": {"type": "Expression", "value": "@item().id"}, "variableName": "call_id"}, "userProperties": []}], "items": {"type": "Expression", "value": "@variables('calls')"}}, "userProperties": []}], "annotations": [], "variables": {"call_example": {"defaultValue": "{\"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#communications/callRecords\", \"value\": [{\"endDateTime\": \"2023-09-25T09:28:41Z\", \"id\": \"3cf3bbc8-b21d-4f2e-bfd0-b13603ae6c65\", \"lastModifiedDateTime\": \"2023-09-25T10:36:40Z\", \"modalities\": [\"audio\"], \"organizer\": {\"user\": {\"displayName\": \"Abbie Wilkins\", \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\"}}, \"organizer_v2\": {\"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"identity\": {\"user\": {\"displayName\": \"Abbie Wilkins\", \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\"}}}, \"organizer_v2@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#communications/callRecords('3cf3bbc8-b21d-4f2e-bfd0-b13603ae6c65')/organizer_v2/$entity\", \"startDateTime\": \"2023-09-25T09:28:38Z\", \"type\": \"unknown\", \"version\": 2}, {\"endDateTime\": \"2023-09-25T14:03:40Z\", \"id\": \"c3ad8c4b-4a87-4ab1-bef0-284d2f40ed9f\", \"lastModifiedDateTime\": \"2023-09-25T14:18:13Z\", \"modalities\": [\"audio\"], \"organizer\": {\"user\": {\"displayName\": \"Abbie Wilkins\", \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\"}}, \"organizer_v2\": {\"id\": \"+5564981205182\", \"identity\": {\"acsUser\": null, \"phone\": {\"displayName\": null, \"id\": \"+5564981205182\", \"tenantId\": null}, \"spoolUser\": null, \"user\": null}}, \"organizer_v2@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#communications/callRecords('c3ad8c4b-4a87-4ab1-bef0-284d2f40ed9f')/organizer_v2/$entity\", \"startDateTime\": \"2023-09-25T14:03:36Z\", \"type\": \"unknown\", \"version\": 2}]}", "type": "String"}, "call_id": {"type": "String"}, "calls": {"type": "Array"}}}}
Hope this helps. If so, please give a Kudos 👍 and mark as Accepted Solution ✔️.
Hi @faaz,
Just following up to see if the Response provided by community member were helpful in addressing the issue.
If one of the responses helped resolve your query, please consider marking it as the Accepted Solution. Feel free to reach out if you need any further clarification or assistance.
Best regards,
Prasanna Kumar
Unfortunately, I was not able to fix it with the above suggestions. But I am very new to the Graph API so I might have done smething wrong
Do you have a problem with extracting the participant data from the List participants API or with configuring the foreach action in ADF?
No, i have managed to extract both the organizer list and then use a random ID to extract the particiapnt info. The challenge is for each call ID, i need to extract the particiapnt information, and store this somewhere
If you create a new ADF dataset and call the dataset Graph_Teams_ListParticipant, you can past the code below to get an idea of how to configure the dataset.
Dataset code:
{"name": "Graph_Teams_ListParticipant", "properties": {"annotations": [], "linkedServiceName": {"referenceName": "GraphAPI", "type": "LinkedServiceReference"}, "parameters": {"call_id": {"type": "string"}}, "schema": {}, "type": "Json", "typeProperties": {"location": {"relativeUrl": {"type": "Expression", "value": "\"/communications/calls/@{dataset().call_id}/participants\""}, "type": "HttpServerLocation"}}}}
If you create a new ADF pipeline and call it pipeline1, you can past the code below to get an idea of how to configure the pipeline to loop through each call and get the participants. With the Copy data action correctly configured to retreive the API participants data, it should be able to sink it into a table and let the action create a destination table.
Pipeline code:
{"name": "pipeline1", "properties": {"activities": [{"dependsOn": [], "name": "Set call ouput variable", "policy": {"secureInput": false, "secureOutput": false}, "type": "SetVariable", "typeProperties": {"value": {"type": "Expression", "value": "@json(variables('call_example')).value"}, "variableName": "calls"}, "userProperties": []}, {"dependsOn": [{"activity": "Set call ouput variable", "dependencyConditions": ["Succeeded"]}], "name": "ForEach call ID", "type": "ForEach", "typeProperties": {"activities": [{"dependsOn": [{"activity": "Set call_id variable", "dependencyConditions": ["Succeeded"]}], "inputs": [{"parameters": {"call_id": {"type": "Expression", "value": "@variables('call_id')"}}, "referenceName": "Graph_Teams_ListParticipant", "type": "DatasetReference"}], "name": "Copy data1", "onInactiveMarkAs": "Succeeded", "policy": {"retry": 0, "retryIntervalInSeconds": 30, "secureInput": false, "secureOutput": false, "timeout": "0.12:00:00"}, "state": "Inactive", "type": "Copy", "typeProperties": {"enableStaging": false, "source": {"formatSettings": {"type": "JsonReadSettings"}, "storeSettings": {"requestMethod": "GET", "type": "HttpReadSettings"}, "type": "JsonSource"}}, "userProperties": []}, {"dependsOn": [], "name": "Set call_id variable", "policy": {"secureInput": false, "secureOutput": false}, "type": "SetVariable", "typeProperties": {"value": {"type": "Expression", "value": "@item().id"}, "variableName": "call_id"}, "userProperties": []}], "items": {"type": "Expression", "value": "@variables('calls')"}}, "userProperties": []}], "annotations": [], "variables": {"call_example": {"defaultValue": "{\"@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#communications/callRecords\", \"value\": [{\"endDateTime\": \"2023-09-25T09:28:41Z\", \"id\": \"3cf3bbc8-b21d-4f2e-bfd0-b13603ae6c65\", \"lastModifiedDateTime\": \"2023-09-25T10:36:40Z\", \"modalities\": [\"audio\"], \"organizer\": {\"user\": {\"displayName\": \"Abbie Wilkins\", \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\"}}, \"organizer_v2\": {\"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"identity\": {\"user\": {\"displayName\": \"Abbie Wilkins\", \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\"}}}, \"organizer_v2@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#communications/callRecords('3cf3bbc8-b21d-4f2e-bfd0-b13603ae6c65')/organizer_v2/$entity\", \"startDateTime\": \"2023-09-25T09:28:38Z\", \"type\": \"unknown\", \"version\": 2}, {\"endDateTime\": \"2023-09-25T14:03:40Z\", \"id\": \"c3ad8c4b-4a87-4ab1-bef0-284d2f40ed9f\", \"lastModifiedDateTime\": \"2023-09-25T14:18:13Z\", \"modalities\": [\"audio\"], \"organizer\": {\"user\": {\"displayName\": \"Abbie Wilkins\", \"id\": \"821809f5-0000-0000-0000-3b5136c0e777\", \"tenantId\": \"dc368399-474c-4d40-900c-6265431fd81f\"}}, \"organizer_v2\": {\"id\": \"+5564981205182\", \"identity\": {\"acsUser\": null, \"phone\": {\"displayName\": null, \"id\": \"+5564981205182\", \"tenantId\": null}, \"spoolUser\": null, \"user\": null}}, \"organizer_v2@odata.context\": \"https://graph.microsoft.com/v1.0/$metadata#communications/callRecords('c3ad8c4b-4a87-4ab1-bef0-284d2f40ed9f')/organizer_v2/$entity\", \"startDateTime\": \"2023-09-25T14:03:36Z\", \"type\": \"unknown\", \"version\": 2}]}", "type": "String"}, "call_id": {"type": "String"}, "calls": {"type": "Array"}}}}
Hope this helps. If so, please give a Kudos 👍 and mark as Accepted Solution ✔️.
Hi @faaz,
Just following up to see if the Response provided by community member were helpful in addressing the issue.
If one of the responses helped resolve your query, please consider marking it as the Accepted Solution. Feel free to reach out if you need any further clarification or assistance.
Best regards,
Prasanna Kumar
Hi @faaz,
Just following up to see if the Response provided was helpful in resolving your issue. Please feel free to let us know if you need any further assistance.
Best regards,
Prasanna Kumar
Hi @nielsvdc,
Thank you for reaching out to the Microsoft Fabric Forum Community, and special thanks to @nielsvdc for prompt and helpful respons
Just following up to see if the Response provided by community member were helpful in addressing the issue.
If one of the responses helped resolve your query, please consider marking it as the Accepted Solution. Feel free to reach out if you need any further clarification or assistance.
Best regards,
Prasanna Kumar
Hi @faaz,
The output of the Copy Data action named CallRecords is not data. Using this action you are copying the data from the Graph API to maybe a database destination. After the CallRecords you should do a Lookup action and get all the CallIds from the database you saved the data to. Using the result from the Lookup action you can define the items for a ForEach action to loop through every CallId. Using the Copy Data action named CallRecords_Participants you can then do a call to the API to get the participants by CallId.
Your pipeline should look something like this.
Hope this helps. If so, please give a Kudos 👍 and mark as Accepted Solution ✔️.
Niels
Hi Niels. Thank you very much for replying. Can you please tell me what your settings are for each of the steps? I am not sure how you managed to get "CallRecords_Particiapnts" under activites on the "For Each" step. Thank you very much in advance!
I haven't made an example to connect to an API, so I cannot share screenshots about that.
In the Lookup action you will enter a SQL select statement or a stored procedure to retreive all the CallIds from the database that you want to collect the participant from.
In the ForEach action choose dynamic content and from Activity outputs tab select the GetCallIds value array. This will result in this expression: @activity('GetCallIds').output.value
In the Copy Data action within the ForEach action, you can use the ForEachCallRecord item to filter your API call with the expression: item().CallId
Hope this helps. If so, please give a Kudos 👍 and mark as Accepted Solution ✔️.