

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Amazon Cognito Events 自訂工作流程
<a name="cognito-events"></a>

****  
如果您第一次使用 Amazon Cognito Sync，請改用 [AWS AppSync](https://aws.amazon.com/appsync/)。如同 Amazon Cognito Sync， AWS AppSync 是一種跨裝置同步應用程式資料的服務。  
可同步使用者資料，如應用程式偏好設定或遊戲狀態。也擴充這些功能，允許多個使用者在共用資料上即時同步及協作。

Amazon Cognito Events 可讓您執行 AWS Lambda 函數，以回應 Amazon Cognito 中的重要事件。當有資料集同步時，Amazon Cognito 會引發同步觸發器事件。當使用者更新資料時，您可以使用同步觸發器事件來採取動作。此函數可以先評估資料，並選擇性地處理，然後再將資料存放在雲端中，並同步到使用者的其他裝置。這很適合用來驗證來自裝置的資料，然後再同步到使用者的其他裝置，或是根據傳入的資料來更新資料集中的其他值，例如當玩家達到新等級時發出獎項。

下列步驟將引導您設定每次同步 Amazon Cognito 資料集時執行的 Lambda 函數。

**注意**  
使用 Amazon Cognito 事件時，您只能使用從 Amazon Cognito Identity 取得的憑證。如果您有相關聯的 Lambda 函數，但您使用`UpdateRecords` AWS 帳戶登入資料 （開發人員登入資料） 呼叫 ，則不會叫用您的 Lambda 函數。

**在 中建立 函數 AWS Lambda**

若要將 Lambda 與 Amazon Cognito 整合，您需要先在 Lambda 中建立函數。若要這麼做：

**在 Amazon Cognito 中選取 Lambda 函數**

1. 開啟 Lambda 主控台。

1. 按一下 Create a Lambda function (建立 Lambda 函數)。

1. 在 Select blueprint (選取藍圖) 畫面中，搜尋並選取 "cognito-sync-trigger"。

1. 在 Configure event sources (設定事件來源) 畫面中，將 Event source type (事件來源類型) 保持設為 "Cognito Sync Trigger" (Cognito 同步觸發器)，然後選取您的身分集區。按一下 Next (下一步)。
**注意**  
在主控台外設定 Amazon Cognito Sync 觸發程序時，您必須新增以 Lambda 資源為基礎的許可，以允許 Amazon Cognito 叫用該函數。您可以從 Lambda 主控台新增此許可 （請參閱[使用資源型政策） AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html)，或使用 Lambda [AddPermission](https://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html) 操作。  
**以 Lambda 資源為基礎的政策範例**  
下列 AWS Lambda 資源型政策允許 Amazon Cognito 叫用 Lambda 函數的有限功能。Amazon Cognito 只能代表 `aws:SourceArn` 條件中的身分集區和 `aws:SourceAccount` 條件中的帳戶叫用函數。  

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Id": "default",
       "Statement": [
           {
               "Sid": "lambda-allow-cognito-my-function",
               "Effect": "Allow",
               "Principal": {
                   "Service": "cognito-sync.amazonaws.com"
               },
               "Action": "lambda:InvokeFunction",
               "Resource": "arn:aws:lambda:us-east-1:111122223333:function:MyFunction",
               "Condition": {
                   "StringEquals": {
                       "AWS:SourceAccount": "111122223333"
                   },
                   "ArnLike": {
                       "AWS:SourceArn": "arn:aws:cognito-identity:us-east-1:111122223333:identitypool/us-east-1:abcdefg-1234-5678-910a-0e8443553f95"
                   }
               }
           }
       ]
   }
   ```

1. 在 Configure function (設定函數) 畫面中，輸入函數的名稱和描述。將 Runtime (執行時間) 保持設為 "Node.js"。針對我們的範例，程式碼保持不變。預設範例不變更所要同步的資料。它只記錄 Amazon Cognito Sync 觸發器事件發生的事實。將 Handler name (處理常式名稱) 保持設為 "index.handler"。針對角色，選取授予存取 AWS Lambda程式碼許可的 IAM 角色。若要修改角色，請參閱 IAM 主控台。將 Advanced (進階) 設定保持不變。按一下 Next (下一步)。

1. 在 Review (檢閱) 畫面上，檢閱詳細資訊，然後按一下 Create function (建立函數)。下一頁會顯示您的新 Lambda 函數。

現在您有了以 Lambda 編寫的適當函數，您需要選擇該函數做為 Amazon Cognito Sync 觸發器事件的處理常式。下列步驟將逐步引導您完成此程序。

從主控台首頁：

1. 針對要設定 Amazon Cognito 事件的身分集區，按一下其名稱。該身分集區的 Dashboard (儀表板) 頁面隨即出現。

1. 在 Dashboard (儀表板) 頁面右上角，按一下 Manage Federated Identities (管理聯合身分)。Manage Federated Identities (管理聯合身分) 頁面隨即出現。

1. 向下捲動，然後按一下 Cognito Events (Cognito 事件) 將其展開。

1. 在 Sync Trigger (Sync 觸發器) 下拉式選單中，選取您想要在同步事件發生時觸發的 Lambda 函數。

1. 按一下 Save Changes (儲存變更)。

現在，每次同步資料集時，就會執行您的 Lambda 函數。下節將說明在進行同步時，如何讀取及修改函數中的資料。

**編寫 Sync 觸發程序的 Lambda 函數**

Sync 觸發程序遵循服務供應商界面使用的程式設計模型。Amazon Cognito 會以下列 JSON 格式提供輸入給您的 Lambda 函數。

```
{
  "version": 2,
  "eventType": "SyncTrigger",
  "region": "us-east-1",
  "identityPoolId": "identityPoolId",
  "identityId": "identityId",
  "datasetName": "datasetName",
  "datasetRecords": {
    "SampleKey1": {
      "oldValue": "oldValue1",
      "newValue": "newValue1",
      "op": "replace"
    },
    "SampleKey2": {
      "oldValue": "oldValue2",
      "newValue": "newValue2",
      "op": "replace"
    },..
  }
}
```

Amazon Cognito 預期函數的傳回值格式與輸入相同。

為同步觸發程序事件編寫函數時，請觀察以下內容：
+ Amazon Cognito 在 UpdateRecords 期間叫用您的 Lambda 函數時，該函數必須在 5 秒內回應。如果沒做到，Amazon Cognito Sync 服務會產生 `LambdaSocketTimeoutException` 例外狀況。您無法提高此逾時值。
+ 如果你收到 `LambdaThrottledException` 例外狀況，請再次嘗試同步操作以更新記錄。
+ Amazon Cognito 提供資料集中的所有記錄做為函數的輸入。
+ 應用程式使用者更新的記錄具有設定為 `replace` 的 `op` 欄位。已刪除的記錄具有設定為 `remove` 的 `op` 欄位。
+ 即使應用程式使用者沒有更新記錄，您也可以修改任何記錄。
+ 除了 datasetRecords 之外的所有欄位都是唯讀欄位。請勿變更這些欄位。如果變更這些欄位，將無法更新記錄。
+ 若要修改記錄的值，請更新該值，並將 `op` 設定為 `replace`。
+ 若要移除記錄，請將 `op` 設定為 `remove`，或將該值設定為 null。
+ 若要新增記錄，請將新的記錄新增到 datasetRecords 陣列。
+ 當 Amazon Cognito 更新記錄時，會忽略回應中任何省略的記錄。

**Lambda 函數範例**

以下 Lambda 函數範例顯示如何存取、修改及移除資料。

```
console.log('Loading function');

exports.handler = function(event, context) {
    console.log(JSON.stringify(event, null, 2));

    //Check for the event type
    if (event.eventType === 'SyncTrigger') {

        //Modify value for a key
        if('SampleKey1' in event.datasetRecords){
            event.datasetRecords.SampleKey1.newValue = 'ModifyValue1';
            event.datasetRecords.SampleKey1.op = 'replace';
        }

        //Remove a key
        if('SampleKey2' in event.datasetRecords){
            event.datasetRecords.SampleKey2.op = 'remove';
        }

        //Add a key
        if(!('SampleKey3' in event.datasetRecords)){
            event.datasetRecords.SampleKey3={'newValue':'ModifyValue3', 'op' : 'replace'};
        }

    }
    context.done(null, event);
};
```