Add Recommendations to Email campaign

Setup Lambda to process recommendations

In Amazon Pinpoint, you can retrieve personalized recommendations from a recommender model and add them to messages that you send from campaigns and journeys.

By using recommender models with Amazon Pinpoint, you can send personalized recommendations to message recipients based on each recipient’s attributes and behavior. With AWS Lambda, you can also customize and enhance these recommendations. For example, you can dynamically transform a recommendation from a single text value (such as a product name or ID) to more sophisticated content (such as a product name, description, and image). And you can do it in real time, when Amazon Pinpoint sends the message.

We are going to create a Lambda function with Amplify CLI. Later, we are going to set it up to process Personalize response in Pinpoint.

  1. Run this Amplify CLI command:
amplify function add
  • Create Lambda function with name: traveldealsrecommendpinpoint
  • For Do you want to configure advanced settings choose Yes.
  • Choose storage category to configure access (press Space key to select required category).
  • Choose read operations (press Space key to select required operation).
  • Select other options as decribed in the output:
? Select which capability you want to add: Lambda function (serverless function)
? Provide an AWS Lambda function name: traveldealsrecommendpinpoint
? Choose the runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello World

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? Yes
? Do you want to access other resources in this project from your Lambda function? Yes
? Select the category storage
? Storage has 2 resources in this project. Select the one you would like your Lambda to access Deal:@model(appsync)
? Select the operations you want to permit for Deal:@model(appsync) read

You can access the following resource attributes as environment variables from your Lambda function
        API_TRAVELDEALS_DEALTABLE_ARN
        API_TRAVELDEALS_DEALTABLE_NAME
        API_TRAVELDEALS_GRAPHQLAPIIDOUTPUT
        ENV
        REGION
? Do you want to invoke this function on a recurring schedule? No
? Do you want to configure Lambda layers for this function? No
? Do you want to edit the local lambda function now? Yes
Please edit the file in your editor: /traveldeals/amplify/backend/function/traveldealsrecommendpinpoint/src/index.js
? Press enter to continue 
Successfully added resource traveldealsrecommendpinpoint locally.
  1. File for Lambda function will be generated. If your IDE/TextEditor did not open it, open it manually: /traveldeals/amplify/backend/function/traveldealsrecommendpinpoint/src/index.js
  2. Keep generated comments and replace handler code:
/* Amplify Params - DO NOT EDIT
	API_TRAVELDEALS_DEALTABLE_ARN
	API_TRAVELDEALS_DEALTABLE_NAME
	API_TRAVELDEALS_GRAPHQLAPIIDOUTPUT
	ENV
	REGION
Amplify Params - DO NOT EDIT */

exports.handler = async (event) => {
    const AWS = require('aws-sdk');
    const awsConfig = new AWS.Config({region: process.env.REGION});
    const dynamodb = new AWS.DynamoDB(awsConfig);

    const endpoints = event.Endpoints;
    for (const idx in endpoints) {
        const el = endpoints[idx];

        const recommendedItemsPromises = el.RecommendationItems.map(function(id) {
            const dynamodbParams = {
                TableName: process.env.API_TRAVELDEALS_DEALTABLE_NAME,
                Key: { 'id' : { 'S': id } },
                AttributesToGet: [
                    'id',
                    'name'
                ],
            };
            return dynamodb.getItem(dynamodbParams).promise();    
        });
    
        const recommendedItems = await Promise.all(recommendedItemsPromises);

        const ids = [];
        const names = [];

        recommendedItems.forEach(item => {
            ids.push(item.Item.id.S);
            names.push(item.Item.name.S);
        })

        el.Recommendations = {
            'Id': ids,
            'Name': names
        };
    }
    
    return endpoints;
};
  1. Add permission to lambda function to authorize Amazon Pinpoint to invoke the function:
    1. Open traveldeals/amplify/backend/function/traveldealsrecommendpinpoint/traveldealsrecommendpinpoint-cloudformation-template.json
    2. Add LambdaPinpointPersonalizePermission to "Resources" section:
