0

I'm trying to create an i-cal event and attach it to a sparkpost transmission like this:

const event = cal.createEvent({
    start: req.body.a.start,
    end: req.body.a.end,
    summary: req.body.a.title,
    description: req.body.a.body,
    url: Config.get('/sparkpost/app'),
});
    
// create event organizer
event.organizer({
    name: 'Test',
    email: 'organizer@example.com',
    mailto: 'explicit@mailto.com'
})

// add an alarm
event.createAlarm({
    type: 'display',
    trigger: 900, // 30min before event
});

req.body.a.teammates.map(async (a) => {
    await event.createAttendee({email: a})
})

b64Event = base64.encode(event)

req.body.a.teammates.map(async (b) => {
    client.transmissions.send({
        recipients: [{address: b}],
        content: {
            from: Config.get('/email/fromEmail'),
            subject: req.body.a.title,
            text: req.body.a.body,
            attachments: [{name: "Test Event", type:"ics", data: [base64.encode(event)]}]
        },
        options: {sandbox: false}
    }).then(data => {console.log(data);}).catch(err => {console.log(err);});
})

Everything seems to work. Except: I cannot get sparkpost to send this file. Keep getting an error:

  { SparkPostError: Unprocessable Entity
     at createSparkPostError (C:\Sonar\node_modules\sparkpost\lib\sparkpost.js:38:15)
     at Request._callback (C:\Sonar\node_modules\sparkpost\lib\sparkpost.js:128:15)
     at Request.self.callback (C:\Sonar\node_modules\request\request.js:185:22)
     at Request.emit (events.js:182:13)
     at Request.<anonymous> (C:\Sonar\node_modules\request\request.js:1154:10)
     at Request.emit (events.js:182:13)
     at IncomingMessage.<anonymous> (C:\Sonar\node_modules\request\request.js:1076:12)
     at Object.onceWrapper (events.js:273:13)
     at IncomingMessage.emit (events.js:187:15)
     at endReadableNT (_stream_readable.js:1094:12)
     at process._tickCallback (internal/process/next_tick.js:63:19)
   name: 'SparkPostError',
   errors:
    [ { message:
         'field \'content.attachments[0].data\' value \'["W29iamVjdCBPYmplY3Rd"]\' is of type \'json_array
\' but needs to be of type \'string\'',
        code: '1300' } ],
   statusCode: 422 }

I also tried it without the Base64.encoding, and got the same error. Sparkpost doesn't offer a lot of examples or advice, so I am blocked... Please any suggestions??

Izzi
  • 2,184
  • 1
  • 16
  • 26
  • Looks like @Jean-François Fabre did not like my answer so it was deleted. Sorry, if you got a copy of it that is what you need. Here is a similar answer I gave a while back that should get you on your way https://stackoverflow.com/questions/54118343/sending-ical-invite-over-sparkpost/54118829#54118829 – Yepher Jan 29 '21 at 18:19
  • Wow dude, thank you for re-posting!! Yes I realized from your answer several things I was missing. I was in the middle of responding to you when the answer disappeared. I was able to get the file to send, but now email clients don’t recognize it as ics file.. Thanks for adding this link. I’ll keep trying – Izzi Jan 30 '21 at 08:37
  • 1
    If the email source (attachment) looks right you likely need this `"type": "application/ics; name=\"invite.ics\"",` – Yepher Jan 31 '21 at 13:30
  • 1
    Yeah dude, your example solved our problem. Thank you. I'm going to post the final code we used, that way there will be a node example for posterity. – Izzi Feb 03 '21 at 15:35
  • I posted an answer here: https://stackoverflow.com/questions/66102584/when-i-add-method-request-to-icalendar-gmail-stops-recognizing-as-event – Izzi Feb 11 '21 at 15:59

1 Answers1

1

Short answer: "YES"

Long Answer:

Attaching .ics to Email Client:

// convert the invite to base64 for attachment
const buf = Buffer.from(iCal.toString(), 'utf-8');
const base64Cal = buf.toString('base64');

// build the email
const sendEmail = async () => {
    const res = await client.transmissions.send({
        recipients: [{ address: 'name@outlook.com' }],
        content: {
          from: 'name@sparkmail.com',
          subject: req.body.a.title,
          text: req.body.a.body,
          attachments: [
            {
              name: 'invite.ics',
              type: 'text/calendar;method=REQUEST;name=\"invite.ics\"',
              data: base64Cal,
            },
          ],
        },
        options: { sandbox: false },
    });
}

// send the email
sendEmail();

Please note: The attachment type is critical for Outlook to recognize the event.

Izzi
  • 2,184
  • 1
  • 16
  • 26