0

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?

user1532146
  • 184
  • 2
  • 14

1 Answers1

0

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() {}
});
Philipp Kewisch
  • 982
  • 6
  • 20
  • I tried to follow addon SDK tutorial (https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Getting_started), I put the second piece of your code as the main.js under my-addon/lib/, and then I ran "cfx run", and I got error log : use 'Components' to access chrome authority. To do so, you need to add a line somewhat like the following: const {Cc,Ci} = require("chrome"); – user1532146 May 07 '15 at 15:06
  • If you replace `Components.classes` with `Cc` and `Components.interfaces` with `Ci` in the examples above, it might work with `const {Cc,Ci,Cu} = require("chrome");`. You will also need to do `Cu.import("resource://calendar/modules/calUtils.jsm");` to get the cal. namespace. That last line might also work with require() instead. – Philipp Kewisch May 08 '15 at 16:00
  • Note also that the Add-ons SDK and cfx tool was written for Firefox. While it may sometimes work for Thunderbird, I don't think its a really great experience. The alternative is to create an [overlay addon](https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions), which works very well with the disadvantage that the addon is not restartless. You can also create a [bootstrapped addon](https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions) which is somewhere inbetween the two. – Philipp Kewisch May 08 '15 at 16:03