-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
'use strict'; | ||
|
||
const alexa = require('alexa-app'); | ||
const endpoint = require('./src/api/endpoints'); | ||
const getData = require('./src/helpers/get-data').getData; | ||
const modelData = require('./src/helpers/model-data').modelData; | ||
|
||
const app = new alexa.app('passport'); | ||
|
||
// Launch welcome | ||
|
||
app.launch((request, response) => { | ||
response.say('Welcome to Passport, an unofficial skill, where you can get ask about info on current travel warnings and alerts issued by the U.S. State Department. You can ask things like: "Is it safe in Syria?" or "What is the status of Sudan?". You can even get information explaining the different advisories, by asking things like, "What is the difference between a warning and an alert?". Go ahead, ask away.'); | ||
}); | ||
|
||
// // Get definition for travel warning | ||
|
||
app.intent('GetWarningDefinition', { | ||
utterances: ['what is a travel warning'] | ||
}, (request, response) => { | ||
return Promise.all([getData(endpoint.warningsURL)]).then(res => modelData(res)).then(res => { | ||
response.say(`${res.warnings.description}`); | ||
}).catch(error => { | ||
response.say(`I'm sorry, but I'm having a little trouble with your request. It seems that there is the following error: ${error}.`); | ||
}); | ||
}); | ||
|
||
// Definition for a travel alert | ||
|
||
app.intent('GetAlertDefinition', { | ||
utterances: ['what is a travel alert'] | ||
}, (request, response) => { | ||
return Promise.all([getData(endpoint.alertsURL)]).then(res => modelData(res)).then(res => { | ||
response.say(`${res.alerts.description}`); | ||
}).catch(error => { | ||
response.say(`I'm sorry, but I'm having a little trouble with your request. It seems that there is the following error: ${error}.`); | ||
}); | ||
}); | ||
|
||
// Difference between a travel warning and travel alert (definitions) | ||
|
||
app.intent('GetAlertAndWarningDefinition', { | ||
utterances: ['what is the difference between a warning and an alert'] | ||
}, (request, response) => { | ||
return Promise.all([getData(endpoint.warningsURL), getData(endpoint.alertsURL)]).then(res => modelData(res)).then(res => { | ||
response.say(`${res.warnings.description}. meanwhile, ${res.alerts.description}.`); | ||
}).catch(error => { | ||
response.say(`I'm sorry, but I'm having a little trouble with your request. It seems that there is the following error: ${error}.`); | ||
}); | ||
}); | ||
|
||
// Find country status | ||
|
||
app.intent('GetCountryStatus', { | ||
slots: { country: 'AMAZON.Country' }, | ||
utterances: ['is it safe in {-|country}', 'should I visit {-|country}', 'is it ok to visit {-|country}', 'is it dangerous in {-|country}', 'how are things in {-|country}', 'what is the status of {-|country}', 'what is going on in {-|country}', 'is there any reason to not visit {-|country}', 'does {-|country} have any warnings or alerts'] | ||
}, (request, response) => { | ||
const phrase = request.slot('country').toLowerCase(); | ||
|
||
return Promise.all([getData(endpoint.warningsURL), getData(endpoint.alertsURL)]).then(res => modelData(res)).then(res => { | ||
let searchResult = null; | ||
|
||
res.warnings.list.forEach(item => { | ||
if (item.country.includes(phrase)) { | ||
searchResult = { | ||
type: 'warning', | ||
details: item | ||
}; | ||
} | ||
}); | ||
|
||
res.alerts.list.forEach(item => { | ||
if (item.country.includes(phrase)) { | ||
searchResult = { | ||
type: 'warning', | ||
details: item | ||
}; | ||
} | ||
}); | ||
|
||
if (searchResult) { | ||
response.say(`There is currently a travel ${searchResult.type} in effect for ${searchResult.details.country}. This travel ${searchResult.type} was issued on ${searchResult.details.issuedAt}. ${searchResult.details.description}. For the most accurate and up to date travel advisories, please visit the U.S. State Department's web site at www.state.gov or by calling the State Department directly at (202) 647-6575.`); | ||
} else { | ||
response.say(`I don't see any current travel warnings or alerts for ${phrase}, however, for the most accurate and up to date travel advisories, please visit the U.S. State Department's web site at www.state.gov or by calling the State Department directly at (202) 647-6575.`); | ||
} | ||
}).catch(error => { | ||
response.say(`I'm sorry, but I'm having a little trouble with your request. It seems that there is the following error: ${error}.`); | ||
}); | ||
}); | ||
|
||
// Find number of total warnings and alerts | ||
|
||
app.intent('GetCount', { | ||
utterances: ['how many alerts are there', 'how many alerts are issued', 'how many warnings are there', 'how many warnings are issued'] | ||
}, (request, response) => { | ||
return Promise.all([getData(endpoint.warningsURL), getData(endpoint.alertsURL)]).then(res => modelData(res)).then(res => { | ||
const warningPlaces = []; | ||
const alertPlaces = []; | ||
|
||
res.alerts.list.forEach(item => alertPlaces.push(item.country)); | ||
res.warnings.list.forEach(item => warningPlaces.push(item.country)); | ||
|
||
response.say(`The U.S. State Department currently has ${res.alerts.list.length} issued travel alerts and ${res.warnings.list.length} issued travel warnings. Travel alerts have been issued for the following reasons: ${alertPlaces.join(', ')}. Travel warnings have been issued for the following ${res.warnings.list.length} countries: ${warningPlaces.join(', ').sort()}`); | ||
}).catch(error => { | ||
response.say(`I'm sorry, but I'm having a little trouble with your request. It seems that there is the following error: ${error}.`); | ||
}); | ||
}); | ||
|
||
exports.handler = app.lambda(); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const warningsURL = 'https://travel.state.gov/_res/rss/TWs.xml'; | ||
const alertsURL = 'https://travel.state.gov/_res/rss/TAs.xml'; | ||
|
||
module.exports = { | ||
warningsURL, | ||
alertsURL | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const fetch = require('node-fetch'); | ||
|
||
const getData = url => { | ||
return new Promise((resolve, reject) => { | ||
fetch(url).then(res => { | ||
res.status === 200 ? resolve(res.text()) : reject(res.status); | ||
}); | ||
}); | ||
}; | ||
|
||
module.exports = { getData }; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const parseString = require('xml2js').parseString; | ||
|
||
const modelData = data => { | ||
const notices = { | ||
warnings: {}, | ||
alerts: {} | ||
}; | ||
|
||
data.forEach(dataObj => { | ||
parseString(dataObj, (err, res) => { | ||
const advisory = res.rss.channel[0]; | ||
const title = advisory.title[0]; | ||
const type = title.toLowerCase().includes('warning') ? 'warnings' : 'alerts'; | ||
notices[type].title = `travel ${type}`; | ||
notices[type].description = advisory.description[0].toLowerCase(); | ||
notices[type].list = []; | ||
advisory.item.forEach(detail => { | ||
notices[type].list.push({ | ||
country: detail.title[0].toLowerCase().replace(/ travel (warning|alert)/g, ''), | ||
issuedAt: detail.pubDate[0].replace(/EST/, 'Eastern Standard Time').toLowerCase(), | ||
description: detail.description[0].toLowerCase().replace(/\\n/g, ' ').replace(/\<.*?\>\s?/g, ' ').replace(/\&.*?\;\s?/g, ' ') | ||
}); | ||
}); | ||
}); | ||
}); | ||
return notices; | ||
}; | ||
|
||
module.exports = { modelData }; |