Implement Alexa Shopping Actions in Your Skill
Your skill starts the Alexa Shopping flows by using the skill connections interface. To add the product to the customer's Amazon Shopping Cart, you invoke the AddToShoppingCart
task. To purchase a given product, you invoke the BuyShoppingProducts
task. Both tasks start a multi-turn interaction between Alexa and the customer to complete the shopping experience.
To use Alexa Shopping Actions in your skill, customers must enable voice purchasing in their Alexa app.
Implement the add-to-cart flow
The AddToShoppingCart
action adds a recommended 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 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 shop for the product, you can send the Connections.StartConnection
directive to Alexa with an AddToShoppingCart
payload.
Connections.StartConnection
exits the current skill session. Save any important details for the session before sending the request.The following example shows a request to add the specified product to the cart.
/**
* Handler to handle RecommendAndShopForProducts.
*/
const RecommendAndShopForProductsHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'RecommendAndShopForProducts');
},
handle(handlerInput) {
console.log("RecommendAndShopForProducts received.");
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' : 'B01962MDHA'
}
]
},
'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 a purchase as a SessionResumedRequest
. The result includes the token
given in the AddToShoppingCart
request. Implement a handler to receive the SessionResumedRequest
response.
Resume the skill based on the result
included in the payload.
You can use the token
to load the stored skill session, 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 purchase flow
The BuyShoppingProducts
action helps the customer purchase a given product. The action 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.
To use the BuyShoppingProducts
action inside your skill, the customer must have a default 1-click setting enabled on their Amazon account. If the customer doesn't have this option enabled, Alexa Shopping informs the customer to enable the required feature, and then returns the appropriate information in a response with status code InvalidCustomerSettings
.
Complete the following steps to implement the Alexa Shopping BuyShoppingProducts
action in your skill code.
Send a directive to buy a product
After your skill receives the permission from the customer to shop for the product, you send the Connections.StartConnection
directive to Alexa with a BuyShoppingProducts
payload.
Connections.StartConnection
exits the current skill session. Save any important details for the session before sending the request.The follow example shows a request to start the product purchase flow.
/**
* Handler to handle RecommendAndShopForProducts.
*/
const RecommendAndShopForProductsHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'RecommendAndShopForProducts');
},
handle(handlerInput) {
console.log("RecommendAndShopForProducts 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' : 'B01962MDHA'
}
]
},
'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
. The result includes the token
given in the BuyShoppingProducts
request. Implement a handler to receive the SessionResumedRequest
response.
Resume the skill based on the result
included in the payload.
You can use the token
to load the stored skill session, 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 === "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.";
}
}
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();
},
}