Saadia Saadia - 3 months ago 31
PHP Question

Generate and Send .ics file via Symfony2 (Swift Mailer)

I am trying to generate a calendar event MS Outlook/Google Calendar in Symfony2, while the email is sent with .ics file but I am not able to get the event added to calendar. When I try to open the file it says

Failed to import events: Unable to process your iCal/CSV file..


This is how I am trying to generate the iCal file

$message="
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:".date('Ymd\THis', strtotime($meetingStartTime))."
DTEND:".date('Ymd\THis', strtotime($meetingEndTime))."
DTSTAMP:".date('Ymd\THis', strtotime($meetingStartTime))."
ORGANIZER;CN=XYZ:mailto:do-not-reply@example.com
UID:".rand(5, 1500)."
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP= TRUE;CN=Sample:emailaddress@testemail.com
DESCRIPTION:".$this->getUser()->getName()." requested Phone/Video Meeting Request
LOCATION: Phone/Video
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Meeting has been scheduled by ".$this->getUser()->getName()."
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR";

$messageObject = \Swift_Message::newInstance();
$messageObject->setContentType("text/calendar");
$messageObject->setSubject("Your meeting has been booked")
->setFrom($this->container->getParameter('mailer_user'), "From Name")
->setTo($this->getUser()->getEmail())
->setBody(trim($message));
$this->get('mailer')->send($messageObject);


I will really appreciate if I can get some help on what I am doing wrong which leads to the error of Failed to import events: Unable to process your iCal/CSV file

Answer

You should instead write your iCal file on your server (using the Filesystem component or with native PHP functions like file_put_contents) then send it as attachment:

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;

$fs = new Filesystem();

//temporary folder, it has to be writable
$tmpFolder = '/tmp/';

//the name of your file to attach
$fileName = 'meeting.ics';

$icsContent = "
    BEGIN:VCALENDAR
    VERSION:2.0
    CALSCALE:GREGORIAN
    METHOD:REQUEST
    BEGIN:VEVENT
    DTSTART:".date('Ymd\THis', strtotime($meetingStartTime))."
    DTEND:".date('Ymd\THis', strtotime($meetingEndTime))."
    DTSTAMP:".date('Ymd\THis', strtotime($meetingStartTime))."
    ORGANIZER;CN=XYZ:mailto:do-not-reply@example.com
    UID:".rand(5, 1500)."
    ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP= TRUE;CN=Sample:emailaddress@testemail.com
    DESCRIPTION:".$this->getUser()->getName()." requested Phone/Video Meeting Request
    LOCATION: Phone/Video
    SEQUENCE:0
    STATUS:CONFIRMED
    SUMMARY:Meeting has been scheduled by ".$this->getUser()->getName()."
    TRANSP:OPAQUE
    END:VEVENT
    END:VCALENDAR"
;

//creation of the file on the server
$icfFile = $fs->dumpFile($tmpFolder.$fileName, $icsContent);

//message to include as body to your mail
$body = 'Hello...';

$messageObject = \Swift_Message::newInstance();
$messageObject->setSubject("Your meeting has been booked")
              ->setFrom($this->container->getParameter('mailer_user'), "From Name")
              ->setTo($this->getUser()->getEmail())
              ->setBody($body)
              ->attach(Swift_Attachment::fromPath($tmpFolder.$fileName))
;
$this->get('mailer')->send($messageObject);

//remove the created file
$fs->remove(array('file', $tmpFolder, $fileName));