Notify when too far(in current traffic) from my next event(s)

Reminds you to get going to an event in your calendar based on the time it will take to get "there" in current traffic.

Using the calendar method I posted on http://onxmarket.com/GoogleCalendarWorkaround

Recipe made in response to https://dev.onx.ms/forums/topic/suggestion-rule/#post-1419

Usage
Set the "feed" , to any Google calendar feed. Make sure to use the "full" version of the feed.
var userAccount = {feed: "https://www.google.com/calendar/feeds/your_calendar_feed_here/full"};
settings.checkInterval  The interval for checking upcoming events
settings.reminderMinutes  Number of minutes before "running late" to get the notification

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);
            }
        );      
    });

Recipe Wall

891

Views