本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
建立 Lambda 函數以搭配 Amazon Pinpoint SMS 訊息使用
本節說明如何建立和設定兩個 Lambda 函數,以搭配 Amazon Pinpoint SMS 訊息使用。稍後,您可以設定 API Gateway 和 Amazon Pinpoint,在特定事件發生時調用這些函數。這兩個函數都會在您指定的 Amazon Pinpoint 專案中建立和更新端點。第一個函數也會使用電話號碼驗證功能。
第一個函數會從註冊表單取得輸入,該表單會從 Amazon API Gateway 接收。它使用此資訊,透過使用 Amazon Pinpoint 的電話號碼驗證功能,取得客戶電話號碼的相關資訊。接著函數使用驗證過的資料,在您指定的 Amazon Pinpoint 專案中建立新端點。在預設情況下,函數建立的端點會選擇退出您未來的通訊,但您可以在第二個函數中變更此狀態。最後,此函數會向客戶傳送一則訊息,要求他們驗證是否想要接收來自您的SMS通訊。
建立 Lambda 函數
在 開啟 AWS Lambda 主控台https://console.aws.amazon.com/lambda/
。 -
選擇建立函數。
-
在建立函數 下,選擇使用藍圖 。
-
在搜尋欄位中,輸入
hello
,然後按 Enter 鍵。在結果清單中,選擇hello-world
Node.js 函數,如下圖所示。 -
在基本資訊下,請執行下列動作:
-
對於 Name (名稱),輸入函數的名稱,例如
RegistrationForm
。 -
針對 Role (角色),請選擇 Choose an existing role (選擇現有的角色)。
-
針對現有角色 ,選擇您在建立SMSRegistrationForm角色 中建立的角色。 IAM
完成後,請選擇 Create function (建立函數)。
-
-
對於程式碼來源,請在程式碼編輯器中刪除範例函數,然後貼上下列程式碼:
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); } }
-
在環境變數 的組態索引標籤上,選擇編輯,然後選擇新增環境變數 ,執行下列動作:
完成後,Environment Variables (環境變數) 區段應該類似於下圖所示的範例。
-
在頁面頂端選擇 Save (儲存)。
測試函數
建立函數後,您應該對其進行測試,以確保您的正確設定。此外,請確定您建立IAM的角色具有適當的許可。
若要測試函數
-
選擇測試標籤。
-
選擇建立新事件 ,執行下列動作:
-
針對 Event name (事件名稱),輸入測試事件的名稱,例如
MyPhoneNumber
。 -
在程式碼編輯器中清除範例程式碼。貼上以下程式碼:
{ "destinationNumber": "
+12065550142
", "firstName": "Carlos
", "lastName": "Salazar
", "source": "Registration form test" } -
在上述程式碼範例中,將
destinationNumber
,firstName
和lastName
屬性替換為您想用於測試的值,例如您的個人聯絡詳細資訊。當您測試此函數時,它會SMS傳送訊息至您在destinationNumber
屬性中指定的電話號碼。請確定您指定的電話號碼能夠接收SMS訊息。 -
選擇 Create (建立)。
-
-
選擇 測試。
-
在 Execution result: succeeded (執行結果:成功) 下方,選擇 Details (詳細資訊)。在 Log output (記錄輸出) 區段,檢閱函數的輸出。確定函數執行沒有發生錯誤。
檢查與您指定之
destinationNumber
關聯的裝置,確定它有收到測試訊息。 在 開啟 Amazon Pinpoint 主控台https://console.aws.amazon.com/pinpoint/
。 -
在所有專案頁面上,選擇您在建立 Amazon Pinpoint 專案 中建立的專案。
-
在導覽窗格中,選擇 Segments (客群)。在 Segments (客群) 頁面,選擇 Create a segment (建立客群)。
-
在 Segment group 1 (客群群組 1) 的 Add filters to your segment (新增篩選條件來精簡客群) 中,選擇 Filter by user (依使用者篩選)。
-
針對選擇使用者屬性 ,選擇 FirstName。然後,對於 Choose values (選擇值),選擇您在測試事件中指定的名字。
Segment estimate (客群估計) 區段應該會顯示有零個符合資格的端點、一個總端點,如下圖所示。這個結果是正常的。當函數建立新的端點時,端點會選擇退出。Amazon Pinpoint 中的客群會自動排除已選擇不接收的端點。
只有當客戶回覆由第一個函數傳送的訊息時,才會執行第二個函數。如果客戶的回覆包含您在啟用雙向 SMS中指定的關鍵字,則函數會更新其端點記錄,以選擇加入未來的通訊。Amazon Pinpoint 也會自動回應您在啟用雙向 SMS中指定的訊息。
如果客戶不回應或回應指定關鍵字以外的其他內容,則不會發生任何事。客戶的端點仍在 Amazon Pinpoint 中,但不能被客群鎖定。
建立 Lambda 函數
在 開啟 AWS Lambda 主控台https://console.aws.amazon.com/lambda/
。 -
選擇建立函數。
-
在 Create function (建立函數) 下方,選擇 Blueprints (藍圖)。
-
在搜尋欄位中,輸入
hello
,然後按 Enter 鍵。在結果清單中,選擇hello-world
Node.js 函數,如下圖所示。選擇設定。 -
在基本資訊下,請執行下列動作:
-
對於 Name (名稱),輸入函數的名稱,例如
RegistrationForm_OptIn
。 -
針對 Role (角色),請選擇 Choose an existing role (選擇現有的角色)。
-
針對現有角色 ,選擇您在建立SMSRegistrationForm角色 中建立的角色。 IAM
完成後,請選擇 Create function (建立函數)。
-
-
在程式碼編輯器中刪除範例函數,然後貼上以下程式碼:
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 } }
-
在 Environment variables (環境變數) 下,執行下列動作:
-
在第一個資料列,建立索引鍵為
projectId
的變數。接下來,將值設定為您在建立 Amazon Pinpoint 專案 中建立的專案的唯一 ID。 -
在第二個資料列,建立索引鍵為
region
的變數。接著將該值設為您使用 Amazon Pinpoint 的區域,例如us-east-1
或us-west-2
。 -
在第三個資料列,建立索引鍵為
confirmKeyword
的變數。接下來,將 值設定為您在啟用雙向 SMS中建立的確認關鍵字。注意
關鍵字不區分大小寫。此函數會將傳入訊息轉換為小寫字母。
完成後,Environment Variables (環境變數) 區段應該類似於下圖所示的範例。
-
-
在頁面頂端選擇 Save (儲存)。
測試函數
建立函數後,您應該對其進行測試,以確保您的正確設定。此外,請確定您建立IAM的角色具有適當的許可。
若要測試函數
-
選擇 測試。
-
在 Configure test event (設定測試事件) 視窗中,執行以下操作:
-
選擇 建立新測試事件。
-
針對 Event name (事件名稱),輸入測試事件的名稱,例如
MyResponse
。 -
在程式碼編輯器中清除範例程式碼。貼上以下程式碼:
{ "Records":[ { "Sns":{ "Message":"{\"originationNumber\":\"
+12065550142
\",\"messageBody\":\"Yes
\"}", "Timestamp":"2019-02-20T17:47:44.147Z" } } ] }在上述程式碼範例中,將
originationNumber
屬性的值替換成您在測試舊 Lambda 函數時使用的電話號碼。將 的值取代messageBody
為您在啟用雙向 中指定的雙向SMSSMS關鍵字。或者,您也可以將Timestamp
的值替換為目前的日期和時間。 -
選擇 Create (建立)。
-
-
再次選擇 Test (測試)。
-
在 Execution result: succeeded (執行結果:成功) 下方,選擇 Details (詳細資訊)。在 Log output (記錄輸出) 區段,檢閱函數的輸出。確定函數執行沒有發生錯誤。
在 開啟 Amazon Pinpoint 主控台https://console.aws.amazon.com/pinpoint/
。 -
在所有專案頁面上,選擇您在建立 Amazon Pinpoint 專案 中建立的專案。
-
在導覽窗格中,選擇 Segments (客群)。在 Segments (客群) 頁面,選擇 Create a segment (建立客群)。
-
在 Segment group 1 (客群群組 1) 的 Add filters to your segment (新增篩選條件來精簡客群) 中,選擇 Filter by user (依使用者篩選)。
-
針對選擇使用者屬性 ,選擇 FirstName。然後,對於 Choose values (選擇值),選擇您在測試事件中指定的名字。
Segment estimate (客群估計) 區段應該會顯示有一個符合資格的端點,以及一個總端點。