DEV Community

Cover image for Adding events to calendar automatically from email
Pavel Kutáč
Pavel Kutáč

Posted on

Adding events to calendar automatically from email

Many email clients can show a small calendar widget with info about event sent in email. That one can also appear in the user's calendar, but only, if is well-formatted.


🇨🇿 V češtině si lze článek přečíst na kutac.cz

Method Request and Attendee

The email client can show info about the event based on attached iCalendar (*.ics) file. However, it must satisfy a few easy requirements:

  1. Attach *.ics file with all information about the event.
  2. Body of the *.ics file must contain property METHOD:REQUEST.
  3. The Content-Type of the attachment must also contain method=REQUEST part.
  4. The Attendee property must be part of the body of iCal file and must contain the email address of the recipient.

Below is the code in PHP for Laravel framework with spatie/icalendar-generator library. For more about sending emails in Laravel framework check the documentation.

use Carbon\Carbon;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Spatie\IcalendarGenerator\Components\Calendar;
use Spatie\IcalendarGenerator\Components\Event;
use Spatie\IcalendarGenerator\Properties\TextProperty;

class EventCreatedNotification extends Notification
{
    // ...

    public function toMail(): MailMessage
    {
        $calendar = Calendar::create()
            ->productIdentifier('Kutac.cz')
            ->event(function (Event $event) {
                $event->name("Email with iCal 101")
                    ->attendee("attendee@gmail.com")
                    ->startsAt(Carbon::parse("2021-12-15 08:00:00"))
                    ->endsAt(Carbon::parse("2021-12-19 17:00:00"))
                    ->fullDay()
                    ->address('Online - Google Meet');
            });
        $calendar->appendProperty(TextProperty::create('METHOD', 'REQUEST'));        

        return (new MailMessage())
            ->subject("Invitation")
            ->markdown('mail.invite.created')
            ->attachData($calendar->get(), 'invite.ics', [
                'mime' => 'text/calendar; charset=UTF-8; method=REQUEST',
            ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

Issues are coming

Everything described above is enough to make it work. But every email client behaves differently. And that produces some issues. In the code I skipped the ->organizer() part, and on purpose. When the organizer is specified, email clients are sending emails when the user accepts or declines the invitation. So it can spam the organizer mailbox. Especially when the system is sending hundreds of emails.

However, web Outlook is sending those emails even if the organizer is not specified. Then the response is sent to the sender email. But what is even worse, Outlook will delete this email after accepting or declining! This can be changed in the settings, but may confuse less skilled users. Especially when the email contains tickets or payment information.

Automatic replies can be filtered out

It is possible to filter out those automatic replies. But it is not so easy, so most likely normal filter in the email client will not be enough. And probably some filter on the email server must be used.

The reply contains the same *.ics file. But instead of REQUEST method, it has method=REPLY in the Content-Type and METHOD:REPLY inside the body of the file.

More than an invitation

GMail supports much more than just a calendar widget. It can show information about your upcoming flights, hotel reservations, or Call to action button directly in the email list. But that is more complicated and you must register your application to have this available. But it is still possible and more can be found on Email markup page.


I would appreciate, if anyone solved some issues described here and would share them in comment.

Top comments (10)

Collapse
 
stian_scholtz_a5dcfbaceae profile image
Stian Scholtz

You deserve a medal! Thanks man

Collapse
 
arxeiss profile image
Pavel Kutáč

You are welcome! I'm always happy, when someone find it useful. I know, that I did not spend some time for nothing.

Collapse
 
oguzhansade profile image
oguzhansade

emergency i've been working like 1 weeks and i need to do something how can i send notification mail to organizer when the clients add event to their calendar there is stackoverflow link for my question please im stuck
stackoverflow.com/questions/739346...

Collapse
 
arxeiss profile image
Pavel Kutáč

I don't know, as I wrote earlier. With organizer it was sending emails for me.

Collapse
 
mohitmehta1996 profile image
mohitmehta1996

Brother, your event will show incorrect time when user is from different timezone. So we should always set time in UTC.

Collapse
 
arxeiss profile image
Pavel Kutáč • Edited

Hi, in this case it really depends on your Laravel settings. The config/app.php file. If you have there set UTC, the invitation will be in UTC. When I set there Europe/Prague, it has in invitation Europe/Prague. But whatever setting you use, it will include timezone details. So it will work for users with different timezone too.

This is result from the code above. So it has timezones and also info about standard and daylight time.

BEGIN:VCALENDAR\r\n
VERSION:2.0\r\n
PRODID:Kutac.cz\r\n
METHOD:REQUEST\r\n
BEGIN:VTIMEZONE\r\n
TZID:Europe/Prague\r\n
BEGIN:DAYLIGHT\r\n
DTSTART:20210328T030000\r\n
TZOFFSETFROM:+0100\r\n
TZOFFSETTO:+0200\r\n
END:DAYLIGHT\r\n
BEGIN:STANDARD\r\n
DTSTART:20211031T030000\r\n
TZOFFSETFROM:+0200\r\n
TZOFFSETTO:+0100\r\n
END:STANDARD\r\n
BEGIN:DAYLIGHT\r\n
DTSTART:20220327T030000\r\n
TZOFFSETFROM:+0100\r\n
TZOFFSETTO:+0200\r\n
END:DAYLIGHT\r\n
END:VTIMEZONE\r\n
BEGIN:VEVENT\r\n
UID:61bcf1ac5cf93\r\n
DTSTAMP;TZID=Europe/Prague:20211217T212308\r\n
SUMMARY:Email with iCal 101\r\n
LOCATION:Online - Google Meet\r\n
ATTENDEE:MAILTO:attendee@gmail.com\r\n
DTSTART;TZID=Europe/Prague;VALUE=DATE:20211215\r\n
DTEND;TZID=Europe/Prague;VALUE=DATE:20211219\r\n
END:VEVENT\r\n
END:VCALENDAR
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lluukinha profile image
Lucas Souza

What happens if you need to update the event?

Collapse
 
arxeiss profile image
Pavel Kutáč

Good question. That should be possible, but I wasn't checking it so much. Maybe tip for future article :)

Collapse
 
zenon profile image
Tomasz Mrozinski • Edited

If you want to update event you should always increase sequence in ics file.
It's quite simple with Spatie lib, you just need to add the following to your event object:

$event->appendProperty(TextProperty::create('SEQUENCE', sequence_value));

initial: sequence_value = 0,
first update: sequence_value = 1
.....
nth update: sequence_value = n

Collapse
 
alihamza509 profile image
Ali Hamza

on send ics file to multiple users email it cannot update guests show only one user as a guest