This is now possible - I have implemented in my own application and it works well.
To allow incoming calls you have to purchase a Toll Free number in ACS - it is not supported with Local numbers. You then configure an Azure Event Grid service to subscribe to Incoming Call events on your ACS instance, and configure a webhook URL for it that points to your own API. Azure Event Grid then posts some data to your API when an incoming call is received which contains the "Incoming Call Context". A member of the ACS team called Jason Shave has created some useful Nugets to help with parsing the Azure Event Grid event data, see here.
Your API can then perform some logic, e.g. check your database to fetch the ACS unique identifier for connected user you want to forward the specific incoming call to, e.g. based on lookup of incoming call telephone number to check for assigned agent, you can then use the CallAutomation client SDK for .Net to redirect the Incoming Call Context to this identifier, and return an empty 200 response to Azure Event Grid so it knows the response has been handled and not to resend.
See full documentation on concepts involved here.
I would also add your endpoint for Azure Event Grid will need to pass validation from Azure - I've added support for that like so:
using Azure.Messaging.EventGrid;
using Azure.Messaging.EventGrid.SystemEvents;
...
[AllowAnonymous]
[HttpPost("~/api/call-automation/event")]
public async Task<IActionResult> Event([FromBody] EventGridEvent[] events)
{
int eventCount = 0;
foreach (var eventGridEvent in events)
{
try
{
logger.LogWarning($"EventGridData[{eventCount++}] data is: {JsonConvert.SerializeObject(eventGridEvent)}");
// Validate whether EventType is of "Microsoft.EventGrid.SubscriptionValidationEvent"
switch (eventGridEvent.EventType)
{
case SystemEventNames.EventGridSubscriptionValidation:
{
var eventData = eventGridEvent.Data.ToObjectFromJson<SubscriptionValidationEventData>();
var responseData = new SubscriptionValidationResponse
{
ValidationResponse = eventData.ValidationCode
};
if (responseData.ValidationResponse != null)
{
return Ok(responseData);
}
}
break;
// Now you can handle incoming call