Azure Communication Services- Tracking User Presence/Status for Calls
Azure Communication Services (ACS) makes it easy for developers to add voice and video calling capabilities to websites, desktop applications and mobile apps with just a few lines of code. While developer friendly APIs and SDKs make it easy to create personalized communication experiences quickly, using the same reliable and secure infrastructure that powers Microsoft Teams.
In the previous blogs Fully Managed Communication Platform — Azure Communication Service, we have learned how to leverage the Azure Portal to create ACS resource then in blog Azure Communication Services Explore Chat SDK we explored JavaScript SDK for building chat application and in the last blog Azure Communication Service- Chat with File Sharing, we explored how by extending Group chat hero sample we added a new feature of file sharing between chat participants in a chat thread so as to have a faster richer experience using ACS.
In this blog, let us explore how to show the Online/In-a-Call status of a participant in a context of ACS calling.
Use Case
For the scenario, where in the collaboration platform, before reaching out to user, there is frequent requirement to know presence of user (Online, In-a-Call). As on today, user presence is not supported in ACS Calling yet. Objective of this blog is to explore how using ACS Calling events, we can define our custom approach to define user presence for Calling.
On to the Drawing Board
Above is the reference diagram of what we are going to achieve by end of this blog. To design and implement logic to know user presence in calling, we shall leverage Communication Services Calling events, which we shall integrate with Azure Event Grid to deliver real-time event notifications in a reliable, scalable and secure manner. When an event is triggered, the Event Grid service sends data about that event to subscribe endpoints which in our case shall be Azure Storage Queue. This triggers user state function which records user state in Azure Storage Table. Now, these user states are ready to be pulled by web client.
Looking into Details
Let's breakdown white board into high level steps
- Azure Communication Services Integration with Azure Event Grid
- Key Calling Events to Subscribe
- Craft Azure functions
1. Azure Communication Services Integration with Azure Event Grid
Azure Communication Services integrates with Azure Event Grid to capture real-time event notifications in a reliable, scalable and secure manner. Event grid uses event subscriptions to route event messages to subscribers and works on publish-subscribe model. From azure portal, select your ACS resource and under Events, create event subscription with Event Grid as shown below.
2. Key Calling Events to Subscribe
Azure Communication Services emits the following event types:
For our use case we need to configure voice and video calling event types and ignore rest safely. Below table provides details about the full Event Type name which shall be used later to capture the status of the user.
To configure above events, from azure portal, select your ACS resource and under Events, create event subscription by selecting below calling events.
Note: Calling events are only available for ACS VoIP users. PSTN, bots, echo bot and Teams users events are excluded. No calling events will be available for ACS — Teams meeting interop call. Also these calling events are in public preview as on writing the blog.
Categorization of Call
ACS calls can be segregated in to two types
- Group Calls
- 1:1 Calls
Key Consideration
We can leverage these events to identify if the call is group call or 1:1 call. The JSON data of these calling events have property “isTwoParty” which has value false if its Group call and value true if its 1:1 call.
ACS Group Calls
In ACS Group Call, above defined all four calling events are triggered.
Now, let’s see what the data would look like for CallParticipantAdded & CallParticipantRemoved events. We will use this data to track user state.
Let’s start with CallParticipantAdded event, here in below JSON, to suffice bare minimum requirements, we need to know calling eventType and ACS user id. In this case, these are in “user”->“rawId” and “eventType” tags and values of these are “8:acs:a096d417–212d-437d-aeae-5a1596de0b5f_0000000e-5710–68c5-ac00–343a0d001211” and Microsoft.Communication.CallParticipantAdded. Event “CallParticipantAdded” signifies that user has entered into a call, hence we can mark user status as “In-a-Call”. To implement this logic, you need to have an Azure function which is trigger based on the storage as described in white boarding section.
Message body Participants Added{"id":"107d73c2-b87b-47c1-84a0-1a194a958885","topic":"/subscriptions/{subscription-id}/resourcegroups/{group-name}/providers/microsoft.communication/communicationservices/{communication-services-resource-name}","subject":"call/{serverCallId}/participant/8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211","data":{"user":{"rawId":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211","communicationUser":{"id":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211"}},"displayName":"ManishAcs1","participantId":"6d6c6c5b-eaae-430b-ad83-7b09c0cbdc54","endpointType":"ACSWeb(3617/1.0.0.1510)/TsCallingVersion=2021.07.01.19/Ovb=e116e8026f445b08ee4d0cc36866a061363c0254","startedBy":{"rawId":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211","communicationUser":{"id":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211"}},"serverCallId":"{serverCallId}","group":{"id":"00000000-0000-0000-0000-000000000000"},"isTwoParty":false,"correlationId":"efd7da03-90e6-4e78-80f9-f9611e3a8024"},"eventType":"Microsoft.Communication.CallParticipantAdded","dataVersion":"1.0","metadataVersion":"1","eventTime":"2021-12-14T04:24:02.6368957Z"}
Once call is over, user status needs to be marked as “Online”. For this, we shall leverage “CallParticipantRemoved” events. From output JSON of event, we will extract both eventType and ACS user id from “user”->“rawId” and “eventType” tags. Below is an example JSON in which we do have eventType as “Microsoft.Communication.CallParticipantRemoved” and ACS User Id “8:acs:a096d417–212d-437d-aeae-5a1596de0b5f_0000000e-5710–68c5-ac00–343a0d001211”.
Message Body Participants removed{"id":"bc37ec29-0185-4484-8bc7-b58a507c86d4","topic":"/subscriptions/{subscription-id}/resourcegroups/{group-name}/providers/microsoft.communication/communicationservices/{communication-services-resource-name}","subject":"call/{serverCallId}/participant/8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211","data":{"user":{"rawId":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211","communicationUser":{"id":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211"}},"displayName":"ManishAcs1","participantId":"6d6c6c5b-eaae-430b-ad83-7b09c0cbdc54","startedBy":{"rawId":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211","communicationUser":{"id":"8:acs:a096d417-212d-437d-aeae-5a1596de0b5f_0000000e-5710-68c5-ac00-343a0d001211"}},"serverCallId":"{serverCallId}","group":{"id":"00000000-0000-0000-0000-000000000000"},"isTwoParty":false,"correlationId":"efd7da03-90e6-4e78-80f9-f9611e3a8024"},"eventType":"Microsoft.Communication.CallParticipantRemoved","dataVersion":"1.0","metadataVersion":"1","eventTime":"2021-12-14T04:32:41.1289695Z"}
ACS 1:1 Calls
For 1:1 calls, only three calling events are triggered. CallStarted, CallParticipantAdded and CallEnded. Using these calling events we can capture the user state for 1:1 calls.
3. Craft Azure functions
In earlier step, we leveraged Event Grid to capture the events. Event Grid has built-in support for Azure services like Azure Functions and Azure Logic Apps. It can deliver event alerts to non-Azure services using webhooks. Choice of services depend on the enterprise Architecture guidelines and Non-Functional Requirements. For this blog, we are going to leverage Azure Function. We are going to use two functions
- Queue Storage trigger maintain user state function
- HTTP trigger query user state function
Building an Azure Maintain User State function
The queue storage trigger runs a function as calling event messages are added to Azure Queue storage after processing. We will leverage this function to capture user state and insert the user state into Azure storage table.
Building an Azure Query User State function
Once user state has been saved into Azure storage table, now we can leverage HTTP trigger Azure function to pull out user state from azure storage table and use in our client application.
Bring Skeleton in life
Now, we do have all the building blocks ready to use. Final step is to create an application which shall be used by end users. You can use Azure communication services sample app as baseline and extend as per your function requirements. In your application, whenever you need to pull user status, or you just need to call Azure Query user state function as a rest API. With this approach you are off loading all heavy and complex work behind the screen on the server side using Event Grid, Azure functions and Azure Communication Service configuration for events.
Summary
In this post, we learned about using ACS Calling Events to track user status (Online, in-a-call) with the help of Azure Event Grid, Azure Functions and Azure Storage.
I would love to know more about your use cases and share my learnings.
References
- Azure Communication Services Calling Events — Get started with the ACS Calling Events.
- HTTP Trigger Azure Function. — Get started with HTTP Trigger Azure Functions
- Azure Queue Storage Trigger Function- Get Started with azure queue storage trigger functions
- Azure Communication Services Sample app- Get started with ACS calling hero sample application
- Azure Event Grid : Get started with Azure Event grid