Notifications // Alexa Skills Proactive Events API

Hello everyone, in this advanced tutorial we will create a skill that will allow us to receive but also send notifications to users with Voiceflow.

WHAT IS PROACTIVE EVENTS?

For those who discover notifications and more particularly the Proactive events API with Alexa, here is a video to explain what it is all about.

After this video you will have understood a bit more the Proactive Events API and the differents event schemas (type of notifications) Amazon provides us.

For this tutorial we will start with the example of a Quiz type skill so the schema that interests us here will be the AMAZON.MediaContent.Available

Feel free to browse the documentation to select the schema that best suits your use.

AMAZON.WeatherAlert.Activated
AMAZON.SportsEvent.Updated
AMAZON.MessageAlert.Activated
AMAZON.OrderStatus.Updated
AMAZON.Occasion.Updated
AMAZON.TrashCollectionAlert.Activated
AMAZON.MediaContent.Available
AMAZON.SocialGameInvite.Available

THE IDEA

The idea of our project will be to inform our users of the availability of a new Quiz.
To ensure that the tutorial is not too long, we will not create the Quiz part here but only the notification logic.
To do this, we will configure our skill to accept notifications and create the code that will allow us to send a notification to all our users from our skill.

ADDING SKILL EVENTS TO THE SKILL MANIFEST

After you have created your project in Voiceflow, click on the settings icon in the top bar.

30%20PM

Then, click on the Advanced tab in the popup window

13%20PM

Then paste this code in the Skill Events field:

{
      "publications": [
         {
          "eventName": "AMAZON.MediaContent.Available"
        }
      ],
      "endpoint": {
        "uri": "https://voiceflow.app/state/skill/{version}",
        "sslCertificateType": "Wildcard"
      },
      "subscriptions": [
        {
          "eventName": "SKILL_PROACTIVE_SUBSCRIPTION_CHANGED"
        }
      ]
}

13%20PM

To better understand what we use here, you can read Amazon’s documentation on how to define proactive events with SMAPI

https://developer.amazon.com/docs/smapi/proactive-events-api.html#onboard-smapi

The part we add to our manifest skill is framed on the next capture.

As you can see, you can add several types of events (eventName) and we also need to specify an endpoint.
The endpoint is the url from which your skill is available.
In Voiceflow this endpoint changes each time you click on the upload to Alexa button so to set the correct one we need to use the {version} variable here:

"uri": "https://voiceflow.app/state/skill/{version}",

and, as we are using a custom endpoint, we also need to add the sslCertificateType:

"sslCertificateType": "Wildcard"

Once this code is added to our skill manifest, we will be able to start creating our project.

CREATING THE PROJECT

We start by adding the part that will check if the user has enabled or not the notifications for our skill.
To do this, we use the User Info block, the Permission block and a Speak block to inform the user why we are requesting access to notifications and how to activate them.

50%20PM

So let’s add our User Info block first and choose Notifications in the drop-down menu.

38%20PM

The next block (Permission) does not require any special configuration.

Finally add the speak block.

Here is the text I used for this project.

In order to be informed of the availability of a new quiz you must allow us to send you notifications. To do this, please open your Alexa mobile application or go to alexa.amazon.com <break time="0.5s"/>

When you have authorized the skill, launch it again saying "Alexa, open yourskillname".

Of course, you can modify this text as you wish, but keep in mind that you must clearly explain the reason(s) for this authorization request to the user.

Let’s finish the first part of our skill with another Speak block after the user info block to inform that our skill is ready to receive notifications.

THE NOTIFICATION PART

Now that we have configured our skill to receive notifications, we will add a mode that will allow us to send a notification in order to test that everything works correctly.

To do this, we will add an Intent block to use the one-shot invocation feature. To put it simply, this will allow us to launch our skill with a command like: “Alexa, launch myskillname for notification”.

So we start by adding an Intent block intent, it is this that will handle the one-shot invocation.

In the configuration of this block, we add different intents. For this example, I will use “notification”, “notifications”, “send notification” and “send notifications” but you can use the intents that best match your needs.

Once again, this will allow us to directly launch the part of our skill that is related to our Intent block. “Alexa, ask myskillname to send notifications”.

57%20PM

Just after our Intent block, we add a Speak block to ask the user for confirmation.

Then you probably know the following, we add an Interaction block to manage the answer (Yes or No) thanks to Amazon.YesIntent and Amazon.NoIntent

02%20PM

This is just a confirmation not to send a notification by mistake. You can also add a verification by code using a new Interaction block and new intent for the code.

THE API PART

Now we enter the more complex part, we will add an Integration block to make a first API call.

So add an Integration block, select API and for the settings, use the following information:

I wan to make a POST request
With settings, URL:

https://api.amazon.com/auth/o2/token

And add the following header:

Content-Type: application/x-www-form-urlencoded

For the Mapping output part, we are going to receive an access_token from this call so let’s use the default access_token variable already available in Voiceflow.

Before continuing even further, upload your skill to Alexa. We will need information that we can only get after a first upload.

!05%20PM

Once your skill has been uploaded, follow the link to ADC (Alexa Developer Console). Click on the Build tab, and go to the Permissions section.

