Adding Events to Users Calendars – Part 1 – iCal/vCal

Tuesday 18th December, 2007

I’ve just been figuring out how to use iCal/vCal to add events to users calendars and the resources I found were a little dry so here’s a quick and dirty HOWTO.

Set up some code on your server to return the text below, and set the “Content-Type” header of the HTTP Response to text/calendar

Getting something working

First up I tried getting a basic event into Outlook (the calendar I have to hand). I found that without the DTSTAMP field Outlook threw a non-specific wobbly. When this field is included Outlook treats it as the creation time of the event. More info on the quirks of specific implementations can be found on the relevant Wikipedia article.

My first working file looked something like this:

BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:SOMETHING
DTSTAMP:20071216T000000Z
DTSTART:20071216T000000Z
DTEND:20071216T235959Z
SUMMARY:Test event
DESCRIPTION:Nothing much
END:VEVENT
END:VCALENDAR

Note the VEVENT element nested inside the VCALENDAR element like in XML.

All-day events

This seems to work, although seems to be putting the dates into Outlook an hour later than I would’ve expected (and we’re in GMT not BST so it’s not that). In any case, I want to return these as all-day events since we don’t store the specific time of the event. The format for that seems to be DTSTART;VALUE=DATE:20070930, which makes sense. The VALUE=DATE seems to be a way of specifying the data type for a field, in this case DATE rather than DATE-TIME.

Setting reminders

Next I want to add a reminder to my calendar item. One week should do the trick. Looking at the code below you can see that I’ve nested a VALARM element within the VEVENT element. Using a TRIGGER value of “-PT7D“, I should now get a notification from my calendar a week before the event. You can also use other units, “-PT3H” would be three hours, “-PT5M” would be five minutes, you get the picture.

Alternatively you could input a specific time for the reminder to go off by overriding the TRIGGER field, like this: TRIGGER;VALUE=DATE-TIME:20080117T133000Z.

Final output

This is my final static version with an all-day event and a reminder.

BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:SOMETHING
DTSTAMP;VALUE=DATE:20071201
DTSTART;VALUE=DATE:20071220
DTEND;VALUE=DATE:20071220
SUMMARY:Test event
DESCRIPTION:Nothing much
BEGIN:VALARM
TRIGGER:-PT7D
ACTION:DISPLAY
DESCRIPTION:Reminder to do something
END:VALARM
END:VEVENT
END:VCALENDAR

Done

That’s about as far as I need to go with this, now I just need to hook it into the database and link to it correctly. Let me know if you find this useful, or find mistakes, either way someone’s learning something.

Tip: If you’re trying to debug your iCal response, try using the Firebug plug-in for Firefox. The “Net” tab will show you the response your server is returning.