"LambdaPinpointPersonalizePermission": {
    "Type": "AWS::Lambda::Permission",
    "Properties": {
        "FunctionName": {
            "Ref": "LambdaFunction"
        },
        "Action": "lambda:InvokeFunction",
        "Principal": {
            "Fn::Sub": [
                "pinpoint.${region}.amazonaws.com",
                {
                    "region": {
                        "Ref": "AWS::Region"
                    },
                }
            ]
        },
        "SourceArn": {
            "Fn::Sub": [
                "arn:aws:mobiletargeting:${region}:${account}:recommenders/*",
                {
                    "region": {
                    "Ref": "AWS::Region"
                    },
                    "account": {
                    "Ref": "AWS::AccountId"
                    }
                }
            ]
        }
    }
}
  1. Push to Backend changes to the Cloud:
amplify push

Confirm your decision, when prompted.

Connect Pinpoint to Personalize

  1. Open the Pinpoint Console.
  2. In the navigation pane, choose Machine learning models.
  3. Choose Add recommender model.
List of recommenders in Pinpoint
Step 1: Set up model
  1. Set Recommender model name, e.g. traveldeals-recommendations
  2. Under Model configuration:
    1. Set IAM role to Automatically create a role and set name, e.g. traveldeals-recommendations-role
    2. Set Recommender model to recently created Personalize campaign, e.g. traveldeals-recommendations-campaign
  3. Under Settings:
    1. Set Identifier to use for recommendations to User ID
    2. Set Number of recommendations per message to 3
  4. Under Processing method:
    1. Set Processing method to Use a Lambda function and select Lambda function, that was created, e.g.: traveldealsrecommendpinpoint.

Environnment specific resources created by Amplify will have an environment suffix. For example, if you created a lambda function name traveldealsrecommendpinpoint, its version for dev environment will have name traveldealsrecommendpinpoint-dev.

  1. Choose Next.
Set up a new recommender model in Pinpoint
Step 2: Add attributes

Add attributes, which are populate by Lambda function and can be used in Pinpoint template:

Display name Attribute name
Id Id
Name Name
Add attributes for a new recommender
  1. Choose Next.
Step 3: Review and publish
  1. Choose Publish.
Review and publish a new recommender

Update Deal Creation Template

We are going to add recommendations to Email template, used by Campaign that we set up in Email Campaign.

  1. Open the Pinpoint Console.
  2. In the navigation page, choose Message templates.
  3. Choose the template, you are going to update, e.g. signout-template
  4. Choose Edit.
Edit Template
  1. Under Attribute finder and Recommended attributes, choose Connect model.
  2. Choose the model added in Connect Pinpoint to Personalize, e.g.: traveldeals-recommendations. It will show how many recommendations per message are available and what attributes can be used in message template.
Choose a recommender model to connect to template
  1. Choose Connect model.
  2. Update Message to include recommendations:
    1. Set URL values in the template to actual application URL. You can get it in the output of amplify status or in Amplify Console.
    2. Use this code:
<!DOCTYPE html>
    <html lang="en">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
We are sorry to see you go! Our top picks for you: 
<ul>
    <li><a href="https://XXXXXXXXXXXXXXXXXX.amplifyapp.com/deals/{{Recommendations.Id.[0]}}">{{Recommendations.Name.[0]}}</a></li>
    <li><a href="https://XXXXXXXXXXXXXXXXXX.amplifyapp.com/deals/{{Recommendations.Id.[1]}}">{{Recommendations.Name.[1]}}</a></li>
    <li><a href="https://XXXXXXXXXXXXXXXXXX.amplifyapp.com/deals/{{Recommendations.Id.[2]}}">{{Recommendations.Name.[2]}}</a></li>
</ul>
</body>
</html>
Add recommendations to Message template
  1. Choose Update version.
  2. When prompted to update template version, choose Update version.

Testing Email campaign

You can test the campaign by logging out a user. Here is the example of the message that a user will receive:

Example of email with deal recommendations
Another example of email with deal recommendations