Sending Smart Invites

In order to have the invite understood correctly by the receiving mail server/client there are a couple of approaches to attaching them required. This ensures that, where supported, the user will also be presented with the Accept/Decline helpers in their email client.

# Using Rails

class SmartInviteMailer < ActionMailer::Base
  def invite(smart_invite)
    event_ics = smart_invite.attachments.icalendar

    attachments.inline["invite.ics"] = {
      content_type: "text/calendar; charset=UTF-8; method=REQUEST",
      encoding: '7bit',
      content: event_ics,
    }

    attachments["invite.ics"] = {
      content_type: "application/ics; charset=UTF-8; method=REQUEST",
      encoding: 'base64',
      content: Base64.encode64(event_ics),
    }

    mail(
      to: smart_invite.recipient.email,
      subject: "Smart Invite Example",
      body: "Here is your invite."
    )
  end
end
// Using the https://github.com/PHPMailer/PHPMailer script

require '../vendor/autoload.php';

$mail = new PHPMailer();

$mail->setFrom('application@example.com');
$mail->addAddress($invite->recipient->email);
$mail->Subject = 'Smart Invite Example';
$mail->Body = 'Here is your invite';

$ics = $invite->attachments->icalendar;
$contentType = 'application/ics; charset=UTF-8; method=REQUEST';

$mail->addAttachment($ics, 'invite.ics', '7bit', $contentType, 'inline');
$mail->addAttachment(base64_encode($ics), 'invite.ics', 'base64', $contentType, 'attachment');

$mail->send();
// Using the https://nodemailer.com/about/ library

const nodemailer = require('../lib/nodemailer');

// TODO configure transport as required
let transporter = nodemailer.createTransport({});

let ics = invite.attachments.icalendar;
let contentType = 'application/ics; charset=UTF-8; method=REQUEST';

let message = {
    to: invite.recipient.email,
    subject: 'Smart Invite Example',
    text: 'Here is your invite',
    attachments: [
        {
            filename: 'invite.ics',
            content: ics,
            contentType: contentType,
            contentDisposition: 'inline'
        },
        {
            filename: 'invite.ics',
            content: Buffer.from(ics, 'base64'),
            contentType: contentType,
            encoding: 'base64'
        },
    ]
};

transporter.sendMail(message, (error, info) => {
    transporter.close();
});
var message = new MailMessage("application@example.com", invite.Recipient.Email);
message.Subject = "Smart Invite Example";
message.Body = "Here is your invite";

var ics = invite.Attachments.ICalendar;

var inlineAttachment = new Attachment(
    new MemoryStream(Encoding.UTF8.GetBytes(ics)),
    "invite.ics",
    "application/ics; charset=UTF-8; method=REQUEST"
);
inlineAttachment.ContentDisposition.Inline = true;

var attachment = new Attachment(
    new MemoryStream(Encoding.UTF8.GetBytes(ics)),
    "invite.ics",
    "application/ics; charset=UTF-8; method=REQUEST"
);

message.Attachments.Add(inlineAttachment);
message.Attachments.Add(attachment);
Search