Skip to content

Instantly share code, notes, and snippets.

@softwarechido
Last active March 26, 2019 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save softwarechido/65f32096dbc08040e535d7efdd64c571 to your computer and use it in GitHub Desktop.
Save softwarechido/65f32096dbc08040e535d7efdd64c571 to your computer and use it in GitHub Desktop.
//lambda
// This sample demonstrates handling intents from an Alexa skill using the Alexa Skills Kit SDK (v2).
// Please visit https://alexa.design/cookbook for additional examples on implementing slots, dialog management,
// session persistence, api calls, and more.
const Alexa = require('ask-sdk-core');
const persistenceAdapter = require('ask-sdk-s3-persistence-adapter');
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Hola! Bienvenido a Paseo Pastelero. ¿Cuándo es tu cumpleaños?';
const repromptText = 'Yo nací el 6 de noviembre del 2016, ¿tú cuándo naciste?';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(repromptText)
.getResponse();
}
};
const HasBirthdayLaunchRequestHandler = {
canHandle(handlerInput) {
const attributesManager = handlerInput.attributesManager;
const sessionAttributes = attributesManager.getSessionAttributes() || {};
const year = sessionAttributes.hasOwnProperty('year') ? sessionAttributes.year : 0;
const month = sessionAttributes.hasOwnProperty('month') ? sessionAttributes.month : 0;
const day = sessionAttributes.hasOwnProperty('day') ? sessionAttributes.day : 0;
return handlerInput.requestEnvelope.request.type === 'LaunchRequest' &&
year &&
month &&
day;
},
async handle(handlerInput) {
const serviceClientFactory = handlerInput.serviceClientFactory;
const deviceId = handlerInput.requestEnvelope.context.System.device.deviceId;
const attributesManager = handlerInput.attributesManager;
const sessionAttributes = attributesManager.getSessionAttributes() || {};
const year = sessionAttributes.hasOwnProperty('year') ? sessionAttributes.year : 0;
const month = sessionAttributes.hasOwnProperty('month') ? sessionAttributes.month : 0;
const day = sessionAttributes.hasOwnProperty('day') ? sessionAttributes.day : 0;
let userTimeZone;
try {
const upsServiceClient = serviceClientFactory.getUpsServiceClient();
userTimeZone = await upsServiceClient.getSystemTimeZone(deviceId);
} catch (error) {
if (error.name !== 'ServiceError') {
return handlerInput.responseBuilder.speak("Hubo un problema de conexión con el servicio").getResponse();
}
console.log('error', error.message);
}
console.log('userTimeZone:', userTimeZone);
const oneDay = 24*60*60*1000;
// getting the current date with the time
const currentDateTime = new Date(new Date().toLocaleString("es-MX", {timeZone: userTimeZone}));
// removing the time from the date because it affects our difference calculation
const currentDate = new Date(currentDateTime.getFullYear(), currentDateTime.getMonth(), currentDateTime.getDate());
const currentYear = currentDate.getFullYear();
console.log('currentDateTime:', currentDateTime);
console.log('currentDate:', currentDate);
console.log('currentYear:', currentYear);
console.log('month:', month);
console.log('day:', day);
console.log('currentYear:', currentYear);
// For spanish locale, getting month as Number
const monthAsNum = monthNameToNum(month);
// getting getting the next birthday
let nextBirthday = Date.parse(`${monthAsNum} ${day}, ${currentYear}`);
console.log('nextBirthday:', new Date(nextBirthday));
// adjust the nextBirthday by one year if the current date is after their birthday
if (currentDate.getTime() > nextBirthday) {
nextBirthday = Date.parse(`${month} ${day}, ${currentYear + 1}`);
}
// setting the default speechText to Happy xth Birthday!!
// Alexa will automatically correct the ordinal for you.
// no need to worry about when to use st, th, rd
const age = currentYear - year;
let speechText = `Feliz Cumpleaños número ${age}!`;
if (currentDate.getTime() !== nextBirthday) {
const diffDays = Math.round(Math.abs((currentDate.getTime() - nextBirthday)/oneDay));
const x = Math.abs(currentDate.getTime())/oneDay;
speechText = `Holi! faltan ${diffDays} días para tu cumpleaños número ${age}`;
}
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
};
const BirthdayIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'BirthdayIntent';
},
async handle(handlerInput) {
const year = handlerInput.requestEnvelope.request.intent.slots.year.value;
const month = handlerInput.requestEnvelope.request.intent.slots.month.value;
const day = handlerInput.requestEnvelope.request.intent.slots.day.value;
const attributesManager = handlerInput.attributesManager;
let birthdayAttributes = {
"year": year,
"month": month,
"day": day
};
attributesManager.setPersistentAttributes(birthdayAttributes);
await attributesManager.savePersistentAttributes();
const speechText = `Gracias, recordaré que naciste el día ${day} de ${month} del año ${year}.`;
return handlerInput.responseBuilder
.speak(speechText)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.withShouldEndSession('true')
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speechText = 'Me puedes decir Hola! ¿Cómo te puedo ayudar?';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
|| handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const speechText = 'Adios!';
return handlerInput.responseBuilder
.speak(speechText)
.getResponse();
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
// Any cleanup logic goes here.
return handlerInput.responseBuilder.getResponse();
}
};
// The intent reflector is used for interaction model testing and debugging.
// It will simply repeat the intent the user said. You can create custom handlers
// for your intents by defining them above, then also adding them to the request
// handler chain below.
const IntentReflectorHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest';
},
handle(handlerInput) {
const intentName = handlerInput.requestEnvelope.request.intent.name;
const speechText = `Lanzaste el intent que se llama ${intentName}`;
return handlerInput.responseBuilder
.speak(speechText)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
const LoadBirthdayInterceptor = {
async process(handlerInput) {
const attributesManager = handlerInput.attributesManager;
const sessionAttributes = await attributesManager.getPersistentAttributes() || {};
const year = sessionAttributes.hasOwnProperty('year') ? sessionAttributes.year : 0;
const month = sessionAttributes.hasOwnProperty('month') ? sessionAttributes.month : 0;
const day = sessionAttributes.hasOwnProperty('day') ? sessionAttributes.day : 0;
if (year && month && day) {
attributesManager.setSessionAttributes(sessionAttributes);
}
}
}
function monthNumToName(monthnum) {
return months[monthnum - 1] || '';
}
function monthNameToNum(monthname) {
var month = months.indexOf(monthname);
return month ? month + 1 : 0;
}
const months = ['enero', 'febrero', 'marzo', 'abril', 'mayo',
'junio', 'julio', 'agosto', 'septiembre',
'octubre', 'noviembre', 'diciembre'
];
// Generic error handling to capture any syntax or routing errors. If you receive an error
// stating the request handler chain is not found, you have not implemented a handler for
// the intent being invoked or included it in the skill builder below.
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`~~~~ Error handled: ${error.message}`);
const speechText = `Lo siento, No puedo entender lo que has dicho. Por favor inténtalo de nuevo`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
// This handler acts as the entry point for your skill, routing all request and response
// payloads to the handlers above. Make sure any new handlers or interceptors you've
// defined are included below. The order matters - they're processed top to bottom.
exports.handler = Alexa.SkillBuilders.custom()
.withPersistenceAdapter(
new persistenceAdapter.S3PersistenceAdapter({bucketName:process.env.S3_PERSISTENCE_BUCKET})
//new persistenceAdapter.S3PersistenceAdapter({bucketName:pastelero})
)
.addRequestHandlers(
HasBirthdayLaunchRequestHandler,
LaunchRequestHandler,
BirthdayIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
IntentReflectorHandler) // make sure IntentReflectorHandler is last so it doesn't override your custom intent handlers
.addRequestInterceptors(
LoadBirthdayInterceptor
)
.addErrorHandlers(
ErrorHandler)
.withApiClient(new Alexa.DefaultApiClient())
.withCustomUserAgent('cookbook/device-settings/v1')
.lambda();
{
"interactionModel": {
"languageModel": {
"invocationName": "paseo pastelero",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "BirthdayIntent",
"slots": [
{
"name": "month",
"type": "AMAZON.Month"
},
{
"name": "day",
"type": "OrdinalSimulation"
},
{
"name": "year",
"type": "AMAZON.FOUR_DIGIT_NUMBER"
}
],
"samples": [
"Nací un {day} de {month} del {year}",
"Nací un {day} de {month} del año {year}",
"Nací el {day} de {month} del año {year}",
"Nací en {month} {day} {year}",
"Nací el {day} de {month} de {year}",
"Nací el {day} de {month} del {year}",
"Nací en {month} {day} ",
"{day} {month} {year}",
"{month} {day}",
"{day} de {month}",
"{month} {day} {year}",
"{month} {year}"
]
}
],
"types": [
{
"name": "OrdinalSimulation",
"values": [
{
"name": {
"value": "31",
"synonyms": [
"trigésimo primero"
]
}
},
{
"name": {
"value": "30",
"synonyms": [
"trigésimo"
]
}
},
{
"name": {
"value": "29",
"synonyms": [
"vigésimo noveno"
]
}
},
{
"name": {
"value": "28",
"synonyms": [
"vigésimo octavo"
]
}
},
{
"name": {
"value": "27",
"synonyms": [
"vigésimo séptimo"
]
}
},
{
"name": {
"value": "26",
"synonyms": [
"vigésimo sexto"
]
}
},
{
"name": {
"value": "25",
"synonyms": [
"vigésimo quinto"
]
}
},
{
"name": {
"value": "24",
"synonyms": [
"vigésimo cuarto"
]
}
},
{
"name": {
"value": "23",
"synonyms": [
"vigésimo tercero"
]
}
},
{
"name": {
"value": "22",
"synonyms": [
"vigésimo segundo"
]
}
},
{
"name": {
"value": "21",
"synonyms": [
"vigésimo primero"
]
}
},
{
"name": {
"value": "20",
"synonyms": [
"vigésimo"
]
}
},
{
"name": {
"value": "19",
"synonyms": [
"décimo noveno"
]
}
},
{
"name": {
"value": "18",
"synonyms": [
"décimo octavo"
]
}
},
{
"name": {
"value": "17",
"synonyms": [
"décimo séptimo"
]
}
},
{
"name": {
"value": "16",
"synonyms": [
"décimo sexto"
]
}
},
{
"name": {
"value": "15",
"synonyms": [
"décimo quinto"
]
}
},
{
"name": {
"value": "14",
"synonyms": [
"décimo cuarto"
]
}
},
{
"name": {
"value": "13",
"synonyms": [
"décimo tercero"
]
}
},
{
"name": {
"value": "12",
"synonyms": [
"décimo segundo"
]
}
},
{
"name": {
"value": "11",
"synonyms": [
"décimo primero"
]
}
},
{
"name": {
"value": "10",
"synonyms": [
"décimo"
]
}
},
{
"name": {
"value": "9",
"synonyms": [
"noveno"
]
}
},
{
"name": {
"value": "8",
"synonyms": [
"octavo"
]
}
},
{
"name": {
"value": "7",
"synonyms": [
"séptimo"
]
}
},
{
"name": {
"value": "6",
"synonyms": [
"sexto"
]
}
},
{
"name": {
"value": "5",
"synonyms": [
"quinto"
]
}
},
{
"name": {
"value": "4",
"synonyms": [
"cuarto"
]
}
},
{
"name": {
"value": "3",
"synonyms": [
"tercero"
]
}
},
{
"name": {
"value": "2",
"synonyms": [
"segundo"
]
}
},
{
"name": {
"value": "1",
"synonyms": [
"primero"
]
}
}
]
}
]
},
"dialog": {
"intents": [
{
"name": "BirthdayIntent",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "month",
"type": "AMAZON.Month",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.303899476312.795077103633"
}
},
{
"name": "day",
"type": "OrdinalSimulation",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.303899476312.985837334781"
}
},
{
"name": "year",
"type": "AMAZON.FOUR_DIGIT_NUMBER",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.303899476312.27341833344"
}
}
]
}
],
"delegationStrategy": "ALWAYS"
},
"prompts": [
{
"id": "Elicit.Slot.303899476312.795077103633",
"variations": [
{
"type": "PlainText",
"value": "Yo nací en Noviembre. ¿tú cuándo naciste?"
},
{
"type": "PlainText",
"value": "¿En qué mes naciste?"
}
]
},
{
"id": "Elicit.Slot.303899476312.985837334781",
"variations": [
{
"type": "PlainText",
"value": "Yo nací un día seís. ¿tú que día de {month} naciste?"
}
]
},
{
"id": "Elicit.Slot.303899476312.27341833344",
"variations": [
{
"type": "PlainText",
"value": "Yo nací en el año dos mil quince, ¿tu de qué año eres?"
}
]
}
]
}
}
{
"name": "hello-world",
"version": "0.9.0",
"description": "alexa utility for quickly building skills",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Amazon Alexa",
"license": "ISC",
"dependencies": {
"ask-sdk-core": "^2.0.7",
"ask-sdk-model": "^1.4.1",
"aws-sdk": "^2.326.0",
"ask-sdk-s3-persistence-adapter": "^2.5.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment