title: How to send .ics calendar invite through SendGrid so that it renders in email clients?
body: <p>I'm trying to send <code>.ics</code> calendar invites through SendGrid (from Node server) so that it renders in clients like Outlook or Gmail as an actual invitation (with accept/decline buttons) and not just as an attachment file.</p>
  <p>I've spent days researching this (dozens of Stackoverflow questions, <a href="https://www.rfc-editor.org/rfc/rfc5545" rel="noreferrer">RFC-5545</a>, <a href="https://www.rfc-editor.org/rfc/rfc2446" rel="noreferrer">RFC-2446</a>, <a href="https://www.kanzaki.com/docs/ical/" rel="noreferrer">iCalendar Specification Excerpts</a>, Sendgrid's GitHub issues threads: <a href="https://github.com/sendgrid/sendgrid-ruby/issues/298" rel="noreferrer">1</a>, <a href="https://github.com/sendgrid/sendgrid-nodejs/issues/217" rel="noreferrer">2</a>, <a href="https://github.com/sendgrid/sendgrid-ruby/issues/298" rel="noreferrer">3</a>, SendGrid docs, sources etc).</p>
  <p>However, there just doesn't seem to be an answer for this (or am I missing something out?).</p>
  <hr />
  <p>What I've found so far is that <code>Content-Type</code> for the attachment is very important here, especially, <code>method=REQUEST</code> part. And that even <a href="https://stackoverflow.com/a/66151376/4674270">the order of properties in the file makes difference</a>.</p>
  <p>Despite a lot of questions here on SO, most of them remain unanswered for some reason.</p>
  <hr />
  <p>Here's how I set up my <code>attachment</code> object:</p>
  <pre class="lang-js prettyprint-override"><code>const SendGrid = require(&quot;@sendgrid/mail&quot;);
  
    const attachment = {
      filename: 'invite.ics',
      name: 'invite.ics',
      content: Buffer.from(data).toString('base64'),
      disposition: 'attachment',
      contentId: uuid(),
      type: 'application/ics'
    };
  
  SendGrid.send({
        attachments: [attachment],
        templateId,
        from: {
          email: config.emailSender,
          name: config.emailName,
        },
        to: user.email,
        dynamicTemplateData: {
          ...rest,
          user,
        },
        headers: {
          'List-Unsubscribe': `&lt;mailto:unsubscribe.link`,
        },
      });
  </code></pre>
  <hr />
  <p>As for <code>type</code> property, I've tried the following variants:</p>
  <pre><code>1. type: 'text/calendar; method=REQUEST'
  2. type: 'application/ics'
  3. type: 'text/calendar;method=REQUEST;name=\&quot;invite.ics\&quot;'
  4. type: 'text/calendar; method=REQUEST; charset=UTF-8; component=vevent'
  5. type: 'text/calendar'
  </code></pre>
  <p>However, nothing works except <code>'text/calendar'</code> and <code>'application/ics'</code> (and there doesn't seem to be any difference between them).</p>
  <p><code>Content-Type</code> is a reserved header according to the SendGrid docs, so it's not possible to set it somehow through <code>headers</code> property or smth.</p>
  <p>The <code>disposition: 'inline'</code> option also doesn't work at all (only <code>disposition: 'attachment'</code>).</p>
  <hr />
  <p>Here's how the <code>.ics</code> file I generate looks like:</p>
  <pre><code>BEGIN:VCALENDAR
  PRODID:-//Organization//Organization App//EN
  VERSION:2.0
  CALSCALE:GREGORIAN
  METHOD:REQUEST
  BEGIN:VEVENT
  DTSTART:20210426T160000Z
  DTEND:20210426T170000Z
  DTSTAMP:20210418T134622Z
  ORGANIZER;CN=John Smith:MAILTO:john.smith+test1@gmail.com
  UID:dcfd5905-be85-4c8f-8a27-475b0ec67d8b
  ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=John Smith;X-NUM-GUESTS=0:MAILTO:john.smith+test1@gmail.com
  ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=John Test;X-NUM-GUESTS=0:MAILTO:john.smith+test2@gmail.com
  CREATED:20210418T134622Z
  DESCRIPTION:my description
  LAST-MODIFIED:20210418T134622Z
  LOCATION:https://location.url
  SEQUENCE:0
  STATUS:CONFIRMED
  SUMMARY:my summary
  TRANSP:OPAQUE
  END:VEVENT
  END:VCALENDAR
  
  </code></pre>
  <p>The file is perfectly valid and opens seamlessly in iCalendar.</p>
  <p><strong>But why doesn't this get rendered in Outlook or Gmail?</strong></p>
  <p>Currently, the only way to add an event to calendar is to click &quot;download&quot; on the attachment <code>invite.ics</code>, then open it and only after that does the Calendar app get opened and you can confirm the invitation.</p>
  <hr />
  <p>PS: What I mean by <code>rendering</code> the <code>.ics</code> invite is when Outlook or Gmail automatically recognise <code>.ics</code> attachment and display it like on the image below (sorry for the red lines):
  <a href="https://i.stack.imgur.com/St5ZT.png" rel="noreferrer"><img src="https://i.stack.imgur.com/St5ZT.png" alt="enter image description here" /></a></p>
  <p><a href="https://i.stack.imgur.com/fdmqg.png" rel="noreferrer"><img src="https://i.stack.imgur.com/fdmqg.png" alt="enter image description here" /></a></p>
  <hr />
  <p>If it makes any difference, I'm using <code>@sendgrid/mail</code> <code>v6.3.1</code></p>
  <hr />
  <p>Could you please help me to somehow fix my problem?
  What am I doing wrong?</p>
  <p>How to make email clients recognise my <code>.ics</code> files and allow users to accept/decline these invitations in the email client itself without the need to manually download the file and open it?</p>