Implement Alexa Shopping Actions in Your Skill
Your skill starts the Alexa Shopping flows by using the skill connections interface to hand off the purchase interaction to Alexa. Alexa Shopping tasks start a multi-turn interaction between Alexa and the customer to complete the shopping experience. When the task completes, Alexa invokes your skill to resume the session.
Follow these instructions to implement the hand-over to Alexa and handle the session resume request. For an overview of Alexa Shopping, see Add Alexa Shopping Actions to Your Alexa Skill.
Product identity
Alexa Shopping Actions operate on a common ProductEntity
object that represents a unique product within Amazon. When you invoke the API, you include an Amazon Standard Identification Number (ASIN) to identify the product. The ASIN is a 10-character alphanumeric unique identifier assigned by Amazon for product identification within Amazon.
You can find an ASIN for a product on the product detail page in two locations:
- In the URL for the product detail page in the format
<Domain-Name>/dp/<asin>
- In the product information section
Implement the add-to-cart flow
When you skill invokes the AMAZON.AddToShoppingCart
action, Alexa presents the purchase details of the recommended product and asks for confirmation to add the product to the customer's Cart. The customer can review this item later by visiting the Amazon retail website. The customer doesn't make the purchasing decision during the skill session.
Complete the following steps to implement the Alexa Shopping AMAZON.AddToShoppingCart
action in your skill code.
Send a directive to add a product to a shopping cart
After you ask the customer for permission to add the product to their Cart, you can send the Connections.StartConnection
directive to Alexa with the AMAZON.AddToShoppingCart
payload.
Connections.StartConnection
exits the current skill session. Save any important details for the session before sending the request. Save the information that you need to restore the session in the token
parameter.The following example shows a request to add the specified product to the cart.
/**
* Handler to handle RecommendAndAddToCart.
*/
const RecommendAndAddToCartHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'RecommendAndAddToCart');
},
handle(handlerInput) {
console.log("AmazoRecommendAndAddToCartreceived.");
const speechText = "<Product intro>" +
" Would you like to add this to your cart on Amazon?"
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
/**
* Handler to handle YesAndNoIntentHandler.
*/
const YesAndNoIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.YesIntent'
|| request.intent.name === 'AMAZON.NoIntent');
},
handle(handlerInput) {
const intentName = handlerInput.requestEnvelope.request.intent.name;
console.log("User said : " + intentName);
if (intentName === 'AMAZON.YesIntent') {
var actionText = "Staging item with Amazon"
let actionTask = {
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.AddToShoppingCart/1',
'input': {
'products' : [
{
'asin' : 'ASN1'
}
]
},
'token': 'AddToShoppingCartToken'
};
return handlerInput.responseBuilder
.speak(actionText)
.addDirective(actionTask)
.getResponse();
}
const speechText = "All right. Please come back if you need more product recommendations."
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
};
Handle a session resumed request
Your skill receives the result of the AMAZON.AddToShoppingCart
request as a SessionResumedRequest
response. Implement a handler to receive the response.
The response includes the token
given in the AMAZON.AddToShoppingCart
request.
Use the token
value to restore the previous session of the skill before you invoked the action. Resume the skill based on the result
included in the payload. You can use the result
to alter the skill experience and handle errors.
The following example shows how to handle a session resumed request response.
/**
* Handler to handle SessionResumedRequest.
*/
const SessionResumedRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionResumedRequest';
},
handle(handlerInput) {
// Session attributes and ID are same as previous IntentRequest
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
console.log("sessionAttributes : " + JSON.stringify(sessionAttributes));
const token = handlerInput.requestEnvelope.request.cause.token;
let request = handlerInput.requestEnvelope.request;
let speechText = "Sorry, I had trouble doing what you asked. Please try again.";
if (request.cause) {
const token = request.cause.token;
const status = request.cause.status;
const code = status.code;
const message = status.message;
const payload = request.cause.result;
console.info(`[Shopping Response] ${JSON.stringify(request)}`);
console.info(`[INFO] Shopping Action Result: Code - ${code}, Message - ${message}, Payload - ${payload}`);
switch(code) {
case '200':
if (typeof payload !== "undefined") {
if (payload.code === "AlexaShopping.RetryLaterError") {
speechText = "Looks like there was an issue. Let's get back to the skill.";
} else {
speechText = "I'm sorry, shopping indicated an issue while performing your request. Please try again later.";
console.info(`[INFO] Shopping Action had an issue while performing the request. ${payload.message}`);
}
} else if (token === "AddToShoppingCartToken") {
console.info(`[INFO] Shopping Action: Add to cart action was a success for ${token}.`);
speechText = "Thank you for adding the product to cart.";
}
break;
default :
console.info(`[INFO] Shopping Action: There was a problem performing the shopping action.`);
speechText = "There was a problem adding the item to your cart.";
}
}
return handlerInput.responseBuilder.speak(speechText).getResponse();
},
};
Implement the add-to-list flow
AMAZON.AddToList
Alexa Shopping action is a developer preview and might change as Amazon receives feedback and iterates on the feature. To use this feature, contact your Amazon business representative.When you skill invokes the AMAZON.AddToList
action, Alexa presents details of the recommended product and asks for confirmation to add the product to the customer's Amazon Wish List. The customer can review this item later by visiting the Amazon retail website. Customers can add items to the Wish List even if they don't define customer settings, such as payment method and delivery address.
Complete the following steps to implement the Alexa Shopping AMAZON.AddToList
action in your skill code.
Send a directive to add a product to a list
After you ask the customer for permission to add the product to their Wish List, you can send the Connections.StartConnection
directive to Alexa with the AMAZON.AddToList
payload.
Connections.StartConnection
exits the current skill session. Save any important details for the session before sending the request. Save the information that you need to restore the session in the token
parameter.The following example shows a request to add the specified product to the list.
/**
* Handler to handle RecommendAndAddToList.
*/
const RecommendAndAddToListHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'RecommendAndAddToList');
},
handle(handlerInput) {
console.log("AmazoRecommendAndAddToCartreceived.");
const speechText = "<Product intro>" +
" Would you like to add this to your wish list on Amazon?"
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
/**
* Handler to handle YesAndNoIntentHandler.
*/
const YesAndNoIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.YesIntent'
|| request.intent.name === 'AMAZON.NoIntent');
},
handle(handlerInput) {
const intentName = handlerInput.requestEnvelope.request.intent.name;
console.log("User said : " + intentName);
if (intentName === 'AMAZON.YesIntent') {
var actionText = "Staging item with Amazon"
let actionTask = {
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.AddToList/1',
'input': {
'products' : [
{
'asin' : 'ASN1'
}
],
"listType": "WISHLIST"
},
'token': 'AddToListToken'
};
return handlerInput.responseBuilder
.speak(actionText)
.addDirective(actionTask)
.getResponse();
}
const speechText = "All right. Please come back if you need more product recommendations."
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
};
Handle a session resumed request
Your skill receives the result of the AMAZON.AddToList
request as a SessionResumedRequest
response. Implement a handler to receive the response.
The response includes the token
given in the AMAZON.AddToList
request.
Use the token
value to restore the previous session of the skill before you invoked the action. Resume the skill based on the result
included in the payload. You can use the result
to alter the skill experience and handle errors.
The following example shows how to handle a session resumed request response.
/**
* Handler to handle SessionResumedRequest.
*/
const SessionResumedRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionResumedRequest';
},
handle(handlerInput) {
// Session attributes and ID are same as previous IntentRequest
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
console.log("sessionAttributes : " + JSON.stringify(sessionAttributes));
const token = handlerInput.requestEnvelope.request.cause.token;
let request = handlerInput.requestEnvelope.request;
let speechText = "Sorry, I had trouble doing what you asked. Please try again.";
if (request.cause) {
const token = request.cause.token;
const status = request.cause.status;
const code = status.code;
const message = status.message;
const payload = request.cause.result;
console.info(`[Add to List Response] ${JSON.stringify(request)}`);
console.info(`[INFO] Shopping Action Result: Code - ${code}, Message - ${message}, Payload - ${payload}`);
switch(code) {
case '200':
if (typeof payload !== "undefined") {
if (payload.code === "AlexaShopping.RetryLaterError") {
speechText = "Looks like there was an issue. Let's get back to the skill.";
} else {
speechText = "I'm sorry, shopping indicated an issue while performing your request. Please try again later.";
console.info(`[INFO] Shopping Action had an issue while performing the request. ${payload.message}`);
}
} else if (token === "AddToListToken") {
console.info(`[INFO] Shopping Action: Add to list action was a success for ${token}.`);
speechText = "Thank you for adding the product to your wish list.";
}
break;
default :
console.info(`[INFO] Shopping Action: There was a problem performing the shopping action.`);
speechText = "There was a problem adding the item to your wish list.";
}
}
return handlerInput.responseBuilder.speak(speechText).getResponse();
},
};
Implement the purchase flow
The AMAZON.BuyShoppingProducts
action helps the customer purchase a recommended product. When you invoke the action, Alexa takes the customer through a multi-turn interaction that presents the product and final price, and asks for confirmation to purchase the product. The purchasing workflow incorporates various checks, including valid payment method, delivery address, and voice PIN authorization associated with the customer account.
Complete the following steps to implement the Alexa Shopping AMAZON.BuyShoppingProducts
action in your skill code.
Send a directive to buy a product
After your skill receives permission from the customer to shop for the product, you send the Connections.StartConnection
directive to Alexa with a AMAZON.BuyShoppingProducts
payload.
Connections.StartConnection
exits the current skill session. Save any important details for the session before sending the request. Save the information that you need to restore the session in the token
parameter.The follow example shows a request to start the product purchase flow.
/**
* Handler to handle RecommendAndAddToList.
*/
const RecommendAndAddToListHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'RecommendAndAddToList');
},
handle(handlerInput) {
console.log("RecommendAndAddToList received.");
const speechText = "<Product intro>" +
" Would you like to know how to purchase this on Amazon?"
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
/**
* Handler to handle YesAndNoIntentHandler.
*/
const YesAndNoIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.YesIntent'
|| request.intent.name === 'AMAZON.NoIntent');
},
handle(handlerInput) {
const intentName = handlerInput.requestEnvelope.request.intent.name;
console.log("User said : " + intentName);
if (intentName === 'AMAZON.YesIntent') {
var actionText = "Staging item with Amazon"
let actionTask = {
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.BuyShoppingProducts/1',
'input': {
'products' : [
{
'asin' : 'ASN1'
}
]
},
'token': 'PurchaseProductToken'
};
return handlerInput.responseBuilder
.speak(actionText)
.addDirective(actionTask)
.getResponse();
}
const speechText = "All right. Please come back if " +
"you need more product recommendations."
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
};
Handle a session resumed request
Your skill receives the result of a purchase as a SessionResumedRequest
. Implement a handler to receive the response.
The response includes the token
given in the AMAZON.BuyShoppingProducts
request.
Use the token
value to restore the previous session of the skill before you invoked the action. Resume the skill based on the result
included in the payload.
If the action fails, Alexa informs the customer of the error and provides available recovery mechanisms to the customer. Alexa Shopping Actions returns the error to your skill in the payload of the response. Don't notify the customer about the error, but use the result
to alter the flow of skill execution.
The following example shows how to handle a session resumed request response.
/**
* Handler to handle SessionResumedRequest.
*/
const SessionResumedRequestHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionResumedRequest';
},
handle(handlerInput) {
// Session attributes and ID are same as previous IntentRequest
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
console.log("sessionAttributes : " + JSON.stringify(sessionAttributes));
const token = handlerInput.requestEnvelope.request.cause.token;
let request = handlerInput.requestEnvelope.request;
let speechText = "Sorry, I had trouble doing what you asked. Please try again.";
if (request.cause) {
const token = request.cause.token;
const status = request.cause.status;
const code = status.code;
const message = status.message;
const payload = request.cause.result;
console.info(`[Shopping Response] ${JSON.stringify(request)}`);
console.info(`[INFO] Shopping Action Result: Code - ${code}, Message - ${message}, Payload - ${payload}`);
switch(code) {
case '200':
if (typeof payload !== "undefined") {
if (payload.code === "AlexaShopping.RetryLaterError") {
speechText = "Looks like there was an issue. Let's get back to the skill.";
} else {
speechText = "I'm sorry, shopping indicated an issue while performing your request. Please try again later.";
console.info(`[INFO] Shopping Action had an issue while performing the request. ${payload.message}`);
}
} else if (token === "PurchaseProductToken") {
console.info(`[INFO] Shopping Action: Buy action was a success for ${token}.`);
speechText = "Thank you for purchasing this product.";
}
break;
default :
console.info(`[INFO] Shopping Action: There was a problem performing the shopping action.`);
speechText = "There was a problem purchasing this product. Let's get back to the skill.";
}
}
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
},
};
Handle a refund request
To handle refund requests, direct the customer to review the order in their Amazon account. No Alexa Shopping Actions task exists to process a refund.
const RefundHandler = {
canHandle(handlerInput) {
return util.parseIntent(handlerInput) === 'RefundIntent';
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak("Please go to the orders section of your Amazon account to review or cancel your order.")
.getResponse();
},
}
Implement the recommend-products flow
AMAZON.RecommendShoppingProducts
Alexa Shopping action is a developer preview and might change as Amazon receives feedback and iterates on the feature. To use this feature, contact your Amazon business representative.When your skill invokes the AMAZON.RecommendShoppingProducts
action, Alexa presents details of the recommended products. Then, the customer can add one or more items to their Cart, buy the items, or continue with the skill. Customers can add items to the Cart even if they don't define customer settings, such as payment method and delivery address.
Complete the following steps to implement the Alexa Shopping AMAZON.RecommendShoppingProducts
action in your skill code.
Send a directive to recommend products
After you ask the customer for permission to learn more about recommended products, you can send the Connections.StartConnection
directive to Alexa with the AMAZON.RecommendShoppingProducts
payload. Here, you request a response on error only.
Connections.StartConnection
exits the current skill session. Save any important details for the session before sending the request. Save the information that you need to restore the session in the token
parameter.The following example shows a request to add the specified product to the list.
/**
* Handler to handle RecommendProducts.
*/
const RecommendProductsHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'RecommendProducts');
},
handle(handlerInput) {
console.log("RecommendProducts received.");
const speechText = "<Product intro>" +
" Would you like hear more?"
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
/**
* Handler to handle YesAndNoIntentHandler.
*/
const YesAndNoIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.YesIntent'
|| request.intent.name === 'AMAZON.NoIntent');
},
handle(handlerInput) {
const intentName = handlerInput.requestEnvelope.request.intent.name;
console.log("User said : " + intentName);
if (intentName === 'AMAZON.YesIntent') {
var actionText = "Transferring product recommendations to Alexa"
let actionTask = {
'type': 'Connections.StartConnection',
'uri': 'connection://AMAZON.AddToList/1',
'input': {
'products' : [
{
'asin' : 'ASN1'
},
{
'asin' : 'ASN2'
}
]
},
'token': 'RecommendProducts',
'onCompletion': 'SEND_ERRORS_ONLY'
};
return handlerInput.responseBuilder
.speak(actionText)
.addDirective(actionTask)
.withShouldEndSession(true)
.getResponse();
}
const speechText = "All right. Please come back if you need more product recommendations."
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
};
Handle a session error
Alexa sends a response on skill connection failure only. Your skill receives the response as a System.ExceptionEncountered
response. For details, see System.ExceptionEncountered. If you want to know if an error occurred, implement a handler to receive the response.
The following example shows how to receive a the System.ExceptionEncountered
response.
/**
* Handler to handle ExceptionEncountered.
*/
const SystemExceptionEncounteredHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'System.ExceptionEncountered';
},
handle(handlerInput) {
console.dir(handlerInput.requestEnvelope.request);
return handlerInput.responseBuilder
.getResponse();
},
};
Related topics
- Implement a handler to receive a response from a skill connections request
- Design the Product Recommendation
- Steps to Add Alexa Shopping Actions to Your Skill
- Alexa Shopping Actions API Reference
- Alexa Shopping Actions FAQ
Last updated: Jan 17, 2023