diff --git a/lambda/main/constants.js b/lambda/main/constants.js index ca4cb74..dedd386 100644 --- a/lambda/main/constants.js +++ b/lambda/main/constants.js @@ -38,6 +38,7 @@ module.exports.ElasticPathIntents = { DESCRIBE_LISTED_PRODUCT: 'DescribeListedProductIntent', DESCRIBE_PRODUCT: 'DescribeProductIntent', GET_CART: 'GetCartIntent', + GET_PREVIOUS_PURCHASE_STATUS: 'GetPreviousPurchaseStatusIntent', GET_WISLIST: 'GetWishlistIntent', KEYWORD_SEARCH: 'KeywordSearchIntent', MOVE_TO_CART: 'MoveToCartIntent', diff --git a/lambda/main/cortex.js b/lambda/main/cortex.js index 585dcd1..4f8bb7f 100644 --- a/lambda/main/cortex.js +++ b/lambda/main/cortex.js @@ -329,4 +329,15 @@ Cortex.prototype.cortexCheckout = function () { }); } +Cortex.prototype.cortexGetPurchases = function () { + return new Promise((resolve, reject) => { + this.cortexGet(`${this.cortexBaseUrl}?zoom=defaultprofile:purchases:element`) + .then((data) => { + const purchases = (data._defaultprofile) ? data._defaultprofile[0]._purchases[0]._element : []; + resolve(purchases); + + }).catch((err) => reject(err)); + }); +} + module.exports = Cortex; diff --git a/lambda/main/handlers/getpreviouspurchase.handler.js b/lambda/main/handlers/getpreviouspurchase.handler.js new file mode 100644 index 0000000..24838a8 --- /dev/null +++ b/lambda/main/handlers/getpreviouspurchase.handler.js @@ -0,0 +1,54 @@ +/** + * Copyright © 2018 Elastic Path Software Inc. All rights reserved. + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this license. If not, see + * + * https://www.gnu.org/licenses/ + * + * + */ + +const Cortex = require('../cortex'); +const SpeechAssets = require('../speech/assets'); +const { isIntentRequestOfType } = require('../utils'); +const { ElasticPathIntents } = require('../constants'); + +const GetPreviousPurchaseStatusHandler = { + canHandle({requestEnvelope}) { + return isIntentRequestOfType(requestEnvelope, ElasticPathIntents.GET_PREVIOUS_PURCHASE_STATUS); + }, + handle({responseBuilder}) { + return new Promise((resolve, reject) => { + Cortex.getCortexInstance() + .cortexGetPurchases() + .then((items) => { + if (items.length > 0) { + const previousPurchase = items[0]; + resolve(responseBuilder + .speak(SpeechAssets.describePurchaseStatus(previousPurchase["purchase-number"], previousPurchase.status)) + .reprompt(SpeechAssets.readyToCheckOut()) + .getResponse()); + } else { + resolve(responseBuilder + .speak(SpeechAssets.emptyPurchases()) + .reprompt(SpeechAssets.howElseCanIHelp()) + .getResponse()); + } + }) + .catch((err) => reject(err)); + }); + } +} + +module.exports = GetPreviousPurchaseStatusHandler; diff --git a/lambda/main/index.js b/lambda/main/index.js index 41ab0ae..2c1c5d6 100644 --- a/lambda/main/index.js +++ b/lambda/main/index.js @@ -34,6 +34,7 @@ const DescribeProductHandler = require('./handlers/describeproduct.handler'); const DescribeListedProductHandler = require('./handlers/descibelistedproduct.handler'); const GetCartHandler = require('./handlers/getcart.handler'); const GetWishlistHandler = require('./handlers/getwishlist.handler'); +const GetPreviousPurchaseHandler = require('./handlers/getpreviouspurchase.handler'); const HelpIntentHandler = require('./handlers/helpintent.handler'); const KeywordSearchHandler = require('./handlers/keywordsearch.handler'); const MoveToCartHandler= require('./handlers/movetocart.handler'); @@ -68,6 +69,7 @@ exports.handler = Alexa.SkillBuilders.custom() DescribeListedProductHandler, GetCartHandler, GetWishlistHandler, + GetPreviousPurchaseHandler, HelpIntentHandler, KeywordSearchHandler, MoveToCartHandler, diff --git a/lambda/main/speech/assets.js b/lambda/main/speech/assets.js index 9581556..e489f2d 100644 --- a/lambda/main/speech/assets.js +++ b/lambda/main/speech/assets.js @@ -140,6 +140,9 @@ const speechAssets = { noItemsInWishlist: [ 'Your wishlist is empty, add some items first. ' ], + noPurchases: [ + 'You have no previous purchases, complete an order first. ' + ], purchaseSuccess: [ 'Great! Your purchase was successful. ', 'Ok, your order has been placed. ', @@ -150,6 +153,12 @@ const speechAssets = { 'Here\'s the description: <>; The <> retails for <>. ', 'Here\'s the write-up: <>; The <> retails for <>. ' ], + describePurchaseStatus: [ + 'Your previous order, order number <>, is <>. ', + 'Your previous purchase, order number <>, is <>. ', + 'Your last order, order number <>, is <>. ', + 'Your last purchase, order number <>, is <>. ', + ], describePrice: [ '<>. ' ], @@ -238,7 +247,7 @@ const pickVariation = function(arrayOfResponses) { const cleanOutput = function(...output) { // eslint-disable-next-line no-useless-escape - return ` ${output.join(' ').replace(/(?!\.[\d\.])\./g, '. ').replace(/&/g, 'and').replace(/\s\s+/g, ' ')} `; + return ` ${output.join(' ').replace(/(?!\.[\d\.])\./g, '. ').replace(/&/g, 'and').replace(/\s\s+/g, ' ').replace(/_/g, ' ')} `; } assets.prototype.greeting = function() { @@ -346,6 +355,14 @@ assets.prototype.describeProduct = function(description, item) { return cleanOutput(this.positiveFiller(), response); }; +assets.prototype.describePurchaseStatus = function(orderNumber, status) { + const response = pickVariation(speechAssets.describePurchaseStatus) + .replace('<>', orderNumber) + .replace('<>', status); + + return cleanOutput(this.positiveFiller(), response); +}; + assets.prototype.noProductToDescribe = function() { return cleanOutput(this.appologeticFiller(), speechAssets.noProductToDescribe, this.howElseCanIHelp()); }; @@ -453,6 +470,10 @@ assets.prototype.emptyWishlist = function() { return cleanOutput(pickVariation(speechAssets.noItemsInWishlist), this.howElseCanIHelp()); }; +assets.prototype.emptyPurchases = function() { + return cleanOutput(pickVariation(speechAssets.noPurchases), this.howElseCanIHelp()); +}; + assets.prototype.fullCheckoutMessage = function(quantity, total) { const checkoutString = speechAssets.itemsInCart[Math.floor(Math.random() * speechAssets.itemsInCart.length)] .replace('<>', quantity) diff --git a/models/en-US.json b/models/en-US.json index ca18544..b84bbd8 100644 --- a/models/en-US.json +++ b/models/en-US.json @@ -274,6 +274,23 @@ "remove item {ItemNumber} from my wish list", "delete item {ItemNumber} from my wish list" ] + }, + { + "name": "GetPreviousPurchaseStatusIntent", + "samples": [ + "What is the status of my last order", + "What is the status of my previous order", + "What is the status of my recent order", + "What is the status of my last purchase", + "What is the status of my previous purchase", + "What is the status of my recent purchase", + "Tell me the status of my last order", + "Tell me the status of my previous order", + "Tell me the status of my recent order", + "Tell me the status of my last purchase", + "Tell me the status of my previous purchase", + "Tell me the status of my recent purchase" + ] } ], "types": [