AWS Mobile Blog

Targeted push notifications and campaign management using Amazon Pinpoint and React Native

by Richard Threlkeld | on | in AWS Mobile, Lambda | | Comments

This post was authored by Michael Labieniec, AWS Solutions Architect

Amazon Pinpoint makes it easy to run targeted campaigns to drive user engagement with mobile apps. Using Amazon Pinpoint you can understand user behavior, determine which users to engage with your campaigns, determine which messages to send, schedule the best time to deliver the messages, and then track the results of your campaign. Building cross-platform mobile apps and engaging with users across these platforms can be challenging; it requires you to maintain multiple code bases to take advantage of native features using the AWS Mobile SDK.

React Native enables you to create cross-platform mobile apps while utilizing native features. By building custom native modules, you can interact with the native AWS Mobile SDK generated by AWS Mobile Hub. This means that you maintain a single code base, while customizing the look and feel per platform within React Native. In this example, we will show how to build a native module for the Android platform. The same concepts can be applied to iOS by building a custom module and using the Mobile Hub-generated package.

In this tutorial, you generate a Mobile Hub app that uses an unauthenticated Amazon Cognito identity pool and interacts with API Gateway and AWS Lambda. This app allows you to purchase round trip tickets to your favorite planet. The app generates monetization events using the native AWS Mobile SDK. It then creates custom user attributes for Amazon Pinpoint so you can engage with users based on their planet interest, traveled to destination, and weather preference. To add user authentication along with features such as registration and MFA, consider using the Amazon Cognito User Pools functionality, which you can enable in Mobile Hub.

Requirements

Clone the completed sample app from Github and use the files within this repository as reference when creating your app.

git clone https://github.com/awslabs/aws-pinpoint-sample

Once you have node.js and npm, you can get started by running the following commands from the terminal:

npm install -g react-native-cli
react-native init PinpointSample
cd PinpointSample

NOTE: If you name your project something other than “PinpointSample”, you will need to find/replace the  references in the sample code with your new project name.

Creating the API for your cross-platform app

Go to the AWS Mobile Hub console and click Create new mobile project. In this example for this tutorial, the app name is PinpointSample. Enter the name then click “Create Project”. In the list of features, choose Cloud Logic and then choose Create new API. Give the API a name PinpointSampleApi and a description, leave the defaults, and choose Create API. This API will simply return back whatever you send to it in the request body. You will use this API later in this tutorial to simulate requesting weather information for specific planets.

CREATE_IN_PROGRESS appears while the APIs are being created. When the status is CREATE_COMPLETE, choose “Configure more features”.

image005

Getting a GCM Sender ID and API Key

To send push notifications to Android devices, you need Google Cloud Messaging keys. To create a new Sender ID and API Key, go to https://firebase.google.com.

  • Choose an existing project or create a new project.
  • Click Add (another) app and select Android

Type your package name from the generated React Native app. In this example, it’s com.pinpointsample. Then click Add App. Click Continue and then Finish. Note, you don’t need the google.json file.

Click the menu icon to the right of your new app’s name and then choose Manage Settings. Choose the CLOUD MESSAGING tab. Copy the Sender ID and Legacy Server Key (this is the API Key).

Enabling User Engagement

In the AWS Mobile Hub console, choose User Engagement and then choose Enable engagement and select Android

  • In Sender ID, add the Sender ID from the previous procedure.
  • In API Key, add the Server Key from the previous procedure.

Click Save changes then choose Integrate with your app. Next choose the Android tab, and then choose Download package.

image009

Find the directory where you created your project earlier with the React Native CLI. Inside that directory, extract the amazonaws folder from the Mobile Hub package archive you downloaded from Mobile Hub to android/app/src/main/java/com/amazonaws. Overwrite the existing directory (if it exists).

image010

Creating the React Native Android Module

Open projectname/android/app/build.gradle with a text editor and add the following dependencies. The Google Play library is required to use push notifications. The included badge library places a badge next to your push notifications.

dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile 'com.android.support:support-v4:23.1.0'
    compile "com.facebook.react:react-native:+"  // From node_modules
    compile "me.leolin:ShortcutBadger:1.1.4@aar"
    compile 'com.amazonaws:aws-android-sdk-core:2.3.9'
    compile('com.amazonaws:aws-android-sdk-pinpoint:2.3.9')
    compile('com.amazonaws:aws-android-sdk-apigateway-core:2.3.9')
    compile 'com.google.android.gms:play-services-gcm:7.8.0'
    compile 'com.google.code.gson:gson:2.7'
}

Create 3 new files in the android/app/src/main/java/com/pinpointsample package folder. Copy the contents of the files from the corresponding sample app repository files.

  • AWSMobileHubModule.java
  • AWSMobileHubPackage.java
  • AWSPushListenerService.java

Next, update your android/app/src/main/AndroidManifest.xml. Copy the contents from the sample app repository. If you did not use the example package name of com.pinpointsample, be sure to update the package names in the manifest file to your package name.

Note: The package names must match your application package name.

In the android/app/src/main/com/amazonaws/mobile/AWSConfiguration.java file, remove the “final” from all variables. These variables will be updateable from the JavaScript interface.

Note: If you update your Mobile Hub app in the future, you mustoverwrite the com.amazonaws.mobile package folder and will need to perform this step again if you want to be able to configure the variables from javascript.

