iCalendar / vCalendar meeting invitation

Probably everybody is familiar with the calendar event invite features?

If you use Microsoft Windows (with Outlook) or Mac OSX (with iCal) or just a basic browser with a GMail account and you use the calendar functionality, you would have realized, that every time you get invited or invite someone to an event, you get a basic email, that adds the recipient to the calendar event.

I had to write an invitation tool that was cross compatible between different platforms and integrated with SugarCRM for a customer of InsightfulCRM (Australian SugarCRM Gold Partner) where I work.

I started from some samples, and by reading the RFC of the protocol and the iCalendar Wikipedia entry.

According to the protocol RFC and the Wikipedia entry, the iCalendar and vCalendar seems really similar, so we can use the common items to create a meeting invite.

Let’s pick a basic sample so that we can run some tests on:

BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20100616T080000Z
DTEND:20100616T090000Z
DTSTAMP:20100616T075116Z
ORGANIZER;CN=Enrico Simonetti:mailto:enrico@test.com
UID:12345678
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP= TRUE;CN=Sample:mailto:sample@test.com
DESCRIPTION:Complete event on http://www.sample.com/get_event.php?id=12345678
LOCATION: Sydney
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Test iCalendar
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

Now, how do we send this event?
It is pretty simple.
We need a specific set of headers on the email, and the content of the email has to be the structured meeting code itself.
(No, it is not an attachment, also if you see an attached file!)

The headers are exactly as below:

$headers = "From: Enrico <enrico@test.com>\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: text/calendar; method=REQUEST;\n";
$headers .= '        charset="UTF-8"';
$headers .= "\n";
$headers .= "Content-Transfer-Encoding: 7bit";

NB: be REALLY careful with the spacing. Apparently calendars are really really fragile, and if you only remove a space, it will result on Outlook removing the buttons at the top of the email itself, where you can accept/reject the meeting, or/and even the attendees will disappear from the list!
It really caused me a lot of headache!

Now we can actually send the above calendar invite, as body of the email, structuring the meeting as per above sample, inside the content of $message variable.

$subject = "Meeting Subject";
$subject = html_entity_decode($subject, ENT_QUOTES, 'UTF-8');
mail("sample@test.com", $subject, $message, $headers);

Of course you will have to send an email for each attendee.

There you go, you just invited your attendee to meeting with id ‘12345678’!

As simple as that!

