Inserting Google Calendar Entries with Service Account

Inserting Google Calendar Entries with Service Account

I figured this out. Since I don't see any complete examples of using service accounts with API v3, I'm just going to post my complete solution for reference. There are a few of things that you need to do in addition to implementing the code, however:

1) You need to go to the Google Developer's console and mark your account as a 'service account'. This will differentiate it from a web application. The important difference is that nobody will be prompted to log in to their account before the events are added since the account will belong to your application, not an end user. For more information see this article, starting on page 5.

2) You need to create a public/private key pair. From the developer's console, click on Credentials. Under you service account, click on 'Generate new P12 key'. You'll need to store this somewhere. That file location becomes the $key_file_location variable string in the code below.

3) Also from the developer's console, you need to enable the Calendar API. From your project, on the left margin you'll see APIs. Select that and find the Calendar API. Click it, accept the terms of service, and verify that it is now displayed under Enabled APIs with a status of On

4) In Google Calendar that you want to add events to, under settings, click Calendar Settings then on 'Share this Calendar' at the top. Under 'Share with specific people' in the 'Person' field, paste in the email address from the service account credentials. Change the permission settings to 'Make changes to events'. Don't forget to save the change.

Then, implement this code somewhere.

Comment if something is confusing or omitted. Good luck!

<?php

function calendarize ($title, $desc, $ev_date, $cal_id) {

session_start();

/************************************************
Make an API request authenticated with a service
account.
************************************************/
set_include_path( '../google-api-php-client/src/');

require_once 'Google/Client.php';
require_once 'Google/Service/Calendar.php';

//obviously, insert your own credentials from the service account in the Google Developer's console
$client_id = '843319906820-xxxxxxxxxxxxxxxxxxxdcqal54p1he6.apps.googleusercontent.com';
$service_account_name = '843319906820-xxxxxxxxxxxxxxxxxxxdcqal54p1he6@developer.gserviceaccount.com';
$key_file_location = '../google-api-php-client/calendar-xxxxxxxxxxxx.p12';

if (!strlen($service_account_name) || !strlen($key_file_location))
echo missingServiceAccountDetailsWarning();

$client = new Google_Client();
$client->setApplicationName("Whatever the name of your app is");

if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}

$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/calendar'),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();

$calendarService = new Google_Service_Calendar($client);
$calendarList = $calendarService->calendarList;

//Set the Event data
$event = new Google_Service_Calendar_Event();
$event->setSummary($title);
$event->setDescription($desc);

$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($ev_date);
$event->setStart($start);

$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($ev_date);
$event->setEnd($end);

$createdEvent = $calendarService->events->insert($cal_id, $event);

echo $createdEvent->getId();
}

?>

Some helpful resources:

Github example for service accounts

Google Developers Console for inserting events in API v3

Using OAuth 2.0 to Access Google APIs

Creating Google Calendar events with a GCP Service Account

Answer:

You need to enable the APIs and provide scopes in three places: in your auth code, in the GCP console, and the Google Admin console.

More Information:

As I explained in the comments, the code you have provided should run without issue. The Insufficient Permission: Request had insufficient authentication scopes. error is a result of the service account not being given access to the required scopes somewhere on Google's side.

Make sure you have completed the following steps:

  1. Provided the scopes in the application as an auth object (which you have already done):
const auth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/compute']
});

  1. Enabled the Calendar API in the GCP console for your Service Account GCP Project.
  2. Provided the required scopes for your service account in the OAuth consent screen settings in GCP.
  3. Added the required scopes to the service account in the Google Admin console. This is done by following the Security > Advanced Settings > Manage API client access UI elements, and assigning all scopes the service account needs to the service account client ID.

Note: This final step must be done by a domain admin and can not be done by anyone who is not.

In this case, you will need to contact your domain admin to give your project API access.

References:

  • Google API Console
  • Google Admin Console


