Поделиться через


Отвечайте на звонки Teams Phone с помощью системы автоматизации звонков

Используйте службу автоматизации вызовов Служб коммуникации Azure для получения и ответа на вызовы учетной записи ресурсов Teams.

Это важно

Эта функция Службы коммуникации Azure сейчас доступна в предварительной версии. Функции в предварительной версии общедоступны и могут использоваться всеми новыми и существующими клиентами Майкрософт.

Эта предварительная версия предоставляется без соглашения об уровне обслуживания, и мы не рекомендуем использовать её для производственных нагрузок. Некоторые функции могут не поддерживаться или могут быть ограничены.

Для получения дополнительной информации см. Дополнительные условия использования для предварительных версий Microsoft Azure.

Предпосылки

Связывание учетной записи ресурсов Teams с ресурсом Служб коммуникации

Выполните следующую команду. Убедитесь, что у вас есть идентификатор ресурса Служб коммуникации Azure. Чтобы найти его, ознакомьтесь с неизменяемым идентификатором ресурса.

Set-CsOnlineApplicationInstance -Identity <appIdentity> -AcsResourceId <acsResourceId>

Дополнительные сведения см. в этом руководстве. Связывание ресурса Служб коммуникации Azure с учетной записью ресурса Teams

Настройте ресурс Служб коммуникации для приема вызовов учетной записи ресурсов Teams

Отправьте запрос к API назначения доступа к расширениям Microsoft Teams, чтобы разрешить прием вызовов для ресурсной учетной записи Teams. Дополнительные сведения о проверке подлинности веб-запроса см. в этом руководстве: проверка подлинности

В следующем примере показан запрос клиента Teams с идентификатором 87d349ed-44d7-43e1-9a83-5f2406dee5bd и идентификатором учетной записи ресурса Teams с идентификатором e5b7f628-ea94-4fdc-b3d9-1af1fe231111.

PUT {endpoint}/access/teamsExtension/tenants/87d349ed-44d7-43e1-9a83-5f2406dee5bd/assignments/e5b7f628-ea94-4fdc-b3d9-1af1fe231111?api-version=2025-03-02-preview

{
    "principalType" : "teamsResourceAccount",
}

{principalType} нужно teamsResourceAccount.

Ответ

Ниже показан пример отклика.

HTTP/1.1 201 Created
Content-type: application/json

{
    "objectId": "e5b7f628-ea94-4fdc-b3d9-1af1fe231111",
    "tenantId": "87d349ed-44d7-43e1-9a83-5f2406dee5bd",
    "principalType" : "teamsResourceAccount",
}

Прекратите принимать вызовы для учетной записи ресурсов Teams

Отправьте запрос в API доступа назначений расширения Microsoft Teams, чтобы удалить запись учетной записи ресурса Teams.

DELETE {endpoint}/access/teamsExtension/assignments/e5b7f628-ea94-4fdc-b3d9-1af1fe231111?api-version=2025-03-02-preview

Ответ

HTTP/1.1 204 NoContent
Content-type: application/json

{}

Чтобы убедиться, что учетная запись ресурсов Teams больше не связана с ресурсом Служб коммуникации, вы можете отправить запрос GET в API назначений расширений Microsoft Teams. Убедитесь, что код состояния ответа равен 404.

GET {endpoint}/access/teamsExtension/assignments/e5b7f628-ea94-4fdc-b3d9-1af1fe231111?api-version=2025-03-02-preview

Получение и ответ на входящие звонки

Настройка и размещение Azure DevTunnel

DevTunnels создает URL-адрес постоянной конечной точки, который разрешает анонимный доступ. Мы используем эту конечную точку для уведомления приложения о вызове событий из службы автоматизации вызовов Службы коммуникации Azure.

devtunnel create --allow-anonymous

devtunnel port create -p 8080

devtunnel host

Обработайте событие входящего вызова и ответьте на вызов

app.MapPost("/api/incomingCall", async (
    [FromBody] EventGridEvent[] eventGridEvents,
    ILogger<Program> logger) =>
{
    if (eventGridEvent.TryGetSystemEventData(out object systemEvent))
    {
        switch (systemEvent)
        {
            case SubscriptionValidationEventData subscriptionValidated:
               var responseData = new SubscriptionValidationResponse
                {
                    ValidationResponse = subscriptionValidationEventData.ValidationCode
                };
                return Results.Ok(responseData);

            case AcsIncomingCallEventData incomingCall:
                var callbackUri = new Uri(new Uri(devTunnelUri), $"/api/callbacks");
                var options = new AnswerCallOptions(incomingCallContext, callbackUri);

                AnswerCallResult answerCallResult = await callAutomationClient.AnswerCallAsync(options);
                logger.LogInformation($"Answered call for connection id: {answerCallResult.CallConnection.CallConnectionId}");

                //Use EventProcessor to process CallConnected event

                var answerResult =  await answerCallResult.WaitForEventProcessorAsync();
                if (answerResult.IsSuccess)
                {
                   logger.LogInformation($"Call connected event received for connection id: {answerResult.SuccessResult.CallConnectionId}");
                   var callConnectionMedia = answerCallResult.CallConnection.GetCallMedia();
                }
                return Results.Ok();

            default:
                logger.LogInformation($"Received unexpected event of type {eventGridEvent.EventType}");
                return Results.BadRequest();
        }
    }
    return Results.Ok();
});

Пример события входящего вызова с идентификатором учетной записи ресурса Teams и пользовательским контекстом (VoIP и SIP)

{
  "to": {
    "kind": "unknown",
    "rawId": "28:orgid:cc123456-5678-5678-1234-ccc123456789"
  },
  "from": {
    "kind": "phoneNumber",
    "rawId": "4:+12065551212",
    "phoneNumber": {
      "value": "+12065551212"
    }
  },
  "serverCallId": "aHR0cHM6Ly9hcGkuZmxpZ2h0cHJveHkudGVhbXMubWljcm9zb2Z0LmNvbS9hcGkvdjIvZXAvY29udi11c3dlLTAyLXNkZi1ha3MuY29udi5za3lwZS5jb20vY29udi9fVERMUjZVS3BrT05aTlRMOHlIVnBnP2k9MTAtNjAtMTMtMjE2JmU9NjM4NTMwMzUzMjk2MjI3NjY1",
  "callerDisplayName": "+12065551212",
  "customContext":
  {
    "voipHeaders":
    {
        "X-myCustomVoipHeaderName": "myValue"
    },
  },
  "incomingCallContext": "<CALL_CONTEXT VALUE>",
  "correlationId": "2e0fa6fe-bf3e-4351-9beb-568add4f5315"
}

Дальнейшие шаги