|
| 1 | +--- |
| 2 | +title: Record a call when it starts |
| 3 | +titleSuffix: An Azure Communication Services how-to document |
| 4 | +description: In this how-to document, you can learn how to record a call through Azure Communication Services once it starts. |
| 5 | +author: ddematheu2 |
| 6 | +manager: shahen |
| 7 | +services: azure-communication-services |
| 8 | +ms.author: dademath |
| 9 | +ms.topic: how-to |
| 10 | +ms.service: azure-communication-services |
| 11 | +ms.date: 03/01/2023 |
| 12 | +--- |
| 13 | + |
| 14 | +# Record a call when it starts |
| 15 | + |
| 16 | +Call recording is often used directly through the UI of a calling application, where the user triggers the recording. For applications within industries like banking or healthcare, call recording is required from the get-go. The service needs to automatically record for compliance purposes. This sample shows how to record a call when it starts. It uses Azure Communication Services and Azure Event Grid to trigger an Azure Function when a call starts. It automatically records every call within your Azure Communication Services resource. |
| 17 | + |
| 18 | +In this QuickStart, we focus on showcasing the processing of call started events through Azure Functions using Event Grid triggers. We use the Call Automation SDK for Azure Communication Services to start recording. |
| 19 | + |
| 20 | +The Call Started event when a call start is formatted in the following way: |
| 21 | + |
| 22 | +```json |
| 23 | + |
| 24 | +[ |
| 25 | + { |
| 26 | + "id": "a8bcd8a3-12d7-46ba-8cde-f6d0bda8feeb", |
| 27 | + "topic": "/subscriptions/{subscription-id}/resourcegroups/{group-name}/providers/microsoft.communication/communicationservices/{communication-services-resource-name}", |
| 28 | + "subject": "call/{serverCallId}/startedBy/8:acs:bc360ba8-d29b-4ef2-b698-769ebef85521_0000000c-1fb9-4878-07fd-0848220077e1", |
| 29 | + "data": { |
| 30 | + "startedBy": { |
| 31 | + "communicationIdentifier": { |
| 32 | + "rawId": "8:acs:bc360ba8-d29b-4ef2-b698-769ebef85521_0000000c-1fb9-4878-07fd-0848220077e1", |
| 33 | + "communicationUser": { |
| 34 | + "id": "8:acs:bc360ba8-d29b-4ef2-b698-769ebef85521_0000000c-1fb9-4878-07fd-0848220077e1" |
| 35 | + } |
| 36 | + }, |
| 37 | + "role": "{role}" |
| 38 | + }, |
| 39 | + "serverCallId": "{serverCallId}", |
| 40 | + "group": { |
| 41 | + "id": "00000000-0000-0000-0000-000000000000" |
| 42 | + }, |
| 43 | + "room": { |
| 44 | + "id": "{roomId}" |
| 45 | + }, |
| 46 | + "isTwoParty": false, |
| 47 | + "correlationId": "{correlationId}", |
| 48 | + "isRoomsCall": true |
| 49 | + }, |
| 50 | + "eventType": "Microsoft.Communication.CallStarted", |
| 51 | + "dataVersion": "1.0", |
| 52 | + "metadataVersion": "1", |
| 53 | + "eventTime": "2021-09-22T17:02:38.6905856Z" |
| 54 | + } |
| 55 | +] |
| 56 | + |
| 57 | +``` |
| 58 | + |
| 59 | +## Pre-requisites |
| 60 | + |
| 61 | +- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). |
| 62 | +- An active Communication Services resource and connection string. [Create a Communication Services resource](../../quickstarts/create-communication-resource.md). |
| 63 | +- Install [Azure CLI](/cli/azure/install-azure-cli-windows?tabs=azure-cli). |
| 64 | + |
| 65 | +## Setting up our local environment |
| 66 | + |
| 67 | +1. Using [Visual Studio Code](https://code.visualstudio.com/), install the [Azure Functions Extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions). |
| 68 | +2. With the extension, create an Azure Function following these [instructions](../../../azure-functions/create-first-function-vs-code-csharp.md). |
| 69 | + |
| 70 | + Configure the function with the following instructions: |
| 71 | + - Language: C# |
| 72 | + - Template: Azure Event Grid Trigger |
| 73 | + - Function Name: User defined |
| 74 | + |
| 75 | + Once created, you see a function created in your directory like this: |
| 76 | + |
| 77 | + ```csharp |
| 78 | + |
| 79 | + using System; |
| 80 | + using Microsoft.Azure.WebJobs; |
| 81 | + using Microsoft.Azure.WebJobs.Extensions.EventGrid; |
| 82 | + using Microsoft.Extensions.Logging; |
| 83 | + using Azure.Messaging.EventGrid; |
| 84 | + using System.Threading.Tasks; |
| 85 | + |
| 86 | + namespace Company.Function |
| 87 | + { |
| 88 | + public static class acs_recording_test |
| 89 | + { |
| 90 | + [FunctionName("acs_recording_test")] |
| 91 | + public static async Task RunAsync([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log) |
| 92 | + { |
| 93 | + log.LogInformation(eventGridEvent.EventType); |
| 94 | + } |
| 95 | + |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + ``` |
| 100 | + |
| 101 | +## Configure Azure Function to receive `CallStarted` event |
| 102 | + |
| 103 | +1. Configure Azure Function to perform actions when the `CallStarted` event triggers. |
| 104 | + |
| 105 | +```csharp |
| 106 | + |
| 107 | + public static async Task RunAsync([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log) |
| 108 | + { |
| 109 | + if(eventGridEvent.EventType == "Microsoft.Communication.CallStarted") |
| 110 | + { |
| 111 | + log.LogInformation("Call started"); |
| 112 | + var callEvent = eventGridEvent.Data.ToObjectFromJson<CallStartedEvent>(); |
| 113 | + |
| 114 | + // CallStartedEvent class is defined in documentation, but the objects looks like this: |
| 115 | + // public class CallStartedEvent |
| 116 | + // { |
| 117 | + // public StartedBy startedBy { get; set; } |
| 118 | + // public string serverCallId { get; set; } |
| 119 | + // public Group group { get; set; } |
| 120 | + // public bool isTwoParty { get; set; } |
| 121 | + // public string correlationId { get; set; } |
| 122 | + // public bool isRoomsCall { get; set; } |
| 123 | + // } |
| 124 | + // public class Group |
| 125 | + // { |
| 126 | + // public string id { get; set; } |
| 127 | + // } |
| 128 | + // public class StartedBy |
| 129 | + // { |
| 130 | + // public CommunicationIdentifier communicationIdentifier { get; set; } |
| 131 | + // public string role { get; set; } |
| 132 | + // } |
| 133 | + // public class CommunicationIdentifier |
| 134 | + // { |
| 135 | + // public string rawId { get; set; } |
| 136 | + // public CommunicationUser communicationUser { get; set; } |
| 137 | + // } |
| 138 | + // public class CommunicationUser |
| 139 | + // { |
| 140 | + // public string id { get; set; } |
| 141 | + // } |
| 142 | + } |
| 143 | + } |
| 144 | + |
| 145 | +``` |
| 146 | + |
| 147 | +## Start recording |
| 148 | + |
| 149 | +1. Create a method to handle the `CallStarted` events. This method trigger recording to start when the call started. |
| 150 | + |
| 151 | +```csharp |
| 152 | + |
| 153 | + public static async Task RunAsync([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log) |
| 154 | + { |
| 155 | + if(eventGridEvent.EventType == "Microsoft.Communication.CallStarted") |
| 156 | + { |
| 157 | + log.LogInformation("Call started"); |
| 158 | + var callEvent = eventGridEvent.Data.ToObjectFromJson<CallStartedEvent>(); |
| 159 | + await startRecordingAsync(callEvent.serverCallId); |
| 160 | + } |
| 161 | + } |
| 162 | + |
| 163 | + public static async Task startRecordingAsync (String serverCallId) |
| 164 | + { |
| 165 | + CallAutomationClient callAutomationClient = new CallAutomationClient(Environment.GetEnvironmentVariable("ACS_CONNECTION_STRING")); |
| 166 | + StartRecordingOptions recordingOptions = new StartRecordingOptions(new ServerCallLocator(serverCallId)); |
| 167 | + recordingOptions.RecordingChannel = RecordingChannel.Mixed; |
| 168 | + recordingOptions.RecordingContent = RecordingContent.AudioVideo; |
| 169 | + recordingOptions.RecordingFormat = RecordingFormat.Mp4; |
| 170 | + var startRecordingResponse = await callAutomationClient.GetCallRecording() |
| 171 | + .StartRecordingAsync(recordingOptions).ConfigureAwait(false); |
| 172 | + } |
| 173 | + |
| 174 | +``` |
| 175 | + |
| 176 | +### Running locally |
| 177 | + |
| 178 | +To run the function locally, you can press `F5` in Visual Studio Code. We use [ngrok](https://ngrok.com/) to hook our locally running Azure Function with Azure Event Grid. |
| 179 | + |
| 180 | +1. Once the function is running, we configure ngrok. (You need to [download ngrok](https://ngrok.com/download) for your environment.) |
| 181 | + |
| 182 | + ```bash |
| 183 | + |
| 184 | + ngrok http 7071 |
| 185 | + |
| 186 | + ``` |
| 187 | + |
| 188 | + Copy the ngrok link provided where your function is running. |
| 189 | + |
| 190 | +2. Configure C`allStarted` events through Event Grid within your Azure Communication Services resource. We do this using the [Azure CLI](/cli/azure/install-azure-cli-windows?tabs=azure-cli). You need the resource ID for your Azure Communication Services resource found in the Azure portal. (The resource ID looks something like: `/subscriptions/<<AZURE SUBSCRIPTION ID>>/resourceGroups/<<RESOURCE GROUP NAME>>/providers/Microsoft.Communication/CommunicationServices/<<RESOURCE NAME>>`) |
| 191 | +
|
| 192 | + ```bash |
| 193 | +
|
| 194 | + az eventgrid event-subscription create --name "<<EVENT_SUBSCRIPTION_NAME>>" --endpoint-type webhook --endpoint "<<NGROK URL>>/runtime/webhooks/EventGrid?functionName=<<FUNCTION NAME>> " --source-resource-id "<<RESOURCE_ID>>" --included-event-types Microsoft.Communication.CallStarted |
| 195 | +
|
| 196 | + ``` |
| 197 | +
|
| 198 | +3. Now that everything is hooked up, test the flow by starting a call on your resource. You should see the console logs on your terminal where the function is running. You can check that the recording is starting by using the [call recording feature](../calling-sdk/record-calls.md?pivots=platform-web) on the calling SDK and check for the boolean to turn TRUE. |
| 199 | +
|
| 200 | +### Deploy to Azure |
| 201 | +
|
| 202 | +To deploy the Azure Function to Azure, you need to follow these [instructions](../../../azure-functions/create-first-function-vs-code-csharp.md#deploy-the-project-to-azure). Once deployed, we configure Event Grid for the Azure Communication Services resource. With the URL for the Azure Function that was deployed (URL found in the Azure portal under the function), we run a similar command: |
| 203 | +
|
| 204 | +```bash |
| 205 | +
|
| 206 | +az eventgrid event-subscription update --name "<<EVENT_SUBSCRIPTION_NAME>>" --endpoint-type azurefunction --endpoint "<<AZ FUNCTION URL>> " --source-resource-id "<<RESOURCE_ID>>" |
| 207 | +
|
| 208 | +``` |
| 209 | +
|
| 210 | +Since we're updating the event subscription we created, make sure to use the same event subscription name you used in the previous step. |
| 211 | +
|
| 212 | +You can test by starting a call in your resource, similar to the previous step. |
0 commit comments