

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 更新正在对 Amazon Chime SDK PTSN 音频服务进行的调用
<a name="update-sip-call"></a>

作为 PSTN 音频服务的一部分，SIP 媒体应用程序允许您根据调用事件（例如传入调用或 DTMF 数字）调用用户定义的 Lambda 函数，从而设置在调用过程中运行的操作。[https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html) API 让您能够在调用处于活动状态时随时触发 Lambda 函数，将当前操作替换为调用返回的新操作。

**工作流**  
您可以在各种情况下使用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html) API，例如向会议添加参与者、将用户静音和取消静音、断开连接等。以下使用案例描述了典型的工作流程。

当 Amazon Chime SDK 设置会议时，用户调用并听音乐。设置完成后，Amazon Chime SDK 会停止播放音频并允许调用者加入会议。然后，假设使用单独的系统 `MyMeetingService` 管理会议。每个传入调用都应置于保持状态。Chime 会 MyMeetingService 通知来电， MyMeetingService 然后为每个呼叫创建一个与会者，当准备好开始会议时，它会通知 SIP 媒体应用程序并提供加入会议的令牌。 MyMeetingService 

要处理这种情况，Lambda 函数必须实现以下逻辑。
+ 当新的传入调用到达时，Lambda 将使用 `NEW_INBOUND_CALL` 事件调用。Lambda 调用 `MyMeetingService` 并传递标识当前调用的 `transactionId`，然后返回 `PlayAudio` 操作。
+ 当 `MyMeetingService` 准备好添加调用者到会议中时，该服务会调用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html) API，并将调用的 `transactionId` 和 `JoinToken` 作为其参数的一部分进行传递。现在，此 API 调用使用 `CALL_UPDATE_REQUESTED` 事件再次触发 Lambda 函数。作为事件的一部分，`JoinToken`将 MyMeetingService 传递给 Lambda 函数，令牌用于将`JoinChimeMeeting`操作返回给 SIP 媒体应用程序，后者会中断`PlayAudio`操作并将呼叫者连接到会议。

![显示 UpdateSipMediaApplicationCall API 中数据流的图表。](http://docs.aws.amazon.com/zh_cn/chime-sdk/latest/dg/images/update-sip-call-flow3.png)


**注意**  
[https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_UpdateSipMediaApplicationCall.html) API 返回 HTTP 202（已接受）。SIP 媒体应用程序确认调用正在进行并且可以更新，因此它会尝试调用 Lambda 函数。调用异步执行，因此 API 的成功响应并不能保证 Lambda 函数已启动或已完成。

以下示例显示请求语法。

```
{
    "SipMediaApplicationId": "{{string}}",
    "TransactionId": "{{string}}",
    "Arguments": {
        "string": "{{string}}"
    } 
}
```

**请求参数**
+ `SipMediaApplicationId` — 处理调用的 SIP 媒体应用程序的 ID。
+ `TransactionId` — 调用事务的 ID。对于入站调用，`TransactionId` 可以从首次调用时传递给 Lambda 函数的 `NEW_INCOMING_CALL` 事件中获取。对于出站调用，`TransactionId` 会在 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_CreateSipMediaApplicationCall.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_CreateSipMediaApplicationCall.html) 的响应中返回。
+ **参数** — 作为 `CallUpdateRequest` 操作数据一部分提供给 Lambda 函数的自定义参数。可包含 0 到 20 个密钥值对。

以下示例显示典型请求。

```
aws chime update-sip-media-application-call --sip-media-application-id feb37a7e-2b66-49fb-b2dd-30f4780dc36d --transaction-id 1322a4e7-c106-4e70-aaaf-a8fa4c77c0cb --arguments '{"JoinToken": "{{abc123}}"}'
```

**响应语法**

```
{
  "SipMediaApplicationCall": {
  "TransactionId": "{{string}}"
  }
}
```

**响应元素**
+ **TransactionId**— 呼叫交易的 ID，与请求的 ID 相同。

以下示例代码显示 `CALL_UPDATE_REQUESTED` 调用事件。

```
{
  "SchemaVersion": "1.0",
  "Sequence": {{2}},
  "InvocationEventType": "CALL_UPDATE_REQUESTED",
  "ActionData": {
    "Type": "CallUpdateRequest",
    "Parameters": {
      "Arguments": {
        "{{string}}": "{{string}}"
      }
    }
  },
  "CallDetails": {
    ...
  }
}
```

**事件元素**
+ **SchemaVersion**— JSON 架构的版本 (1.0)
+ **序列** — 调用中事件的序列号
+ **InvocationEventType**— 在本例中为 Lambda 调用事件的类型，`CALL_UPDATE_REQUESTED`
+ **ActionData**— 与`CallUpdateRequest`操作相关的数据。
  + **类型** — 操作的类型，在本例中为 `CallUpdateRequest`
  + **参数** — 操作的参数
    + **参数** — 作为 `UpdateSipMediaApplicationCall` API 请求的一部分传递的参数
+ **CallDetails**— 有关当前呼叫状态的信息

**了解可中断和不间断操作**  
当 Lambda 函数返回新的操作列表是现有操作仍在运行时，所有正在进行的操作之后的操作都将被替换为新操作。在某些情况下，Lambda 函数会中断正在进行的操作，以便立即运行新操作。

以下图表显示典型示例。图表下方的文字解释逻辑。

![显示正在进行的 SIP 媒体应用程序调用期间如何替换操作的图表。](http://docs.aws.amazon.com/zh_cn/chime-sdk/latest/dg/images/update-sip-actions.png)


如果操作 2 可中断，我们将其停止并运行新的操作 1。

如果操作 2 不可中断，它将在完成后运行新的操作 1。

在这两种情况下，都不会运行操作 3。

如果某个操作被中断，则使用 `ACTION_INTERRUPTED` 事件调用 Lambda 函数。此事件仅用于提供信息。SIP 媒体应用程序会忽略此调用返回的所有操作。

可中断操作的类型：
+ `PlayAudio`
+ `RecordAudio`
+ `Pause`

**示例 Lambda 函数**  
此示例显示典型的 Lambda 函数，该函数用于播放音频文件、传递加入令牌并更新调用。

```
const MMS = require('my-meeting-service');
const myMeetingServiceClient = new MMS.Client();

exports.handler = async (event) => {
    console.log('Request: ' + JSON.stringify(event));
    
    const playAudio = () => {
      return {
        Type: 'PlayAudio',
        Parameters: {
          ParticipantTag: 'LEG-A',
          AudioSource: {
            Type: 'S3',
            BucketName: '{{chime-meetings-audio-files-bucket-name}}',
            Key: '{{welcome.wav}}'
          }
        }
      }
    }
    
    const joinChimeMeeting = (joinToken) => {
      return {
        Type: 'JoinChimeMeeting',
        Parameters: {
          JoinToken: {{joinToken}}
        }
      }
    }
    
    const response = (...actions) => {
      const r = {
        SchemaVersion: '1.0',
        Actions: actions
      };
      console.log('Response: ' + JSON.stringify(r));
      return r;
    };
    
    switch (event.InvocationEventType) {
      case 'NEW_INBOUND_CALL': 
        myMeetingServiceClient.addPendingCall(event.CallDetails.TransactionId);         
        return response(playAudio());      
      case 'CALL_UPDATE_REQUESTED':
        const joinToken = event.ActionData.Parameters.Arguments['{{JoinToken}}']
        return response(joinChimeMeeting(joinToken));
      default:
        return response();
    }
}
```