Related Answers:

  • Google Calendar API. Adding an event to someone calendar throws error “Error 401: invalid_client” just when authenticating

GET/ADD Events to google calendar with a service account

Service account is a dummy user. It has its own Google Calendar account. By default it doesn't have access to any Google Calendars you need to either share a google calendar with it or insert a new Google Calendars into it.

Calendar.list is something else entirely its basically the little box at the bottom left in the Calendars website. In order for a calendar to appear there it I needs to be inserted into the calendar.list.

Solution:

Go to the Google calendar website add the service account email address as a user of your calendar. Then the service account will be able to access it. If you want you can programmatically insert it into calendar.list if you really need it to be there. IMO there is really not much point for Calendar.list with a service account.

update

You should be able to grant your service account access to do what ever you like like any other user.

Sample Image

If you want it in calendar.list call Calendarlist.insert from the service account code. You will only need to run it once to insert the calendar in question into the service accounts calendar list.

try running Calendars.get on the calendar it should have access without needing to insert it into calendar.list

Insert event in google calendar using service account with Nodejs

This is a known bug

There is an issue when adding attendees to an event with a Service Account.

The current workaround is to impersonate a user using G Suite Domain-wide Delegation. If you do so, you should be able to create the events with attendees.

Another option is to remove the attendees from the Event creation request.

Google service account unable to list calendars?

From your explanation and the returned value, I'm worried that in your situation, you might have never inserted the shared Calendar with the service account. If my understanding is correct, how about the following modification?

Modification points:

  1. Insert the shared Calendar to the service account.

    • In this case, please modify the scope https://www.googleapis.com/auth/calendar.readonly to https://www.googleapis.com/auth/calendar.

        async init () {
      // loads the configuration from our app's configuration file
      this.keyConfig = getKeyConfig('google-calendar');

      const calendarApi = await this.getCalendarApi();
      const response = await calendarApi.calendarList.insert({resource: {id: "###@group.calendar.google.com"}}); // Please set the Calendar ID here. Or {requestBody: {id: "###@group.calendar.google.com"}}
      console.log(JSON.stringify(response.data, undefined, 2));
      }
  2. Retrieve the calendar list using your script.

    • After the Calendar was inserted to the service account using the above script, you can obtain the shared Calendar in the Calendar list.

Reference:

  • CalendarList: insert

What role and conditions are appropriate for allowing a service to add events to my google calendar?

https://support.google.com/a/answer/7378726?hl=en

Please follow the guide mentioned in above link to setup your service account. You can skip step 3 because you need service account instead of implementing OAuth consent screen to authenticate the account.

You may need G-Suit account if you get any trouble with setting up service account with your public gmail account.

You also need to enable Google calendar apis from library while setting up service account using above link. Otherwise you won't be able to access calendar apis.

After you setup up account accordingly, you need to follow the quick start guide according to your development platform. First you need to implement auth method where you will pass your service account keys to authenticate the account. And then you can call calendar apis using those auth credentials. You also need to define the scope in the auth method

Here are the available scopes of calendar apis
https://developers.google.com/calendar/api/guides/auth

In this link, there are some quick starts available in the left menu. You can pick one according to your need and start implementing it in your app.

Using a service account to create google calendar event, can't change creator name

I had a similar issue a long time ago, and the creator.displayName documentation only stated that it would show if available, which was confusing.

After that, I found this Google issue tracker, which mentioned that the "if available" was referring to the Google+ profile information. I updated the name inside Google+, and it worked. Since Google+ is no longer available, I will say to try using Currents (which replaced Google+), and it should do the same thing.

You can access Currents here.

Reference:

  • Issue tracker
  • Evets overview

Cannot create events in google calendar with service account

You appear to have forgotten to specify which user you want the service account to delegate to.

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/calendar']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)

delegated_credentials = credentials.with_subject('user@example.org')


Related Topics



Leave a reply



Submit