Senseful
Senseful

Reputation: 91691

How do I send the standard invitation email when calling addGuest on a CalendarEvent?

Whenever I add a guest via the Google Calendar UI, the following dialog pops up:

enter image description here

If I choose "Send" it sends a nicely formatted email to the user with an option to respond to the calendar event too:

enter image description here

This works flawlessly when you're manually using the Google Calendar UI. Problem is I'm trying to use Google Apps Scripts to automate adding people to events.

I'm programmatically adding guests to a CalendarEvent by using addGuest():

event.addGuest("[email protected]");

However, there doesn't seem to be an option to send an email.

The closest I could find is that when you programmatically create an event, you can set sendInvites:

  var event = CalendarApp.getDefaultCalendar().createEvent(
    'Test',
    new Date('April 5, 2029 20:00:00 UTC'),
    new Date('April 5, 2029 21:00:00 UTC'),
    {sendInvites: true, guests:"[email protected]"});
  Logger.log(event.getId());

This sends a nicely formatted email correctly.

However, the sendInvites option only works when the event is newly created. If at a later time I call:

  var event = CalendarApp.getEventById("insert_id_here");
  event.addGuest("[email protected]");

... it does not send an email update (even though the event was created with sendInvites=true). This means sendInvites is transient and doesn't persist on the event.

Is there any way to sendInvites when calling addGuest() on an event? E.g. event.addGuest("[email protected]", {sendInvite: true})?

Are there any other workarounds that will produce the same email that is sent when hitting that "Send" button in the UI above?

Note: I do not want to use MailApp to send an email because it won't be nicely formatted like the one Google automatically sends out (e.g. with embedded calendar invite, attendees, description, response links, etc, etc, etc).


Update:

Upvotes: 7

Views: 6296

Answers (3)

olawalejuwonm
olawalejuwonm

Reputation: 1527

Just an update to senseful answer. Since the api has been updated in it's latest version.

I modified the function to:

const { google } = require("googleapis");

const calendar = google.calendar({ version: "v3" });

async function addGuestAndSendEmail(calendarId, eventId, newGuest) {
  try {
    const event = await calendar.events.get({
      calendarId,
      eventId,
    });
    // console.log("micheal ~ file: index.js ~ line 316 ~ addGuestAndSendEmail ~ event", event)
    const attendees = event.data.attendees;
    attendees.push({ email: newGuest });

    const resource = { attendees: attendees };
    const args = { sendUpdates: "all" };
    // resource, calendarId, eventId, args
    const res =  await calendar.events.patch({
      calendarId,
      eventId,
      sendUpdates: "all",
      requestBody: {
        attendees,
      },
    });

    return res
  } catch (err) {
    throw new Error(err.message);
  }
}

And i called it this way:

async function inviteAnEmail(id, attendee) {
  try {
    const res = await addGuestAndSendEmail("primary", id, attendee);

    console.log(res.data, "invite Email Data");
  } catch (err) {
    console.log(err.message);
  }
}

Upvotes: 2

Saurabh Bhurle
Saurabh Bhurle

Reputation: 169

refer the following request.

method: POST

endpoint: https://www.googleapis.com/calendar/v3/calendars/primary/events?sendUpdates=all

here, sendUpdates means when you add any guest so he would get an invitation mail used based on scenario.

Input Json Like:

    {
            "kind": "calendar#event",
            "etag": "etag",
            "status": "confirmed",
            "summary": "JayKara",
            "description": "eqwbdjhwhhwhhwrhjehrhejhfj",
            "location": "America",
            "creator": {
                "email": "**@mail.com",
                "self": true
            },
            "organizer": {
                "email": "**@mail.com",
                "self": true
            },
            "start": {
                "date": "2019-12-23"
            },
            "end": {
                "date": "2019-12-24"
            },
            "originalStartTime": {
                "date": "2019-12-24"
            },
            "visibility": "public",
            "attendees": [
                {
                    "email": "****@mail.com" //this guys are the guest 
                }
            ]
        }.

After that there is no patch method required your guest guys will receive an invitation whenever event will be updated.

Cheers!

Upvotes: 0

Senseful
Senseful

Reputation: 91691

As tehhowch mentioned, the key is you must use the Advanced Google API for this. However, the text on this page that says:

This sends an invitation email to the attendees and places the event on their calendar.

... is very misleading. The only way it'll send email is if you set sendUpdates to all for the request.


