-1

I am emailing an HTML link of a Google calendar event generated by Google API to users but they are unable to edit the event, they can only view it when they click the link. I am creating this event with a service account and sharing with other users.

How can I ensure these events are editable in the user's calendar?

This is a link to the code I am using:

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

// Provide the required configuration
const CREDENTIALS = JSON.parse(process.env.CREDENTIALS);
const calendarId = process.env.CALENDAR_ID;

// Google calendar API settings
const SCOPES = ['https://www.googleapis.com/auth/calendar.events'];
const calendar = google.calendar({version : "v3"});

const auth = new google.auth.JWT(
    CREDENTIALS.client_email,
    null,
    CREDENTIALS.private_key,
    SCOPES,
    'email_used_to_configure_the_service_account@gmail.com'
);

auth.authorize(function (err, tokens) {
    if (err) {
      console.log(err);
      return;
    } else {
      console.log("Successfully connected!");
    }
   });

  //fetching the even object from the db to get evnt.name and co
   const saveEvent = {
        summary: event.name,
        location: event.room.host.location,
        description: event.extra,
        colorId: 3,
        start: {
          dateTime: event.startDate,
          timeZone: 'Africa/Lagos',
        },
        end: {
          dateTime: event.endDate,
          timeZone: 'Africa/Lagos',
        },
        organizer: {
            email: 'email_used_to_configure_the_service_account@gmail.com',
            displayName: 'display name',
            self: true
           },
        attendees: [{ email: 'email of recepient of event' }]
        //visibility: 'public'
      }


      async function generateLink(){
          try{

            const val = await calendar.events.insert({ auth: auth, calendarId: calendarId, resource: saveEvent, sendNotifications: true });
            if(val.status === 200 && val.statusText === 'OK'){
                console.log('CREATED', val);
                return val.data.htmlLink;
            }
            return console.log('NOT CREATED')
          } catch(error){
              console.log(`Error ${error}`);
              return;
          }
      }
      
      const link = await generateLink();


      let mailData = {
            name: user.name ? user.name : user.firstname,
            token: `${config.get('platform.url')}/event-accepted/${invite.token}`,
            coverImage: event.gallery.link,
            eventName: event.name,
            hostName: host.name? host.name : host.firstname,
            venue: event.venue,
            date: event.startDate,
            time: event.startDate,
            attendees: '',
            ticketNo: '',
            cost: event.amount,
            action: link // htmlLink that takes you to the calendar where user can edit event.
    }

    mail.sendTemplate({
        template: 'acceptEventEmail',
        to: u.email.value,
        context: mailData
    });

Current Behaviour

enter image description here

Expected behaviour

enter image description here

P.S: Code has been added to the question

camelCase
  • 475
  • 5
  • 14

1 Answers1

1

YOu created the event using a Service account, think of a service account as a dummy user. When it created the event it became the owner / organizer of the event and there for only the service account can make changes to it.

You either need the service account to update it and set someone else as organizer

"organizer": {
    "email": "me@gmail.com",
    "displayName": "L P",
    "self": true
   },

Service accounts cannot invite attendees without Domain-Wide Delegation of Authority

In enterprise applications you may want to programmatically access users data without any manual authorization on their part. In Google Workspace domains, the domain administrator can grant to third party applications domain-wide access to its users' data—this is referred as domain-wide delegation of authority. To delegate authority this way, domain administrators can use service accounts with OAuth 2.0.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • @DalmTo I get this error "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority" when I added the organizer object. I have also updated the question with a link to my current implementation. Kindly check and let me know. Thanks – camelCase Mar 29 '21 at 10:28
  • Service accounts only work with gsuite accounts. You can only invite members of the same domain. You need to set it up in gsuite grant the service account permission and delicate its access to a user on the domain then it can impersonat that user3 – Linda Lawton - DaImTo Mar 29 '21 at 11:52