00%20PM

At the very bottom of the page, you should have access to two information in the Alexa Skill Messaging section.

Client Id and Client Secret.

Copy these two pieces of information into a document, we’ll need it right after. If the Client Secret is not visible, click on SHOW to display it.

Let’s go back to our Interaction block and add this information in the Body part of our request. Don’t forget to select the Form Url-Encoded format here.

As you can see on this screenshot, we will have to add four elements here.
The first and last are the default settings.

grant_type: client_credentials
scope: alexa::proactive_event

client_id and client_secret are the two pieces of information you just got from ADC.

This is it for the token recovery part, thanks to this API call, Alexa returns us a token that will allow us to send a notification.

MAKING THE DATA

Now, we will need a Code block to generate the data we need to add to the content of our notification.
If we go back to the Amazon documentation link, we can see that our request must contain a lot of information.

https://developer.amazon.com/docs/smapi/schemas-for-proactive-events.html#media-content


image

Here is the JSON code we will send:

{
  "timestamp": "{now}",
  "referenceId": "{referenceId}",
  "expiryTime": "{expiryTime}",
   "event":  {
      "name": "AMAZON.MediaContent.Available",
      "payload": {
        "availability": {
          "startTime": "{now}",
          "provider": {
            "name": "localizedattribute:providerName"
          },
          "method": "RELEASE"
        },
        "content": {
          "name": "localizedattribute:contentName",
          "contentType": "GAME"
        }
      }
    },
     "localizedAttributes": [
      {
        "locale": "en-US",
        "providerName": "the Skill Quiz.",
        "contentName": "A new quiz"
      }
    ],
   "relevantAudience": {
    "type": "Multicast",
    "payload": {}
   }
}

We will, therefore, have to generate a timestamp, a random reference id and an expiration time.

"timestamp": "{now}"
"referenceId": "{referenceId}"
"expiryTime": "{expiryTime}"

So let’s add our Code block and copy/paste this code inside.

// Random String
const length = 20;
const randomString = [...Array(length)]
  .map(() => Math.random().toString(36)[5])
  .join("");
referenceId = randomString;

// Contents of above date object is 
// converted into a string using toISOString() function. 
var dateobj = new Date(); 
now = dateobj.toISOString();
//dateobj = new Date();
dateobj.setHours(dateobj.getHours() + 24);
expiryTime = dateobj.toISOString();

Don’t forget to add the following variables in Voiceflow:
referenceId
now
expiryTime

image

Your Code block should look like something like this.

34%20PM

I’m not going to go into the details, but to make it simple:

// Random String
const length = 20;
const randomString = [...Array(length)]
  .map(() => Math.random().toString(36)[5])
  .join("");
referenceId = randomString;

allows generating a random id of 20 characters.

And:

var dateobj = new Date(); now = dateobj.toISOString(); //dateobj = new Date(); dateobj.setHours(dateobj.getHours() + 24); expiryTime = dateobj.toISOString();

This code allows you to obtain the date in the format desired by Amazon as well as an expiryTime at +24 hours from the current time.

SEND OUR NOTIFICATION

The last step of this tutorial is to send the notification using all the information we have obtained. To send the request, again we use the Integration block.
Here is the configuration information you will need to enter.

For the URL part, know that depending on the region and mode (Dev or Prod), the endpoint will change:

Development
https://api.amazonalexa.com/v1/proactiveEvents/stages/development (North America)
https://api.eu.amazonalexa.com/v1/proactiveEvents/stages/development (Europe)
https://api.fe.amazonalexa.com/v1/proactiveEvents/stages/development (Far East)

Production
https://api.amazonalexa.com/v1/proactiveEvents/ (North America)
https://api.eu.amazonalexa.com/v1/proactiveEvents/ (Europe)
https://api.fe.amazonalexa.com/v1/proactiveEvents/ (Far East)

For this tutorial, I assume that we are testing a US skill in development mode.

We also use the Content-Type: application/json and the acces_token variable that we retrieved from our first API call for the Authorization header.

Finally, for the Body, this time we use the Raw Input to send our JSON.

{
  "timestamp": "{now}",
  "referenceId": "{referenceId}",
  "expiryTime": "{expiryTime}",
   "event":  {
      "name": "AMAZON.MediaContent.Available",
      "payload": {
        "availability": {
          "startTime": "{now}",
          "provider": {
            "name": "localizedattribute:providerName"
          },
          "method": "RELEASE"
        },
        "content": {
          "name": "localizedattribute:contentName",
          "contentType": "GAME"
        }
      }
    },
     "localizedAttributes": [
      {
        "locale": "en-US",
        "providerName": "the Quiz Skill",
        "contentName": "A new quiz"
      }
    ],
   "relevantAudience": {
    "type": "Multicast",
    "payload": {}
   }
}

All you have to do now is add two Speak blocks, one in case of success and another one in case of error and you are ready to test your skill.

25%20PM

CONCLUSION

Congratulations, you have learned the basics of the Proactive events API. Don’t forget to allow notifications in your Alexa application or on alexa.amazon.com to test this project.

This is awesome! Thanks Nicolas

This is very powerful !
Can’t wait to add it to my project.