

**支援結束通知：**2026 年 10 月 30 日， AWS 將結束對 Amazon Pinpoint 的支援。2026 年 10 月 30 日之後，您將無法再存取 Amazon Pinpoint 主控台或 Amazon Pinpoint 資源 (端點、區段、行銷活動、旅程和分析)。如需詳細資訊，請參閱 [Amazon Pinpoint 終止支援](https://docs.aws.amazon.com/console/pinpoint/migration-guide)。**注意：**與 SMS、語音、行動推播、OTP 和電話號碼驗證相關的 APIs 不受此變更影響，並受 AWS 最終使用者傳訊支援。

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

# 建立 Lambda 函數以搭配 Amazon Pinpoint SMS 訊息使用
<a name="tutorials-two-way-sms-part-3"></a>

本節說明如何建立和設定兩個 Lambda 函數，以搭配 Amazon Pinpoint SMS 訊息使用。稍後，您會設定 API Gateway 和 Amazon Pinpoint，在特定事件發生時叫用這些函數。這兩個函數都會在您指定的 Amazon Pinpoint 專案中建立和更新端點。第一個函數也會使用電話號碼驗證功能。

## 建立函數來驗證客戶資訊和建立端點
<a name="tutorials-two-way-sms-part-3-create-register-function"></a>

第一個函數會從註冊表單取得輸入，該表單會從 Amazon API Gateway 接收。它使用此資訊，透過使用 Amazon Pinpoint [的電話號碼驗證](https://docs.aws.amazon.com/pinpoint/latest/developerguide/validate-phone-numbers.html)功能來取得客戶電話號碼的相關資訊。接著函數使用驗證過的資料，在您指定的 Amazon Pinpoint 專案中建立新端點。在預設情況下，函數建立的端點會選擇退出您未來的通訊，但您可以在第二個函數中變更此狀態。最後，此函數會傳送訊息給客戶，要求他們確認是否希望收到您的簡訊通訊。

**建立 Lambda 函數**

1. 在 https：//[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) 開啟 AWS Lambda 主控台。

1. 選擇**建立函數**。

1. 在**建立函數**下，選擇**使用藍圖**。

1. 在搜尋欄位中，輸入 **hello**，然後按 Enter 鍵。在結果清單中，選擇 `hello-world` Node.js 函數，如下圖所示。  
![\[顯示使用所選藍圖的建立函數頁面。\]](http://docs.aws.amazon.com/zh_tw/pinpoint/latest/userguide/images/SMS_Reg_Tutorial_LAM_Step1.5.png)

1. 在**基本資訊**下，請執行下列動作：
   + 對於 **Name (名稱)**，輸入函數的名稱，例如 **RegistrationForm**。
   + 針對 **Role (角色)**，請選擇 **Choose an existing role (選擇現有的角色)**。
   + 針對**現有角色**，選擇您在建立 IAM 角色中建立的 **SMSRegistrationForm** 角色。 [建立 IAM 角色](tutorials-two-way-sms-part-2.md#tutorials-two-way-sms-part-2-create-role)

   完成後，請選擇 **Create function (建立函數)**。

1. 對於**程式碼來源**，請在程式碼編輯器中刪除範例函數，然後貼上下列程式碼：

   ```
   import { PinpointClient, PhoneNumberValidateCommand, UpdateEndpointCommand, SendMessagesCommand } from "@aws-sdk/client-pinpoint"; // ES Modules import
   const pinClient = new PinpointClient({region: process.env.region});  
   
   // Make sure the SMS channel is enabled for the projectId that you specify.
   // See: https://docs.aws.amazon.com/pinpoint/latest/userguide/channels-sms-setup.html
   var projectId = process.env.projectId;
   
   // You need a dedicated long code in order to use two-way SMS. 
   // See: https://docs.aws.amazon.com/pinpoint/latest/userguide/channels-voice-manage.html#channels-voice-manage-request-phone-numbers
   var originationNumber = process.env.originationNumber;
   
   // This message is spread across multiple lines for improved readability.
   var message = "ExampleCorp: Reply YES to confirm your subscription. 2 msgs per "
               + "month. No purchase req'd. Msg&data rates may apply. Terms: "
               + "example.com/terms-sms";
               
   var messageType = "TRANSACTIONAL";
   
   export const handler = async (event, context) => {
     console.log('Received event:', event);
     await validateNumber(event);
   };
   
   async function validateNumber (event) {
     var destinationNumber = event.destinationNumber;
     if (destinationNumber.length == 10) {
       destinationNumber = "+1" + destinationNumber;
     }
     var params = {
       NumberValidateRequest: {
         IsoCountryCode: 'US',
         PhoneNumber: destinationNumber
       }
     };
     try{
       const PhoneNumberValidateresponse = await pinClient.send( new  PhoneNumberValidateCommand(params));
       console.log(PhoneNumberValidateresponse);
        if (PhoneNumberValidateresponse['NumberValidateResponse']['PhoneTypeCode'] == 0) {
           await createEndpoint(PhoneNumberValidateresponse, event.firstName, event.lastName, event.source);
           
         } else {
           console.log("Received a phone number that isn't capable of receiving "
                      +"SMS messages. No endpoint created.");
         }
     }catch(err){
       console.log(err);
     }
   }
   
   async function createEndpoint(data, firstName, lastName, source) {
     var destinationNumber = data['NumberValidateResponse']['CleansedPhoneNumberE164'];
     var endpointId = data['NumberValidateResponse']['CleansedPhoneNumberE164'].substring(1);
     
     var params = {
       ApplicationId: projectId,
       // The Endpoint ID is equal to the cleansed phone number minus the leading
       // plus sign. This makes it easier to easily update the endpoint later.
       EndpointId: endpointId,
       EndpointRequest: {
         ChannelType: 'SMS',
         Address: destinationNumber,
         // OptOut is set to ALL (that is, endpoint is opted out of all messages)
         // because the recipient hasn't confirmed their subscription at this
         // point. When they confirm, a different Lambda function changes this 
         // value to NONE (not opted out).
         OptOut: 'ALL',
         Location: {
           PostalCode:data['NumberValidateResponse']['ZipCode'],
           City:data['NumberValidateResponse']['City'],
           Country:data['NumberValidateResponse']['CountryCodeIso2'],
         },
         Demographic: {
           Timezone:data['NumberValidateResponse']['Timezone']
         },
         Attributes: {
           Source: [
             source
           ]
         },
         User: {
           UserAttributes: {
             FirstName: [
               firstName
             ],
             LastName: [
               lastName
             ]
           }
         }
       }
     };
     try{
       const UpdateEndpointresponse = await pinClient.send(new UpdateEndpointCommand(params));
       console.log(UpdateEndpointresponse);
       await sendConfirmation(destinationNumber);
     }catch(err){
       console.log(err);
     }  
   }
   
   async function sendConfirmation(destinationNumber) {
     var params = {
       ApplicationId: projectId,
       MessageRequest: {
         Addresses: {
           [destinationNumber]: {
             ChannelType: 'SMS'
           }
         },
         MessageConfiguration: {
           SMSMessage: {
             Body: message,
             MessageType: messageType,
             OriginationNumber: originationNumber
           }
         }
       }
     };
     try{
       const SendMessagesCommandresponse = await pinClient.send(new SendMessagesCommand(params));
       console.log("Message sent! " 
             + SendMessagesCommandresponse['MessageResponse']['Result'][destinationNumber]['StatusMessage']);
     }catch(err){
       console.log(err);
     }
   }
   ```

1. 在**環境變數**的**組態**索引標籤上，選擇**編輯**，然後選擇**新增環境變數**，然後執行下列動作：
   + 在第一個資料列，建立索引鍵為 **originationNumber** 的變數。接著，將其值設定為您在[步驟 1.2](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-set-up-channel) 中所收到專屬長碼的電話號碼。
**注意**  
請務必加上加號 (\$1) 和電話號碼的國家/地區代碼。不要包含任何其他特殊字元，例如連字號 (-)、句號 (.) 或括號。
   + 在第二個資料列，建立索引鍵為 **projectId** 的變數。接著，將其值設定為您在[步驟 1.1](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-create-project) 中所建立專案的唯一 ID。
   + 在第三個資料列，建立索引鍵為 **region** 的變數。接著將該值設為您使用 Amazon Pinpoint 的區域，例如 **us-east-1** 或 **us-west-2**。

   完成後，**Environment Variables (環境變數)** 區段應該類似於下圖所示的範例。  
![\[originationNumber、projectId 和區域的環境變數。\]](http://docs.aws.amazon.com/zh_tw/pinpoint/latest/userguide/images/SMS_Reg_Tutorial_LAM_Step1.7.png)

1. 在頁面頂端選擇 **Save (儲存)**。

### 測試函數
<a name="tutorials-two-way-sms-part-3-create-register-function-test"></a>

建立函數後，您應該對其進行測試，以確保您的正確設定。此外請確認您建立的 IAM 角色具有適當的許可。

**若要測試函數**

1. 選擇**測試**標籤。

1. 選擇**建立新事件**，執行下列動作：
   + 針對 **Event name (事件名稱)**，輸入測試事件的名稱，例如 **MyPhoneNumber**。
   + 在程式碼編輯器中清除範例程式碼。貼上以下程式碼：

     ```
     {
       "destinationNumber": "+12065550142",
       "firstName": "Carlos",
       "lastName": "Salazar",
       "source": "Registration form test"
     }
     ```
   + 在上述程式碼範例中，將 `destinationNumber`, `firstName` 和 `lastName` 屬性替換為您想用於測試的值，例如您的個人聯絡詳細資訊。測試此函數時，函數會傳送簡訊到您在 `destinationNumber` 屬性中指定的電話號碼。請確定您指定的電話號碼可以接收簡訊。
   + 選擇**建立**。

1. 選擇**測試**。

1. 在 **Execution result: succeeded (執行結果：成功)** 下方，選擇 **Details (詳細資訊)**。在 **Log output (記錄輸出)** 區段，檢閱函數的輸出。確定函數執行沒有發生錯誤。

   檢查與您指定之 `destinationNumber` 關聯的裝置，確定它有收到測試訊息。

1. 開啟位於 [https://console.aws.amazon.com/pinpoint/](https://console.aws.amazon.com/pinpoint/) 的 Amazon Pinpoint 主控台。

1. **在所有專案**頁面上，選擇您在[建立 Amazon Pinpoint 專案中建立的專案](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-create-project)。

1. 在導覽窗格中，選擇 **Segments (客群)**。在 **Segments (客群)** 頁面，選擇 **Create a segment (建立客群)**。

1. 在 **Segment group 1 (客群群組 1)** 的 **Add filters to your segment (新增篩選條件來精簡客群)** 中，選擇 **Filter by user (依使用者篩選)**。

1. 對於 **Choose a user attribute (選擇使用者屬性)**，選擇 **FirstName**。然後，對於 **Choose values (選擇值)**，選擇您在測試事件中指定的名字。

   **Segment estimate (客群估計)** 區段應該會顯示有零個符合資格的端點、一個總端點，如下圖所示。這個結果是正常的。當函數建立新的端點時，端點會選擇退出。Amazon Pinpoint 中的客群會自動排除已選擇不接收的端點。  
![\[區段群組顯示零端點。\]](http://docs.aws.amazon.com/zh_tw/pinpoint/latest/userguide/images/SMS_Reg_Tutorial_LAM_Step8.9.png)

## 建立函數以將客戶選擇加入您的通訊
<a name="tutorials-two-way-sms-part-3-create-optin-function"></a>

只有當客戶回覆由第一個函數傳送的訊息時，才會執行第二個函數。如果客戶的回覆包含您在[啟用雙向 SMS](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-set-up-channel) 中指定的關鍵字，則函數會更新其端點記錄，以選擇加入未來的通訊。Amazon Pinpoint 也會自動回應您在[啟用雙向簡訊](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-set-up-channel)中指定的訊息。

如果客戶不回應或回應指定關鍵字以外的其他內容，則不會發生任何事。客戶的端點仍在 Amazon Pinpoint 中，但不能被客群鎖定。

**建立 Lambda 函數**

1. 在 https：//[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) 開啟 AWS Lambda 主控台。

1. 選擇**建立函數**。

1. 在 **Create function (建立函數)** 下方，選擇 **Blueprints (藍圖)**。

1. 在搜尋欄位中，輸入 **hello**，然後按 Enter 鍵。在結果清單中，選擇 `hello-world` Node.js 函數，如下圖所示。選擇**設定**。

1. 在**基本資訊**下，請執行下列動作：
   + 對於 **Name (名稱)**，輸入函數的名稱，例如 **RegistrationForm\$1OptIn**。
   + 針對 **Role (角色)**，請選擇 **Choose an existing role (選擇現有的角色)**。
   + 針對**現有角色**，選擇您在建立 IAM 角色中建立的 SMSRegistrationForm 角色。 [建立 IAM 角色](tutorials-two-way-sms-part-2.md#tutorials-two-way-sms-part-2-create-role)

   完成後，請選擇 **Create function (建立函數)**。

1. 在程式碼編輯器中刪除範例函數，然後貼上以下程式碼：

   ```
   import { PinpointClient, UpdateEndpointCommand } from "@aws-sdk/client-pinpoint"; // ES Modules import
   
   // Create a new Pinpoint client instance with the region specified in the environment variables
   const pinClient = new PinpointClient({ region: process.env.region });
   
   // Get the Pinpoint project ID and the confirm keyword from environment variables
   const projectId = process.env.projectId;
   const confirmKeyword = process.env.confirmKeyword.toLowerCase();
   
   // This is the main handler function that is invoked when the Lambda function is triggered
   export const handler = async (event, context) => {
       console.log('Received event:', event);
   
       try {
           // Extract the timestamp, message, and origination number from the SNS event
           const timestamp = event.Records[0].Sns.Timestamp;
           const message = JSON.parse(event.Records[0].Sns.Message);
           const originationNumber = message.originationNumber;
           const response = message.messageBody.toLowerCase();
   
           // Check if the response message contains the confirm keyword
           if (response.includes(confirmKeyword)) {
               // If the confirm keyword is found, update the endpoint's opt-in status
               await updateEndpointOptIn(originationNumber, timestamp);
           }
       }catch (error) {
           console.error('An error occurred:', error);
           throw error; // Rethrow the error to handle it upstream
       }
   };
   
   // This function updates the opt-in status of a Pinpoint endpoint
   async function updateEndpointOptIn(originationNumber, timestamp) {
       // Extract the endpoint ID from the origination number
       const endpointId = originationNumber.substring(1);
   
        // Prepare the parameters for the UpdateEndpointCommand
       const params = {
           ApplicationId: projectId,
           EndpointId: endpointId,
           EndpointRequest: {
               Address: originationNumber,
               ChannelType: 'SMS',
               OptOut: 'NONE',
               Attributes: {
                   OptInTimestamp: [timestamp]
               },
           }
       };
   
       try {
           // Send the UpdateEndpointCommand to update the endpoint's opt-in status
           const updateEndpointResponse = await pinClient.send(new UpdateEndpointCommand(params));
           console.log(updateEndpointResponse);
           console.log(`Successfully changed the opt status of endpoint ID ${endpointId}`);
       } catch (error) {
           console.error('An error occurred while updating endpoint:', error);
           throw error; // Rethrow the error to handle it upstream
       }
   }
   ```

1. 在 **Environment variables (環境變數)** 下，執行下列動作：
   + 在第一個資料列，建立索引鍵為 **projectId** 的變數。接著，將值設定為您在[建立 Amazon Pinpoint ](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-create-project)專案中建立之專案的唯一 ID。
   + 在第二個資料列，建立索引鍵為 **region** 的變數。接著將該值設為您使用 Amazon Pinpoint 的區域，例如 **us-east-1** 或 **us-west-2**。
   + 在第三個資料列，建立索引鍵為 **confirmKeyword** 的變數。接著，將值設定為您在[啟用雙向簡訊](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-set-up-channel)中建立的確認關鍵字。
**注意**  
關鍵字不區分大小寫。此函數會將傳入訊息轉換為小寫字母。

   完成後，**Environment Variables (環境變數)** 區段應該類似於下圖所示的範例。  
![\[projectId、region 和 confirmKeyword 的環境變數。\]](http://docs.aws.amazon.com/zh_tw/pinpoint/latest/userguide/images/SMS_Reg_Tutorial_LAM_Step2.7.png)

1. 在頁面頂端選擇 **Save (儲存)**。

### 測試函數
<a name="tutorials-two-way-sms-part-3-create-optin-function-test"></a>

建立函數後，您應該對其進行測試，以確保您的正確設定。此外請確認您建立的 IAM 角色具有適當的許可。

**若要測試函數**

1. 選擇**測試**。

1. 在 **Configure test event (設定測試事件)** 視窗中，執行以下操作：

   1. 選擇 **建立新測試事件**。

   1. 針對 **Event name (事件名稱)**，輸入測試事件的名稱，例如 **MyResponse**。

   1. 在程式碼編輯器中清除範例程式碼。貼上以下程式碼：

      ```
      {
        "Records":[
          {
            "Sns":{
              "Message":"{\"originationNumber\":\"+12065550142\",\"messageBody\":\"Yes\"}",
              "Timestamp":"2019-02-20T17:47:44.147Z"
            }
          }
        ]
      }
      ```

      在上述程式碼範例中，將 `originationNumber` 屬性的值替換成您在測試舊 Lambda 函數時使用的電話號碼。將 的值取代`messageBody`為您在[啟用雙向 SMS 中指定的雙向 SMS ](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-enable-two-way)關鍵字。或者，您也可以將 `Timestamp` 的值替換為目前的日期和時間。

   1. 選擇**建立**。

1. 再次選擇 **Test (測試)**。

1. 在 **Execution result: succeeded (執行結果：成功)** 下方，選擇 **Details (詳細資訊)**。在 **Log output (記錄輸出)** 區段，檢閱函數的輸出。確定函數執行沒有發生錯誤。

1. 開啟位於 [https://console.aws.amazon.com/pinpoint/](https://console.aws.amazon.com/pinpoint/) 的 Amazon Pinpoint 主控台。

1. **在所有專案**頁面上，選擇您在[建立 Amazon Pinpoint 專案中建立的專案](tutorials-two-way-sms-part-1.md#tutorials-two-way-sms-part-1-create-project)。

1. 在導覽窗格中，選擇 **Segments (客群)**。在 **Segments (客群)** 頁面，選擇 **Create a segment (建立客群)**。

1. 在 **Segment group 1 (客群群組 1)** 的 **Add filters to your segment (新增篩選條件來精簡客群)** 中，選擇 **Filter by user (依使用者篩選)**。

1. 對於 **Choose a user attribute (選擇使用者屬性)**，選擇 **FirstName**。然後，對於 **Choose values (選擇值)**，選擇您在測試事件中指定的名字。

   **Segment estimate (客群估計)** 區段應該會顯示有一個符合資格的端點，以及一個總端點。

**下一步**：[設定 Amazon API Gateway](tutorials-two-way-sms-part-4.md)