I'm trying to send ics calendar invites to users from node.js server with the goal of getting email clients (e.g. Gmail/Outlook etc) to render them as actual invites and not just usual file attachments.
This is very similar to what Calend.ly does.
So, basically, I'm trying to get something like this in Gmail:
The flow I need is the following (on the client-side):
- In my frontend app User 1 presses the
schedule eventbutton; - User 2 presses
acceptbutton. - The event gets automatically scheduled and appears in both users google calendars (without any OAuth 2.0 stuff or anything like that. Just 2 button presses).
- At the same time the users get emails with event details and the
.icsfile attachment. But the invites should already be in their calendars.
How can I do that?
If I need to use Google Calendar API for this, then how should I at least approach this if I can't have any OAuth 2.0 stuff for my users?
What I'm currently doing is I'm generating .ics files and sending them using SendGrid. However, with .icss I can't achieve a result like in the image above. These .ics files are not invites, they are merely attachments.
So I was wondering how should I approach this at all? Is using Google Calendar API the right way to implement this? If yes, then how can it be done server-side-only without making users authenticate?
I know it's possible because Calendly does exactly this. Users just enter their emails into the input field, press submit and the event invites automatically appear in their Google calendars.
How could this be implemented?
Maybe I don't get something, but generating .ics files doesn't seem to do the trick, and at the same time Google Calendar API does not appear to be the solution as well because of OAuth2 authentication.
Your application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported.
Here's the code I'm using to send emails with .ics attachments (there's also a template on SendGrid side, hence the dynamicTemplateData prop):
const SendGrid = require("@sendgrid/mail");
const attachment = {
filename: 'invite.ics',
name: 'invite.ics',
content: Buffer.from(data).toString('base64'),
disposition: 'attachment',
contentId: uuid(),
type: 'text/calendar; method=REQUEST',
};
SendGrid.send({
attachments: [attachment],
templateId,
from: {
email: config.emailSender,
name: config.emailName,
},
to: user.email,
dynamicTemplateData: {
...rest,
user,
},
headers: {
'List-Unsubscribe': `<mailto:unsubscribe.link`,
},
});
And here's how my .ics attachment files look like:
BEGIN:VCALENDAR
PRODID:-//Organization//Organization App//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART:20210420T180000Z
DTEND:20210420T190000Z
DTSTAMP:20210418T201735Z
ORGANIZER;CN=Denis Yakovenko:MAILTO:test+1@gmail.com
UID:25bb4d3e-b69d-46b0-baea-489c71c48c88
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=Denis Yakovenko;X-NUM-GUESTS=0:MAILTO:test+1@gmail.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=John Smith;X-NUM-GUESTS=0:MAILTO:test+2@gmail.com
CREATED:20210418T201735Z
DESCRIPTION:my description
LAST-MODIFIED:20210418T201735Z
LOCATION:https://virtual.location.com
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:my summary
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