14 thoughts on “iCalendar / vCalendar meeting invitation

  1. Wow… you make it sound so simple. I’m sure there was plenty more blood, sweat and tears to get to the end result, right. But, yes, it’s now done and it’s a cool extra piece of functionality for SugarCRM!

  2. Hello there,

    I just tried your solution only i can’t get it to work.

    I am currently using SugarCRM 6.1.3 on windows 7.
    I created a logic hook before_save, in Meetings module.
    The hook calls a file(sendEmailMeeting.php)which contains the following code:
    bean->location;

    $headers = “From: SugarCRM \n”;
    $headers .= “MIME-Version: 1.0\n”;
    $headers .= “Content-Type: text/calendar; method=REQUEST;\n”;
    $headers .= ‘ charset=”UTF-8″‘;
    $headers .= “\n”;
    $headers .= “Content-Transfer-Encoding: 7bit\n”;

    $subject = $this->bean->name;
    $subject = html_entity_decode($subject, ENT_QUOTES, ‘UTF-8’);

    $message= “BEGIN:VCALENDAR
    VERSION:2.0
    CALSCALE:GREGORIAN
    METHOD:REQUEST
    BEGIN:VEVENT
    DTSTART:20110616T080000Z
    DTEND:20110616T090000Z
    DTSTAMP:20110616T075116Z
    ORGANIZER;CN=SugarCRM:mailto:some.body@mycomp.com
    UID:1
    ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP= TRUE;CN=Sample:mailto:sample@test.com
    DESCRIPTION:Complete event on http://www.sample.com/get_event.php?id=1
    LOCATION: $location
    SEQUENCE:0
    STATUS:CONFIRMED
    SUMMARY:Test iCalendar
    TRANSP:OPAQUE
    END:VEVENT
    END:VCALENDAR”;

    mail(“mytarget@somecompany.com”, $subject, $message, $headers);

    }
    }
    ?>

    Can you please tell me what is it I am missing??
    Thanks a lot in advance.
    Cheers

  3. Great tutorial! I’ve noticed that it didn’t worked properly with Mozilla Thunderbird. I’ve modified the headers by looking at the source of a ‘real’ invite, and I came up with this and it works fine:

    $headers = “Return-Path: \n”;
    $headers .= “From: My Name \n”;
    $headers .= “MIME-Version: 1.0\n”;
    $headers .= “Content-class: urn:content-classes:calendarmessage\n”;
    $headers .= “Content-Type: text/calendar; method=REQUEST; component=VEVENT; name=meeting.ics;\n”;
    $headers .= ‘ charset=”UTF-8″‘;
    $headers .= “\n”;
    $headers .= “Content-Transfer-Encoding: 7bit”;

  4. I would suggest you to double check the exact number of spaces and tabs on the invite’s content.
    If still does not work, try viewing the source of a real invite generated with Outlook and check your code against it…

  5. “Of course you will have to send an email for each attendee.” – does that mean we need to send an email to each attendee – ie as a template email.

    or does this script work with the meeting invite module – ie the normal “save & send invites” functionality in the “create meeting” section?

  6. Hi Horus and thanks for the comment!

    Are you referring to SugarCRM? Well… I actually wrote this blog post back in 2010 and SugarCRM was quite different at the time. Now the “Save and Send Invites” button on meetings should actually send all the people invited an email with a SugarCRM url to accept/reject the meeting and also an “.ics” iCal file that can be used to add the meeting to your calendar application.

    Sugar also allows you to publish your internal calendar in read only mode to iCal compatible applications.

    You can read more about SugarCRM meetings for the SugarCRM 7.1 Professional version at this url.

    If you need any help on training, consulting or customisations for your SugarCRM system, and you are in the APAC region, you can contact our InsightfulCRM office any time!

    This tutorial can anyway still be useful if you have any PHP application that you want to add iCal functionality to.

  7. Thanks Enrico

    The issue is that when an invite goes out and someone clicks the “Accept this meeting:” url in the invite – it changes the status in sugar – but it does not add the event to the invitees calendar – and many people will not realise they need to download the .ics file. And even if they do – how do they add that to their gmail account – rather than outlook?

  8. Horus,

    Are the people you invite SugarCRM users, and have Gmail/Google Apps accounts? If that’s the case, then that’s easy. They can use the the iCal url from SugarCRM and import that as the “SugarCRM calendar” inside Google Calendar.
    As soon as they push the “Accept” button on the email invite, the calendar url updates and shows the appointment in Google Calendar.

    Alternatively, if they are on a SugarCRM Commercial version, and they are Outlook users on Windows, they can use the Outlook plugin included in the subscription to sync the calendar and meetings in both directions.

    I guess you just have to figure out which one is your customer’s main calendar. Will it be SugarCRM’s calendar? Will it be Google Calendar? Depending on that, you can then design your solution accordingly or use the out-of-the-box SugarCRM solution.

    Hope it helps.

  9. Hi Again Enrico

    I’m using Version 6.5.16 CE – and the people send appointments to are using Google Calendar and some Outlook – They are not Sugar users.

    The existing out-of-the-box setup sets appointments but it doesn’t seem to pu them into Google Calendar.

    When they click accept – it updates thier status in sugar – but does not put the meeting into their calendar unless they download the .ics

    I’m hoping to set appointments in sugar that will go directly into their calendar when they click accept.

    I didn’t have much luck playing with your code above.

    Any suggestions would be appreciated :)

  10. Horus,

    I have the feeling you are trying to do too many things with one feature.

    If you still want to achieve both things, you could customise the email template to have a more precise wording that explains the two different actions:
    – To let whoever invited you to the meeting know if you are actually going, click on accept/reject etc.
    – To add this meeting to your own calendar, click on the .ics file.

    I think you can either make it more clear for the user on what they are trying to do (as described above), or remove one of the two functionalities and make it work seamlessly, just one of the two ways.

    Also, in the past few days SugarCRM opened a new community forum here http://community.sugarcrm.com maybe it is worthwhile asking the question there too?

    Good luck!

    Enrico

Leave a Comment