Just ask Alexa for Today In History to get a brief description of historical events, birth, death and aviation events on any date, including today. Alexa will give you five (5) events for the date you tell her, then she will ask you if you want to go deeper into history. This will continue until you say 'no' .
For the moment, This day in history API is limited to 4 types of queries: aviation, birth, death and event queries. Get started by saying "Alexa, ask Today In History".
When you first invoke Today In History, you will query event history. To change query type, says "change type".
Note: Since there are a lot of tutorials which describe how to setup Lambda and Alexa skill. Please follow the link listed below to setup this skill.
Setup Alexa SkillFollow Step 1. Setting up Your Alexa Skill in the Developer Portal of this guide. Intent Schema and Sample Utterances are provided in the code section below.
Setup AWS LambdaFollow Step 2: Creating Your Skill Logic Using AWS Lambda of this guide. Use the index.js and package.json at the code section to setup the Lambda zip file. Refer to Alexa Skills Kit SDK for Node.js for details.
Link Lambda to skillFollow Step 3: Add Your Lambda Function to Your Skill of this guide.
Test the skillFollow Step 4: Testing Your Skill of the same guide above.
.
Code (node.js)The code starts with setting up app ID, API options and a few default values like pageSize and pageNo.
var appId = 'amzn1.echo-sdk-ams.app.your-skill-id';
var http = require("http");
var optionsGet = {
host : 'api.hiztory.org',
port : 80,
path : '',
method : 'GET'
};
var parseString = require('xml2js').parseString;
var pageSize = 5;
var pageNo = 1;
var month = '';
var day = '';
This registers the various handlers of the skill.
alexa.registerHandlers(newSessionHandlers, startHistoryHandlers, queryHistoryHandlers, queryEventHandlers, changeTypeHandlers);
Then set the skill's states and query type values. There are three states and four types.
var states = {
STARTMODE: '_STARTMODE', // prompt the user to start or restart
TYPEMODE: '_TYPEMODE', // changing query type
QUERYMODE: '_QUERYMODE' // user querying history
};
var types = ['events', 'births', 'deaths', 'aviation'];
There are a few intent handler functions. The important one are QueryEventIntent, NextEventIntent, ChangeTypeIntent and SelectTypeIntent. These intents are invoked depending on the states explained in the Voice UI section below.
'QueryEventIntent': function () {
pageNo = 1;
var daySlot = this.event.request.intent.slots.day;
var date = '';
// If the user provides a date, then use that, otherwise use today
// The date is in server time, not in the user's time zone. So "today" for the user may actually be tomorrow
if (daySlot && daySlot.value) {
date = new Date(daySlot.value);
} else {
date = new Date();
}
month = ('0' + (date.getMonth()+1)).slice(-2);
day = ('0' + date.getDate()).slice(-2);
this.emit('QueryEvent', this);
},
.
'NextEventIntent': function () {
pageNo += 1;
this.emit('QueryEvent', this);
},
.
'ChangeTypeIntent': function() {
this.handler.state = states.TYPEMODE;
this.emit('ChangeType');
},
.
'SelectTypeIntent': function() {
this.handler.state = states.STARTMODE;
this.emit('SelectType', this);
},
.
In additional to the above intent functions, there are a few handler helper functions which actual carry out the work: QueryEvent, ChangeType and SelectType functions.
QueryEvent is the main function which actually makes the REST call and constructs the output speech.
'QueryEvent': function(that) {
optionsGet.path = "/" + that.attributes['queryType'] + "/" + month + "/" + day + "/"+ pageNo + "/" + pageSize + "/api.xml";
console.log(optionsGet.path);
var message = '';
// do the GET request
var reqGet = http.request(optionsGet, function(res) {
console.log("statusCode: ", res.statusCode);
// uncomment it for header details
// console.log("headers: ", res.headers);
res.on('data', function(d) {
//var obj = JSON.parse(d);
parseString(d, {explicitRoot: false, mergeAttrs: true}, function (err, result) {
console.log(JSON.stringify(result));
console.log("\n\nstatus code -> " + result.status[0].code);
if (result.status[0].code == 200) {
var pageNumber = parseInt(result.page[0].number);
var totalPages = parseInt(result.page[0].totalpages);
//message = "You are at page " + pageNumber + ". There are " + totalPages + " pages. ";
message = '';
if (pageNumber < totalPages) {
var count = result.events[0].event.length;
console.log("page no -> " + pageNumber + ", len -> " + count);
for (var i=0; i<count; i++) {
message += result.events[0].event[i].content + ". ";
}
message += "Say yes to go deeper, or say no to end the query.";
that.emit(':ask', message, message);
} else {
that.handler.state = states.STARTMODE;
message += "This is the end of query. Good-bye.";
that.emit(':tell', message);
}
} else {
var message = "Today In History does not response. Please try again later.";
that.emit(':tell', message);
}
console.log('Done');
});
});
res.on('error', function(e) {
console.error(e);
message = "Today In History does not response. Please try again later.";
that.emit(':tell', message);
});
});
reqGet.end();
}
.
'ChangeType': function() {
var message = 'You have a choice of 4 types of query: choose 1 for event, 2 for birth, 3 for death, and 4 for aviation. Say no to end the query.';
this.emit(':ask', message, message)
},
.
'SelectType': function(that) {
var typeSlotValid = isTypeSlotValid(that.event.request.intent);
if (typeSlotValid) {
that.attributes['queryType'] = types[parseInt(that.event.request.intent.slots.type.value)-1];
}
var message = 'Your have changed the query type to ' + that.attributes['queryType'] + '. Which day do you want?, or say no to end the query.';
that.emit(':ask', message, message);
},
.
Voice UI.
Skill LinkHere is the link.
Comments