Integration with Google Calendar API using Service Account

--

This blog will help you to integrate google calendar for sending automated meeting or any calendar events with the step-by-step process.

GitHub link: https://github.com/soundar-iceapple/.net-google-calendar-api-integration

Analyzing different authentication options and choose the appropriate one based on the use case.

Common authentication options to integrate the Google Calendar API

  • OAuth 2.0: It will be used mostly when integrating with front end systems. It’s recommended method of authentication for most use cases. It allows you to securely authorize your application to access a user’s Google Calendar data without handling their username and password directly. With OAuth 2.0, users can grant permissions to your application for a limited scope of access.
  • API key: For some limited use cases, such as accessing publicly available calendars, you can use an API key. This method does not require user authentication but has limited functionalities compared to OAuth, as it does not allow access to private user data.
  • Service accounts: If you are building an application that needs to access Google Calendar data on behalf of your own application rather than individual users, you can use service accounts. With service accounts, you can authenticate your application using a private key file instead of user credentials.
  • We will see how to integrate with service account in this blog. Other methods simpler than service account integration.

Use Case: Create a calendar event to schedule for a meeting from the application. Some of the business use case for using service account

  • Creating automated processes that can create, update, or delete events on behalf of users.
  • Integrating calendar features into a collaboration or productivity tool that needs to manage and interact with user calendars.
  • Building a booking system or appointment scheduling application that requires access to multiple user calendars.

High Level Steps

  • Project Setup
  • Service Account
  • Share Email Calendar
  • Domain wide delegation authority
  • Application Integration

Project Setup

· Navigate to google cloud console https://console.cloud.google.com/

· Create New Project

· Select the newly created project.

· Enable the Google Calendar API.

· Create Credentials for Service account.

· Add “Service Account Token Creator” role and create the service account.

· Select the “Service Accounts” menu from IAM & Admin -> Service Accounts

· Share the calendar with service account.

· As service account doesn’t have calendar, we must share the actual user calendar with service account to send an event.

· Navigate to actual user account email calendar.

· Go to Calendar setting -> Share with specific people or groups -> Add people and groups.

· Provide email id of service account. It will be available under the specific service account.

· Enable Domain-wide delegation.

  • It requires google workspace admin credentials to enable it.
  • It is required for the Google Calendar API because it allows a service account, which is an account representing an application rather than an individual user, to access the resources of a user within a G Suite domain.
  • By using domain-wide delegation, the service account can act on behalf of users within the domain and access their calendars. This is crucial in scenarios where an application needs to manage and interact with calendars of multiple users within an organization.

· Navigate to https://admin.google.com/ and login with admin credentials.

· Go to Security -> API Controls -> Domain-wide Delegation -> MANAGE DOMAIN WIDE DELEGATION

· Add a new Client.

· Get client id from service account. Unique ID available under the service account

· Add all the below scopes and authorize it

https://www.googleapis.com/auth/calendar
https://www.googleapis.com/auth/calendar.events
https://www.googleapis.com/auth/admin.directory.resource.calendar

· Add Key in the Service Account. IAM & Admin -> Service Accounts -> <your service account> -> KEYS

· It will download the JSON file with the Service Account Private Key and other details. Downloaded JSON represents below format.

{
"type": "service_account",
"project_id": "xxx-1231",
"private_key_id": "xxx",
"private_key": "xxx",
"client_email": "test.iam.gserviceaccount.com",
"client_id": "xxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}

· Integrate with Application.

 using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using Newtonsoft.Json;

public class ServiceAccount
{
public string type { get; set; }
public string project_id { get; set; }
public string private_key_id { get; set; }
public string private_key { get; set; }
public string client_email { get; set; }
public string client_id { get; set; }
public string auth_uri { get; set; }
public string token_uri { get; set; }
public string auth_provider_x509_cert_url { get; set; }
public string client_x509_cert_url { get; set; }
public string universe_domain { get; set; }
}

namespace Test
{
internal class Program
{
[STAThread]
static void Main(string[] args)
{
string impersonateUser = "user-impersonate@test.com"; // actual user to impersonate. Mandatory!
string calendarId = "primary";


var jsonData = System.IO.File.ReadAllText("client_secret.json");
ServiceAccount serviceAccount = JsonConvert.DeserializeObject<ServiceAccount>(jsonData);

var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccount.client_email)
{
Scopes = new[] { CalendarService.Scope.Calendar, CalendarService.Scope.CalendarEvents },
User = impersonateUser
}.FromPrivateKey(serviceAccount.private_key));

var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "application-name"
});

var newEvent = new Event
{
Summary = "Google meet",
Description = "Sample meeting",
Location = "Virtual Meeting",
Start = new EventDateTime
{
DateTime = DateTime.Now.AddHours(2), // Set the start time
TimeZone = "Asia/Kolkata"
},
End = new EventDateTime
{
DateTime = DateTime.Now.AddHours(3), // Set the end time
TimeZone = "Asia/Kolkata"
},
ConferenceData = new ConferenceData
{
CreateRequest = new CreateConferenceRequest
{
RequestId = Guid.NewGuid().ToString(),
ConferenceSolutionKey = new ConferenceSolutionKey { Type = "hangoutsMeet" }
}
},
Attendees = new List<EventAttendee>
{
new EventAttendee()
{
DisplayName = "organizer",
Email = "organizer@email.com",
Organizer = true,
Resource = false,
},
new EventAttendee()
{
DisplayName = "test1",
Email = "test1@email.com",
Organizer = false
}
}
};

EventsResource.InsertRequest request = service.Events.Insert(newEvent, calendarId);
request.SendNotifications = true;
request.ConferenceDataVersion = 1;
var createdEvent = request.Execute();
}
}
}

--

--