Skip to content

Instantly share code, notes, and snippets.

@LucioMSP
Last active October 26, 2019 18:24
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 LucioMSP/1bb06a2b4f1ad92e03ac59cf6852cde5 to your computer and use it in GitHub Desktop.
Save LucioMSP/1bb06a2b4f1ad92e03ac59cf6852cde5 to your computer and use it in GitHub Desktop.
Alexa, lanza consejos del abuelo
{
"interactionModel": {
"languageModel": {
"invocationName": "consejos del abuelo",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": [
"cancela"
]
},
{
"name": "AMAZON.HelpIntent",
"samples": [
"ayudame",
"ayuda"
]
},
{
"name": "AMAZON.StopIntent",
"samples": [
"alto",
"para",
"detente",
"adios",
"salir",
"adiós"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "ConsejoIntent",
"slots": [
{
"name": "nombre",
"type": "AMAZON.FirstName",
"samples": [
"me dicen {nombre}",
"puedes decirme {nombre}",
"dime {nombre}",
"me llamo {nombre}",
"{nombre}"
]
}
],
"samples": [
"dame un consejo",
"aconséjame"
]
}
],
"types": []
},
"dialog": {
"intents": [
{
"name": "ConsejoIntent",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "nombre",
"type": "AMAZON.FirstName",
"confirmationRequired": false,
"elicitationRequired": true,
"prompts": {
"elicitation": "Elicit.Slot.666209592402.794048786262"
}
}
]
}
],
"delegationStrategy": "ALWAYS"
},
"prompts": [
{
"id": "Elicit.Slot.666209592402.794048786262",
"variations": [
{
"type": "PlainText",
"value": "¿cómo te puedo llamar?"
},
{
"type": "PlainText",
"value": "¿cómo te puedo decir?"
},
{
"type": "PlainText",
"value": "¿cuál es tu nombre?"
},
{
"type": "PlainText",
"value": "¿cómo te llamas?"
}
]
}
]
}
}
/*********************
* Author: VGGL
* Fecha: 24 de Octubre 2019
**********************/
// lambda
// Ejemplo sobre el manejo de Intents en una skill Alexa SDK v2
const Alexa = require('ask-sdk-core');
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
var speechText = '';
// Verifica que el dispositivo tenga soporte APL.
if (!supportsAPL(handlerInput)) {
speechText = '¡Hola! bienvenido a Consejos del Abuelo, para comenzar puedes decir: dame un consejo... o si deseas detenerme solo di: ¡Cancela!... entonces, ¿cómo te puedo ayudar?';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Consejos del Abuelo', speechText)
.reprompt('¿Cómo te puedo ayudar?')
.getResponse();
}
speechText = '¡Hola! bienvenido a Consejos del Abuelo, para comenzar puedes decir: dame un consejo... o si deseas detenerme solo di: ¡Cancela!... entonces, ¿cómo te puedo ayudar?';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Consejos del Abuelo', speechText)
.reprompt('¿Cómo te puedo ayudar?')
.addDirective({
type: 'Alexa.Presentation.APL.RenderDocument',
version: '1.0',
document: require('./welcome.json'),
datasources: {}
})
.getResponse();
}
};
const ConsejoIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'ConsejoIntent';
},
handle(handlerInput) {
const listaConsejos = [
'No puedes dar lo que no tienes, no prometas nada si no puedes hacerlo.',
'Piensa en algo malo o tonto que hiciste hace seis años. Ahora piensa algo tonto que algún amigo te hizo hace algunas semanas. ¿Ves? Prestamos más atención a nuestros propios errores, lo que acabamos haciéndole a los demás.',
'No te cases con un hombre pensando que puedes cambiar lo que no te gusta de él. En lugar de eso, piensa en sus peores cualidades, multiplícalas por 100 y eso es lo que tendrás después de 30 años de matrimonio.',
'Las preocupaciones son como una mecedora. Te mueven y te dan algo que hacer, pero no llevan a ninguna parte.',
'',
'',
];
const indiceAleatorio = Math.floor(Math.random() * listaConsejos.length);
const consejoAleatorio = listaConsejos[indiceAleatorio];
const listaImagenes = [
'https://fsmedia.imgix.net/11/66/dc/09/78d1/486d/91eb/d7c6804f72e1/grandfather-smoking.jpeg?rect=0%2C876%2C2519%2C1258&auto=format%2Ccompress&dpr=2&w=650',
'https://www.bbva.com/wp-content/uploads/2016/10/que-plan-de-pensiones-escojo-e1526642490798-1024x467.jpg',
'http://campeonafm.com.ve/wp-content/uploads/2018/07/abuelo.jpg',
'',
'',
];
const imgsAleatorio = Math.floor(Math.random() * listaImagenes.length);
const consejoImgAleatorio = listaImagenes[imgsAleatorio];
const request = handlerInput.requestEnvelope.request;
var myName = request.intent.slots.nombre.value;
var speechReprompt = 'Si quieres escuchar otro consejo puedes solicitarlo diciendo: dame un consejo o también puedes decir adiós para salir de la Skill, entonces ¿cómo te puedo ayudar?'
var speechText = "Hola" + " " + myName + "," + " " + "un consejo que te puede dar este viejo es:" + " " + consejoAleatorio;
var speechTextFull = "<voice name='Enrique'>" + speechText + "</voice>" + " " + speechReprompt;
// Verifica que el dispositivo tenga soporte APL.
if (!supportsAPL(handlerInput)) {
return handlerInput.responseBuilder
.speak(speechTextFull)
.withSimpleCard('Consejos del Abuelo', speechText)
.reprompt(speechReprompt)
.getResponse();
}
// Meter en un arreglo los consejos e imagenes disponibles (urls)
// y hacer la selección de forma aleatoria.
//speechText = "<voice name='Enrique'>Hola" + " " + myName + "," + " " + "un consejo que te puede dar este viejo es:" + " " + consejoAleatorio + "</voice>" + " " + speechReprompt;
var myUrl = consejoImgAleatorio;
return handlerInput.responseBuilder
.speak(speechTextFull)
.reprompt('¿Cómo te puedo ayudar?')
.addDirective({
type: 'Alexa.Presentation.APL.RenderDocument',
version: '1.0',
document: require('./main.json'),
datasources: {
"bodyTemplate7Data": {
"type": "object",
"objectId": "bt7Sample",
"title": "Un consejo que te puede dar este viejo es ...",
"image": {
"sources": [
{
"url": myUrl,
"size": "small",
"widthPixels": 0,
"heightPixels": 0
},
{
"url": myUrl,
"size": "large",
"widthPixels": 0,
"heightPixels": 0
}
]
},
"logoUrl": "",
"hintText": "Di, \"Alexa, dame un consejo\""
}
}
})
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speechText = 'Puedo darte un consejo, para esto, di: dame un consejo, para salir puedes decirme adiós, entonces, ¿cómo te puedo ayudar?';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('El abuelo te ayuda', 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 = "<voice name='Enrique'>No me voy, me llevan..." + "</voice>" + 'Y se fue el abuelo.., ¡adiós!';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Hasta pronto!', 'No me voy, me llevan...y se fue el abuelo.., ¡adiós!')
.withShouldEndSession(true)
.getResponse();
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
// aquí va código de limpieza o reinicialización.
return handlerInput.responseBuilder.getResponse();
}
};
// Handler para testing y debugging.
// Repite la petición del usuario.
const IntentReflectorHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest';
},
handle(handlerInput) {
const intentName = handlerInput.requestEnvelope.request.intent.name;
const speechText = 'Ejecutaste,' + intentName + ', en breve tendré funcionalidad disponible';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
// Captura genérica de errores, (sintáxis, enrutamiento).
// Si se recibe error, significa que no hay un handler que regrese "true" para el método canHandle()
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();
}
};
// Comprueba si el dispositivo en uso soporta APL.
function supportsAPL(handlerInput) {
const supportedInterfaces = handlerInput.requestEnvelope.context.System.device.supportedInterfaces;
const aplInterface = supportedInterfaces['Alexa.Presentation.APL'];
return aplInterface !== null && aplInterface !== undefined;
}
// Entrada de la skill, se encarga de enrutar todas las peticiones.
// Aquí deben existir todos los handlers e interceptores.
/*************************************************************
/* IMPORTANTE EL ORDEN DE APARICIÓN, en dicho orden se procesan.
/*************************************************************/
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
ConsejoIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
IntentReflectorHandler) // al final va el IntentReflector, con esto evitamos que maneje peticiones erróneas
.addErrorHandlers(
ErrorHandler)
.lambda();
{
"type": "APL",
"version": "1.0",
"theme": "dark",
"import": [
{
"name": "alexa-layouts",
"version": "1.0.0"
}
],
"resources": [
{
"description": "Stock color for the light theme",
"colors": {
"colorTextPrimary": "#151920"
}
},
{
"description": "Stock color for the dark theme",
"when": "${viewport.theme == 'dark'}",
"colors": {
"colorTextPrimary": "#f0f1ef"
}
},
{
"description": "Standard font sizes",
"dimensions": {
"textSizeBody": 38,
"textSizePrimary": 17,
"textSizeSecondary": 13,
"textSizeSecondaryHint": 15
}
},
{
"description": "Common spacing values",
"dimensions": {
"spacingThin": 6,
"spacingSmall": 12,
"spacingMedium": 24,
"spacingLarge": 48,
"spacingExtraLarge": 72
}
},
{
"description": "Common margins and padding",
"dimensions": {
"marginTop": 40,
"marginLeft": 60,
"marginRight": 60,
"marginBottom": 40
}
}
],
"styles": {
"textStyleBase": {
"description": "Base font description; set color",
"values": [
{
"color": "@colorTextPrimary"
}
]
},
"textStyleBase0": {
"description": "Thin version of basic font",
"extend": "textStyleBase",
"values": {
"fontWeight": "100"
}
},
"textStyleBase1": {
"description": "Light version of basic font",
"extend": "textStyleBase",
"values": {
"fontWeight": "300"
}
},
"mixinBody": {
"values": {
"fontSize": "@textSizeBody"
}
},
"mixinPrimary": {
"values": {
"fontSize": "@textSizePrimary"
}
},
"mixinSecondary": {
"values": {
"fontSize": "@textSizeSecondary"
}
},
"textStylePrimary": {
"extend": [
"textStyleBase1",
"mixinPrimary"
]
},
"textStyleSecondary": {
"extend": [
"textStyleBase0",
"mixinSecondary"
]
},
"textStyleBody": {
"extend": [
"textStyleBase1",
"mixinBody"
]
},
"textStyleSecondaryHint": {
"values": {
"fontFamily": "Bookerly",
"fontStyle": "italic",
"fontSize": "@textSizeSecondaryHint",
"color": "@colorTextPrimary"
}
}
},
"layouts": {},
"mainTemplate": {
"parameters": [
"payload"
],
"items": [
{
"when": "${viewport.shape == 'round'}",
"type": "Container",
"direction": "column",
"items": [
{
"type": "Image",
"source": "${payload.bodyTemplate7Data.backgroundImage.sources[0].url}",
"scale": "best-fill",
"position": "absolute",
"width": "100vw",
"height": "100vh"
},
{
"type": "AlexaHeader",
"headerTitle": "${payload.bodyTemplate7Data.title}",
"headerAttributionImage": "${payload.bodyTemplate7Data.logoUrl}"
},
{
"type": "Container",
"grow": 1,
"alignItems": "center",
"justifyContent": "center",
"items": [
{
"type": "Image",
"source": "${payload.bodyTemplate7Data.image.sources[0].url}",
"scale": "best-fill",
"width": "100vh",
"height": "70vw",
"align": "center"
}
]
}
]
},
{
"type": "Container",
"items": [
{
"type": "Image",
"source": "${payload.bodyTemplate7Data.backgroundImage.sources[0].url}",
"scale": "best-fill",
"position": "absolute",
"width": "150vw",
"height": "100vh"
},
{
"type": "AlexaHeader",
"headerTitle": "${payload.bodyTemplate7Data.title}",
"headerAttributionImage": "${payload.bodyTemplate7Data.logoUrl}"
},
{
"type": "Container",
"direction": "row",
"paddingLeft": "5vw",
"paddingRight": "5vw",
"paddingBottom": "5vh",
"alignItems": "center",
"justifyContent": "center",
"items": [
{
"type": "Image",
"height": "75vh",
"width": "90vw",
"source": "${payload.bodyTemplate7Data.image.sources[0].url}",
"scale": "best-fill",
"align": "center"
}
]
}
]
}
]
}
}
{
"type": "APL",
"version": "1.0",
"theme": "dark",
"import": [],
"resources": [],
"styles": {},
"layouts": {},
"mainTemplate": {
"items": [
{
"type": "Frame",
"backgroundColor": "black",
"item": {
"type": "Container",
"height": "100vh",
"width": "100vw",
"direction": "column",
"alignItems": "center",
"justifyContent": "center",
"items": [
{
"type": "Text",
"text": "Consejos del Abuelo"
},
{
"type": "Text",
"text": "¡Bienvenidos!"
}
]
}
}
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment