thunderbirdthunderbird-addonthunderbird-lightning

how to let thunderbird calender event trigger a shell script?


I need to update the messenger's status when there is a calender event is happening in Thunderbird. Is it possible to hook the existing alarm?


Solution

  • Do you want to update the status any time there is an event, or when an alarm fires? Unfortunately for both options there is no built-in way. You would have to create an extension that listens to the respective events and then connects with your messenger.

    Any time there is an event

    Ideally there would be an observer service notification when an event is in progress and when it ends, but internally we didn't come across a situation where we needed this yet. Its a very nice feature request, so if you'd like to add this feature to core and then use if from your extension please let me know.

    Anyway, one way to handle this would be to run a timer every 15 minutes or so that retrieves items from all enabled calendars for the current time. When the timer fires, you can request events at the current time from all calendars. To do so, you should:

    // Create a composite calendar
    var composite = Components.classes["@mozilla.org/calendar/calendar;1?type=composite"]
                              .createInstance(Components.interfaces.calICompositeCalendar);
    
    // Add all current calendars into the composite
    var calendars = cal.getCalendarManager().getCalendars({});
    for (let calendar of calendars) {
        if (!calendar.getProperty("disabled")) {
            composite.addCalendar(calendar);
        }
    }
    
    // In newer versions of Lightning you can use calAsyncUtils.jsm like this:
    var pcal = cal.async.promisifyCalendar(composite);
    var now = cal.now();
    pcal.getItems(Components.interfaces.calICalendar.ITEM_FILTER_ALL_ITEMS, 0, now, now).then(function(items) {
       if (items.length) {
           // Something is going on right now
       } else {
           // Nothing is going on
       }
    });
    

    If you want to improve on this, you could at startup get the next event occurring and set the timer interval accordingly. This way you don't have empty timer runs and a more exact result.

    When an alarm fires

    This is far simpler. You can listen to the alarm service to determine when an alarm fires and act upon it.

    cal.getAlarmService().addObserver({
        onAlarm: function(aItem, aAlarm) {
            // Alarm fired, update your messenger
        },
        onRemoveAlarmsByItem: function(item) {},
        onRemoveAlarmsByCalendar: function(calendar) {},
        onAlarmsLoaded: function() {}
    });