Finally, modify the MainApplication.java file to load your new package. Add import com.pinpointsample.AWSMobileHubPackage; to the imports section of the class, then update the getPackages() method to include the module:

@Override
    protected List getPackages() {
      return Arrays.asList(
          new MainReactPackage(),
          new AWSMobileHubPackage()
      );
    }

Add your configuration to the constructor method in by copying the contents of the index.android.js from the sample code into your projects index.android.js. The values can be copied from your Mobile Hub generated AWSConfiguration.java file class (where you previously removed the “final” statement).

Finally, create a AWSMobileHub.js file in your projects root directory. this is the main interface that communicates with our native module. Copy the contents from the completed sample app repository file.

Note: the name of the module corresponds directly to the getName property inside the java module code getName() method.

Finally, enable the gradle daemon to speed up builds; run this command from your terminal on your Mac or Linux computer.

touch ~/.gradle/gradle.properties && echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties

Now, run the app either on a device (push notifications may not work on the Android Emulator). From your root project run the following command:

react-native run-android
adb logcat

image011

The following information is logged to adb logcat:

Note: use the logcat.sh script in the sample app repository to automatically filter your adb logs with ./logcat.sh (on mac/linux) or just “logcat” on windows.

  • AWSMobileClient: AWS Mobile Client is OK – This means the AWS Mobile SDK was initiated
  • EventRecorder: Successful submission of 1 events – These events are being submitted to Pinpoint
  • TargetingClient: EndpointProfile – These are Amazon Pinpoint events

Within the app, when you choose the Request Weather button, you see a request to Amazon API Gateway. This request calls an AWS Lambda function, which simply returns the request. The app echoes the query parameter that was sent; in this case, the weather for the selected planet.

The API Gateway call can be used to send any request to API Gateway by passing in the method, endpoint, request body, and query params (see comments in the sample code). This call uses the Amazon Cognito identity, which in this example is an unauthenticated user. You can instead use a login system with an authenticated role and the SDK manages that for you. This call also sets custom attributes for the Weather Requested attribute so that you can engage with specific users that requested weather for a specific planet by creating a custom user segment within Amazon Pinpoint.

Next, choose Planet Trip, {COST}. The event echoes out in the adb log, which creates a monetization event using the AWS Mobile SDK. This event also updates custom attributes about this user under the Traveled To attribute, which enables you to engage with users who have traveled to this specific planet.

Enabling Campaign Management with Amazon Pinpoint

Next we are going to create user segments for each of the planet attributes users are interested in traveling to. Then we will create a campaign that targets these specific users based on their interests.

Go to the Amazon Pinpoint console and click on your app (if you used “PinpointSample” as the name of your Mobile Hub app, your Pinpoint app should be called “pinpointsample_MobileHub”), choose Segments, and then choose New Segment. Name your segment after a planet that you selected within the app; for example, “Earth People” if, in the app, you purchased a trip to Earth by clicking “Planet Trip”. Choose the + button under Custom Attributes, choose Planet and then choose Earth. This enables you to engage with all users that picked Earth in the app. You can also specify a usage metric; for example, Used within the last 30 days. The user count goes to 1 and shows 100%. This indicates that all current users are interested in this planet.

image013

Next, choose Campaigns, and then choose Create Campaign. Choose the segment that you created in the previous step by selecting Use a previously defined segment. For this example, the segment is called “Earth People”.

image014

The Segment estimate should be 1 total user. If the Segment estimate is 0, give it some time, refresh the app, and refresh the console. Be sure you see the Endpoint updated successfully event in the logcat log. If you are only running the app on the Android Emulator, try running it on a device instead.

Click Next step, choose Message and type a message. For example, in Title, type “Earth is Awesome”, and in Message, type “Travel to Earth now the weather is great!”

image015

Choose Next step.

image016

In the Advanced section, choose Immediate, and then choose Review and Launch. Choose Launch Campaign and return to the app running on your device. If the app is active the alert popup will display with your message. If your app is minimized, your notification appears in the top area of the screen with any other notifications. You can also see the update in the Amazon Pinpoint console. Tapping your notification will open your app. This behavior can be customized when you create the campaign within Amazon Pinpoint.

image017

Next, in the app, choose another planet. If your terminal is open, you should see a Endpoint updated successfully event display. Go back to the Amazon Pinpoint console. Choose Copy to new campaign. Choose Segment, choose Create a New Segment, and then choose Custom.

In “Customer Attributes” choose Planet and then choose the planet name you chose in the previous step. Repeat the preceding steps to send push notifications to this custom segment.

The custom attributes (attribute,value) can be changed in the index.android.js file’s _customAttributes function. The native module takes a simple comma delimited string as its argument for custom attributes, as follows.

  • @param {String} Attribute name i.e. “Interest”
  • @param {String} Attribute values i.e. “Pizza, Sushi”

You should also now see monetization events if you choose the Planet Trip, $200.00 button in the app. The monetization and usage data is populated in the Amazon Pinpoint console in near real time. When you choose the Planet Trip button in the app, the event is sent via Google Play monetization builder in the native AWS Mobile SDK. You can customize the values in index.android.js method via JavaScript. You can also customize and send more parameters by modifying the AWSMobileHubModule.java file to send details like Transaction ID. You simply need to update the generateMonetizationEvent method appropriately.

Questions or Comments?
Reach out to us on the AWS Mobile Development Forum.

Source Code on GitHub
github.com/awslabs/aws-pinpoint-sample