php - Sending Calendar invite via AWS SES - Error: Duplicate header 'Content-Type'
Get the solution ↓↓↓I am trying to auto-generate calendar invites and send them via SMTP through AWS Simple Email Service (SES). The sending is done via PHPMailer and seems to work with other SMTP servers (unverified), but not with AWS.
It seems that when sending via SES it triggers Amazon to adjust the content headers. No idea how to proceed, appreciate any help as I have to use Amazon as the sending address.
Thank you
Error:
SMTP ERROR: DATA END command failed: 554 Transaction failed: Duplicate header 'Content-Type'.
Code:
// PHPMailer Parameters
$cal_mail = new PHPMailer(true);
//$mail->isSMTP(); // Send using SMTP
$cal_mail->SMTPDebug = 1; // Enable verbose debug output
$cal_mail->SMTPAuth = $smtp_auth; // Enable SMTP authentication
$cal_mail->SMTPSecure = 'tls';
$cal_mail->Host = $smtp_host; // Set the SMTP server to send through
$cal_mail->Port = $smtp_port;
$cal_mail->SMTPKeepAlive = true;
$cal_mail->Mailer = "smtp";
$cal_mail->Username = $smtp_username; // SMTP username
$cal_mail->Password = $smtp_password; // SMTP password
$cal_mail->AddAddress($to_email, $name); // Add a recipient
$cal_mail->SetFrom($from_email, $from_name);
$cal_mail->AddReplyTo($to_email, $to_name);
$cal_mail->isHTML(false); // calendar must be FALSE
$cal_mail->ContentType = 'text/calendar';
$cal_mail->Subject = "Outlook Event";
$cal_mail->addCustomHeader('MIME-version', "1.0");
$cal_mail->addCustomHeader('Content-type', "text/calendar; method=REQUEST; charset=UTF-8");
$cal_mail->addCustomHeader('Content-Transfer-Encoding', "7bit");
$cal_mail->addCustomHeader('X-Mailer', "Microsoft Office Outlook 12.0");
$cal_mail->addCustomHeader("Content-class: urn:content-classes:calendarmessage");
// Create Calendar Body
$ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n";
$ical .= "PRODID:-//BPNSolutions//SalesDept//EN\r\n";
$ical .= "METHOD:REQUEST\r\n";
$ical .= "BEGIN:VEVENT\r\n";
$ical .= "ORGANIZER;SENT-BY=\"MAILTO:[email protected]\":MAILTO:[email protected]\r\n";
$ical .= "ATTENDEE;CN=" . $to_email . ";ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE:MAILTO:" . $to_email . "\r\n";
$ical .= "UID:" . strtoupper(md5($event_id)) . "-bpn-solutions.com\r\n";
$ical .= "SEQUENCE:" . $sequence . "\r\n";
$ical .= "STATUS:" . $status . "\r\n";
$ical .= "DTSTAMP;TZID=Etc/UTC:" . date('Ymd') . 'T' . date('His') . "\r\n";
$ical .= "DTSTART:" . $start . "T" . $start_time . "\r\n";
$ical .= "DTEND:" . $end . "T" . $end_time . "\r\n";
$ical .= "LOCATION:" . $venue . "\r\n";
$ical .= "SUMMARY:" . $summary . "\r\n";
$ical .= "DESCRIPTION:" . $event['description'] . "\r\n";
$ical .= "BEGIN:VALARM\r\n";
$ical .= "TRIGGER:-PT15M\r\n";
$ical .= "ACTION:DISPLAY\r\n";
$ical .= "DESCRIPTION:Reminder\r\n";
$ical .= "END:VALARM\r\n";
$ical .= "END:VEVENT\r\n";
$ical .= "END:VCALENDAR\r\n";
EDIT 1:
the below code successfully generates an email with a.ics
attachment, but MS Outlook for desktop is unable to open / read the attachment, respectively does not trigger any accept/refuse buttons when previewing the email. The same attachment does work perfectly fine on Outlook / Apple Mail for iOS though.
// Create Calendar Body
$ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n";
$ical .= "PRODID:-//Company//SalesDept//EN\r\n";
$ical .= "METHOD:REQUEST\r\n";
$ical .= "NAME: Test1\r\n";
$ical .= "X-WR-CALNAME:Test Calendar\r\n";
$ical .= "BEGIN:VEVENT\r\n";
$ical .= "ORGANIZER;CN=\"Company Name:mailto:[email protected]\r\n";
$ical .= "ATTENDEE;CN=" . $to_email . ";ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE:MAILTO:" . $to_email . "\r\n";
$ical .= "UID:" . md5(uniqid(mt_rand(), true)) . "domain.com\r\n";
$ical .= "SEQUENCE:" . $sequence . "\r\n";
$ical .= "STATUS:" . $status . "\r\n";
$ical .= "DTSTART:" . $start . "T" . $start_time . "Z\r\n";
$ical .= "DTEND:" . $end . "T" . $end_time . "Z\r\n";
$ical .= "DTSTAMP:" . date('Ymd') . 'T' . date('His') . "Z\r\n";
$ical .= "LOCATION:" . $venue . "\r\n";
$ical .= "SUMMARY:" . $summary . "\r\n";
$ical .= "DESCRIPTION:Some descriptive text here.\r\n";
$ical .= "BEGIN:VALARM\r\n";
$ical .= "TRIGGER:-PT15M\r\n";
$ical .= "ACTION:DISPLAY\r\n";
$ical .= "DESCRIPTION:Reminder\r\n";
$ical .= "END:VALARM\r\n";
$ical .= "END:VEVENT\r\n";
$ical .= "END:VCALENDAR\r\n";
$cal_mail->ContentType = 'text/calendar';
$cal_mail->Subject = $summary;
$cal_mail->Body = "This is the body text which is meant to be shown in the email body";
$cal_mail->AltBody = $ical;
$cal_mail->Ical = $ical;
Answer
Solution:
Stop right there. You're trying to undermine all the things that PHPMailer does for you. If you're going to try to build your own messages from scratch, you don't need PHPMailer. PHPMailer has built-in support for sending iCal attachments and message parts, so remove all thoseaddCustomHeader
calls. Sending a message that contains only an ical part is very unlikely to work universally (there has been a lot of discussion related to the problems in various ical clients – short version: both gmail and outlook are absolutely terrible at it) so set a message body, and then add your iCal part after creating your$ical
string:
$cal_mail->Body = 'Here is your calendar invitation';
$cal_mail->Ical = $ical;
And that's all there is to it. All the headers and encoding are taken care of for you.
To debug, you really want to haveSMTPDebug = 2
; 1 is not very useful. Also don't setMailer
directly; callisSMTP()
instead.
Answer
Solution:
After a lot of trial and error and getting it work on either Desktop or Mobile, I finally managed to find the correct combination of$ical
elements to have the Accept / Refuse buttons appear on both MS Outlook for Desktop, Outlook for iOS and Apple Mail. Please note that the below does not work with Gmail.
// Create Calendar Body
$ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n";
$ical .= "PRODID:-//CompanyName//SalesDept//EN\r\n";
$ical .= "METHOD:REQUEST\r\n";
$ical .= "NAME: Test1\r\n";
$ical .= "X-WR-CALNAME:Test Cal\r\n";
$ical .= "BEGIN:VEVENT\r\n";
$ical .= "ORGANIZER;CN=" . $from_name . ":mailto:" . $from_email . "\r\n";
$ical .= "ATTENDEE;CN=" . $to_email . ";ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE:MAILTO:" . $to_email . "\r\n";
$ical .= "UID:" . md5(uniqid(mt_rand(), true)) . "mydomain.com\r\n";
$ical .= "SEQUENCE:" . $sequence . "\r\n";
$ical .= "STATUS:" . $status . "\r\n";
$ical .= "DTSTART:" . $start . "T" . $start_time . "Z\r\n";
$ical .= "DTEND:" . $end . "T" . $end_time . "Z\r\n";
$ical .= "DTSTAMP:" . date('Ymd') . 'T' . date('His') . "Z\r\n";
$ical .= "LOCATION:" . $venue . "\r\n";
$ical .= "SUMMARY:" . $summary . "\r\n";
$ical .= "DESCRIPTION:Some descriptive text here.\r\n";
$ical .= "BEGIN:VALARM\r\n";
$ical .= "TRIGGER:-PT15M\r\n";
$ical .= "ACTION:DISPLAY\r\n";
$ical .= "DESCRIPTION:Reminder\r\n";
$ical .= "END:VALARM\r\n";
$ical .= "END:VEVENT\r\n";
$ical .= "END:VCALENDAR\r\n";
$cal_mail->ContentType = 'text/calendar';
$cal_mail->Subject = $summary;
$cal_mail->Body = "This is the body text";
$cal_mail->AltBody = $ical;
$cal_mail->AddStringAttachment("$ical", "attachment.ics", "base64", "text/calendar; charset=utf-8; method=REQUEST");
$cal_mail->Ical = $ical;
It worth pointing out that MS Outlook for Desktop did not properly show the calendar invite until I added below code, attaching the.ics
attachment to the mail (even though PHPMailer supposedly does that automatically).
Kudos to Frank Van Der Oort who pinpointed this bit here
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: sqlstate[23000]: integrity constraint violation: 1452 cannot add or update a child row: a foreign key constraint fails
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.