Created
February 10, 2021 11:54
-
-
Save cooldevil007/7e4aba8b7af3b39b6923cb3b2a52e418 to your computer and use it in GitHub Desktop.
Reminder operation from out of session
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Alexa = require('ask-sdk-core'); | |
const messages = { | |
WELCOME: 'Welcome to the Reminders API Demo Skill! You can say "create a reminder" to create a reminder. What would you like to do?', | |
WHAT_DO_YOU_WANT: 'What would you like to do?', | |
NOTIFY_MISSING_PERMISSIONS: 'Please enable Reminder permissions in the Amazon Alexa app using the card I\'ve sent to your Alexa app.', | |
ERROR: 'Uh Oh. Looks like something went wrong.', | |
API_FAILURE: 'There was an error with the Reminders API.', | |
GOODBYE: 'Bye! Thanks for using the Reminders API Skill!', | |
UNHANDLED: 'This skill doesn\'t support that. Please ask something else.', | |
HELP: 'You can use this skill by asking something like: create a reminder?', | |
REMINDER_CREATED: 'OK, I will remind you in 30 seconds.', | |
UNSUPPORTED_DEVICE: 'Sorry, this device doesn\'t support reminders.', | |
WELCOME_REMINDER_COUNT: 'Welcome to the Reminders API Demo Skill. The number of your reminders related to this skill is ', | |
NO_REMINDER: 'OK, I won\'t remind you.', | |
}; | |
const PERMISSIONS = ['alexa::alerts:reminders:skill:readwrite']; | |
const LaunchRequestHandler = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'LaunchRequest'; | |
}, | |
async handle(handlerInput) { | |
const requestEnvelope = handlerInput.requestEnvelope; | |
const responseBuilder = handlerInput.responseBuilder; | |
const consentToken = requestEnvelope.context.System.apiAccessToken; | |
if (!consentToken) { | |
// if no consent token, skip getting reminder count | |
return responseBuilder | |
.speak(messages.WELCOME) | |
.reprompt(messages.WHAT_DO_YOU_WANT) | |
.getResponse(); | |
} | |
try { | |
const client = handlerInput.serviceClientFactory.getReminderManagementServiceClient(); | |
const remindersResponse = await client.getReminders(); | |
console.log(JSON.stringify(remindersResponse)); | |
// reminders are retained for 3 days after they 'remind' the customer before being deleted | |
const remindersCount = remindersResponse.totalCount; | |
return responseBuilder | |
.speak(`${messages.WELCOME_REMINDER_COUNT} ${remindersCount}. ${messages.WHAT_DO_YOU_WANT}`) | |
.reprompt(messages.WHAT_DO_YOU_WANT) | |
.getResponse(); | |
} catch (error) { | |
console.log(`error message: ${error.message}`); | |
console.log(`error stack: ${error.stack}`); | |
console.log(`error status code: ${error.statusCode}`); | |
console.log(`error response: ${error.response}`); | |
if (error.name === 'ServiceError' && error.statusCode === 401) { | |
console.log('No reminders permissions (yet). Skipping reporting on reminder count.'); | |
return responseBuilder | |
.speak(messages.WELCOME) | |
.reprompt(messages.WHAT_DO_YOU_WANT) | |
.getResponse(); | |
} | |
if (error.name !== 'ServiceError') { | |
console.log(`error: ${error.stack}`); | |
const response = responseBuilder.speak(messages.ERROR).getResponse(); | |
return response; | |
} | |
throw error; | |
} | |
}, | |
}; | |
const CreateReminderHandler = { | |
canHandle(handlerInput) { | |
const request = handlerInput.requestEnvelope.request; | |
return request.type === 'IntentRequest' && request.intent.name === 'CreateReminderIntent'; | |
}, | |
async handle(handlerInput) { | |
const requestEnvelope = handlerInput.requestEnvelope; | |
const responseBuilder = handlerInput.responseBuilder; | |
const consentToken = requestEnvelope.context.System.apiAccessToken; | |
// check for confirmation. if not confirmed, delegate | |
switch (requestEnvelope.request.intent.confirmationStatus) { | |
case 'CONFIRMED': | |
// intent is confirmed, so continue | |
console.log('Alexa confirmed intent, so clear to create reminder'); | |
break; | |
case 'DENIED': | |
// intent was explicitly not confirmed, so skip creating the reminder | |
console.log('Alexa disconfirmed the intent; not creating reminder'); | |
return responseBuilder | |
.speak(`${messages.NO_REMINDER} ${messages.WHAT_DO_YOU_WANT}`) | |
.reprompt(messages.WHAT_DO_YOU_WANT) | |
.getResponse(); | |
case 'NONE': | |
default: | |
console.log('delegate back to Alexa to get confirmation'); | |
return responseBuilder | |
.addDelegateDirective() | |
.getResponse(); | |
} | |
if (!consentToken) { | |
return responseBuilder | |
.speak(messages.NOTIFY_MISSING_PERMISSIONS) | |
.withAskForPermissionsConsentCard(PERMISSIONS) | |
.getResponse(); | |
} | |
try { | |
const client = handlerInput.serviceClientFactory.getReminderManagementServiceClient(); | |
const reminderRequest = { | |
trigger: { | |
type: 'SCHEDULED_RELATIVE', | |
offsetInSeconds: '30', | |
}, | |
alertInfo: { | |
spokenInfo: { | |
content: [{ | |
locale: 'en-US', | |
text: 'time to get up and dance', | |
}], | |
}, | |
}, | |
pushNotification: { | |
status: 'ENABLED', | |
}, | |
}; | |
const reminderResponse = await client.createReminder(reminderRequest); | |
console.log(JSON.stringify(reminderResponse)); | |
} catch (error) { | |
if (error.name !== 'ServiceError') { | |
console.log(`error: ${error.stack}`); | |
const response = responseBuilder.speak(messages.ERROR).getResponse(); | |
return response; | |
} | |
throw error; | |
} | |
return responseBuilder | |
.speak(messages.REMINDER_CREATED) | |
.getResponse(); | |
}, | |
}; | |
const MessageHandler = { | |
canHandle(handlerInput){ | |
return handlerInput.requestEnvelope.request.type === 'Messaging.MessageReceived'; | |
}, | |
async handle(handlerInput){ | |
const { requestEnvelope, serviceClientFactory } = handlerInput; | |
const client = serviceClientFactory.getReminderManagementServiceClient(); | |
let reminder; | |
try { | |
reminder = await client.getReminders(); | |
console.log(`[INFO] reminders: ${JSON.stringify(reminder)}`); | |
} | |
catch(error){ | |
console.log(error); | |
} | |
} | |
}; | |
const SessionEndedRequestHandler = { | |
canHandle(handlerInput) { | |
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest'; | |
}, | |
handle(handlerInput) { | |
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`); | |
return handlerInput.responseBuilder.getResponse(); | |
}, | |
}; | |
const UnhandledHandler = { | |
canHandle() { | |
return true; | |
}, | |
handle(handlerInput) { | |
return handlerInput.responseBuilder | |
.speak(messages.UNHANDLED) | |
.reprompt(messages.UNHANDLED) | |
.getResponse(); | |
}, | |
}; | |
const HelpHandler = { | |
canHandle(handlerInput) { | |
const request = handlerInput.requestEnvelope.request; | |
return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent'; | |
}, | |
handle(handlerInput) { | |
return handlerInput.responseBuilder | |
.speak(messages.HELP) | |
.reprompt(messages.HELP) | |
.getResponse(); | |
}, | |
}; | |
const CancelStopHandler = { | |
canHandle(handlerInput) { | |
const request = handlerInput.requestEnvelope.request; | |
return request.type === 'IntentRequest' | |
&& (request.intent.name === 'AMAZON.CancelIntent' | |
|| request.intent.name === 'AMAZON.StopIntent'); | |
}, | |
handle(handlerInput) { | |
return handlerInput.responseBuilder | |
.speak(messages.GOODBYE) | |
.getResponse(); | |
}, | |
}; | |
const ErrorHandler = { | |
canHandle(handlerInput, error) { | |
return error.name === 'ServiceError'; | |
}, | |
handle(handlerInput, error) { | |
// console.log(`ERROR STATUS: ${error.statusCode}`); | |
console.log(`ERROR MESSAGE: ${error.message}`); | |
// console.log(`ERROR RESPONSE: ${JSON.stringify(error.response)}`); | |
// console.log(`ERROR STACK: ${error.stack}`); | |
switch (error.statusCode) { | |
case 401: | |
return handlerInput.responseBuilder | |
.speak(messages.NOTIFY_MISSING_PERMISSIONS) | |
.withAskForPermissionsConsentCard(PERMISSIONS) | |
.getResponse(); | |
case 403: | |
return handlerInput.responseBuilder | |
.speak(`${messages.UNSUPPORTED_DEVICE} ${messages.WHAT_DO_YOU_WANT}`) | |
.reprompt(messages.WHAT_DO_YOU_WANT) | |
.getResponse(); | |
default: | |
return handlerInput.responseBuilder | |
.speak(messages.API_FAILURE) | |
.getResponse(); | |
} | |
}, | |
}; | |
const RequestLog = { | |
async process(handlerInput) { | |
console.log(`REQUEST ENVELOPE = ${JSON.stringify(handlerInput.requestEnvelope)}`); | |
}, | |
}; | |
const ResponseLog = { | |
process(handlerInput) { | |
console.log(`RESPONSE = ${JSON.stringify(handlerInput.responseBuilder.getResponse())}`); | |
}, | |
}; | |
const skillBuilder = Alexa.SkillBuilders.custom(); | |
exports.handler = skillBuilder | |
.addRequestHandlers( | |
LaunchRequestHandler, | |
CreateReminderHandler, | |
MessageHandler, | |
SessionEndedRequestHandler, | |
HelpHandler, | |
CancelStopHandler, | |
UnhandledHandler, | |
) | |
.addRequestInterceptors(RequestLog) | |
.addResponseInterceptors(ResponseLog) | |
.addErrorHandlers(ErrorHandler) | |
.withApiClient(new Alexa.DefaultApiClient()) | |
.withCustomUserAgent('cookbook/reminders/v1') | |
.lambda(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment