Reminds you to get going to an event in your calendar based on the time it will take to get "there" in current traffic.
To use this on{X} Recipe, simply copy the code below and modify if needed.
// This is a sample code for a basic rule you can create.
var userAccount = {feed: "https://www.google.com/calendar/feeds/your_calendar_feed_here/full"};
var settings = {checkInterval: "hour", reminderMinutes: 30};
// modify with care, implementaion depends on the specific parameters
var googleQueryParams = "alt=json&ctz=UTC&max-results=5&singleevents=false&futureevents=true&orderby=starttime&sortorder=ascending&fields=title,entry(title,gd:when,gd:where)";
// calculates the time form current location to the specified destination
function getTimeToDestination(event, destination, timeCallbackSuccess) {
var currentLocation = device.location.lastLocation.location;
var fromTo = [ currentLocation.latitude +','+ currentLocation.longitude,
destination];
feeds.traffic.get({wps: fromTo, unittype: 'm'},
function(traffic, textStatus, response) {
console.info('The traffic duration for '+ destination +' is: '+ traffic.totalTravelDuration +'sec');
// duration is given in seconds, modify to minutes
timeCallbackSuccess(event, traffic.totalTravelDuration / 60);
},
function(response, textStatus) {
console.error('getting traffic to '+ destination +' returned error : ' + textStatus);
}
);
}
console.log('CheckMyCalendar started');
device.scheduler.setTimer({ name: "meetingTooFarCheck", time: 0, interval: settings.checkInterval, exact: false },
function () {
console.log('get upcomming meetings from ' + userAccount.feed);
// get the upcoming meetings
device.ajax(
{
url: userAccount.feed + '?' + googleQueryParams,
type: 'GET',
headers: {'Content-Type': 'application/json'}
},
function onSuccess(body, textStatus, response) {
console.log(textStatus);
var feed;
if (!(body && (feed = JSON.parse(body)))) {
console.error('invalid body format');
return;
}
// get the actual feed
feed = feed.feed;
// check we have any entries
if (!feed || !feed.entry) {
console.info('no future events for '+ feed.title.$t);
return;
}
// process the events
var eventCount = feed.entry.length;
console.info('got '+ eventCount +' events for '+ feed.title.$t);
// get check upcoming events
for (var i = 0; i < eventCount; i++) {
var eventEntry = feed.entry[i];
if (!eventEntry.gd$where || !eventEntry.gd$where[0].valueString) {
// no location
console.log('no location for: ' + eventEntry.title.$t);
continue;
}
// calculate time to destination
getTimeToDestination(eventEntry, eventEntry.gd$where[0].valueString, function(event, minutes) {
var title = event.title.$t;
var startTime = new Date(event.gd$when[0].startTime);
if (!startTime || isNaN(startTime.getTime())) {
console.error(title +' bad date: ' + event.gd$when[0].startTime);
return;
}
var now = new Date();
var minutesToStartTime = Math.floor(startTime.getTime() - now.getTime()) / (60 * 1000);
// no need to notify, it's too late
if (minutesToStartTime < settings.reminderMinutes) {
console.log(title +' under reminder limit');
return;
}
var minutesToArrive = Math.floor(minutes + settings.reminderMinutes); // arrive + buffer
// check if we can arrive on time
if (minutesToStartTime < minutesToArrive) {
var notification = device.notifications.createNotification('Running late for ' + title);
notification.content = 'Takes '+ Math.floor(minutes) +'minutes to get there';
notification.on('click', function() {
device.browser.launch(event.link[0].href);
});
notification.show();
}
});
}
},
function onError(textStatus, response) {
console.error(textStatus);
}
);
});
Views