First, you can verify that sendUpdates is the key piece to sending email for new events via the advanced API:

  1. Go to this link.
  2. Hit the Try it now button up top.

    This should show you a form with the following info populated:

    • calendarId: primary
    • sendUpdates: all
    • Request body:

      {
        "start": {
          "date": "2029-04-04"
        },
        "end": {
          "date": "2029-04-04"
        },
        "summary": "Test",
        "attendees": [
          {
            "email": "[email protected]"
          }
        ]
      }
      
  3. Change the [email protected] to your email address.

    Note that this cannot be your exact email address that you are logged in with. Otherwise the script will notice that you're trying to send an email to yourself and not send it. Instead, if you have a Google email account, you should use a plus address instead.

  4. Hit the Execute button.

    After giving it permissions, you will receive an email to your inbox with the calendar event fully populated just as it is sent when using Google Calendar's UI.

  5. If you want to definitively prove that sendUpdates is important, set it to blank instead of all. Send the invite. Notice that it didn't arrive in your inbox.

If it's not working, make sure that you follow these caveats:

  1. You must not send an email to the same logged in Google account. E.g. either use a plus address, or send it to a different account.
  2. Ensure that sendUpdates is set to all.
  3. Ensure that the event is some time in the future. Google will never send email for invites sent to events in the past. This is true even if you manually use Google Calendar's interface. It'll ask you if you want to send updates to the user(s), you choose "yes", but because the event is in the past, it won't actually send email.

Since the original question already shows how to use the standard CalendarApp to do what we did above, we didn't accomplish much, yet. Now that we know that sendUpdates is important, though, it's time to look at adding a guest.

As the original question points out, there is no way to specify sendInvite (as we would with the standard Calendar API) or sendUpdates (as we would with the advanced Calendar API) when using CalendarApp. The only method we have is addGuest().

Luckily, we can use the Advanced Calendar API similar to how we did above and send an update (aka PATCH) to the event. Rather than interfacing with raw JSON and the Advanced Calendar API, we can use Google's nice wrapper around the advanced API (aka Calendar).

However, since we're using the advanced Calendar API, we must abide by this note:

Note: This is an advanced service that must be enabled before use.

This means there are some prerequisites before jumping into code:

  1. First, enable Google Calendar API in your Cloud Platform project:

    1. In your script, navigate to Resources > Cloud Platform project...
    2. Do one of the following:

      • If you see This script has an Apps Script-managed Cloud Platform project., congratulations, you're done with this step!
      • If you see This script is currently associated with project:, do the following:

        1. Click on the link underneath This script is currently associated with project:

          This will take you to the current project on Google Cloud Platform.

        2. APIs & Services > Dashboard
        3. Enable APIs and Services
        4. Add Google Calendar API
        5. Hit the Enable button.
        6. You can safely ignore the warning: To use this API, you may need credentials. Click 'Create credentials' to get started.
      • If both of the above fail, you can try the nuclear route and recreate your spreadsheet/doc/script whatever.
  2. Next, enable Google Calendar API for the script:

    1. Back in your script, Resources > Advanced Google services
    2. Hit "On" next to Google Calendar API.

      You're now ready to use the advanced API in a script.

With those prerequisites out of the way, you can now create a function:

// Note: requires advanced API
function addGuestAndSendEmail(calendarId, eventId, newGuest) {
  var event = Calendar.Events.get(calendarId, eventId);
  var attendees = event.attendees;
  attendees.push({email: newGuest});

  var resource = { attendees: attendees };
  var args = { sendUpdates: "all" };

  Calendar.Events.patch(resource, calendarId, eventId, args);
}

Some caveats:

  1. When you pass an eventId, you will need to remove the @google.com at the end of the eventId.
  2. You must call get first to get the current list of invitees. If you don't, you'll accidentally remove all the people that were on the event originally. See this answer for more info.

    Note: patch is smart and will only send email updates to the people that were actually added. E.g. if the current people on an event are [alice, bob], and you send a patch with [alice, bob, charlie], only charlie will receive an email. This is exactly what you want!

  3. All the previous caveats in the list above apply.

Again, the key is knowing how to pass in sendUpdates to the insert() method. I couldn't find any documentation about the patch method1, but the auto-complete revealed that there is an optionalArgs parameter that can be added. I randomly tried the format you see above, and it worked!

If it's not working, make sure you read all caveats above.

Note: I'm glad this worked with Google's API, because if it didn't, it likely meant needing to manually send the email(s), and look into how to add calendar metadata to a message so that Gmail parses it properly.


1 We have the general patch API, but this is only useful when sending the raw JSON. We're using Google's Calendar wrapper, which doesn't map exactly the same.

Upvotes: 18

Related Questions