Il blog di Sandro Rizzetto

Accedere ai Google Calendars con un ServiceAccount e le API v3

 

Mi sono trovato nell'obbligata necessità di dover aggiornare un mio piccolo progetto alla versione v3 delle Google API e più precisamente delle Google Calendar API. In breve si tratta di un servizio (scritto in C# e che sfrutta le Client Library .NET) che periodicamente legge i calendari di tutti i collaboratori e scrive alcuni impegni/appuntamenti sulla dashboard della nostra intranet.

Siccome la documentazione e gli esempi forniti da Google sono a mio avviso spesso deficitari e di scarsa qualità (da un mio tweet di ieri forse non si capiva bene che ritengo la documentazione di Microsoft di qualità notevolmente migliore!), cerco di riassumere qui gli step necessari per arrivare all'obiettivo.

Creare il progetto

E' ora obbligatorio creare nella Developers Console il proprio progetto; Google infatti si riserva di monetizzare l'uso delle proprie API se queste superano il numero massimo di chiamate/connessioni e quindi diventa obbligatorio far tracciare la propria applicazione.

image

Una volta creato è necessario abilitare le Google Calendar API per quel progetto in quanto non lo sono per default

image

Successivamente dobbiamo creare un Service Account, dal menu Credentials

image

Che ci fornirà 3 informazioni che ci saranno utili dopo: il ClientID, un emailAddress e un file .p12 per il certificato X-509

image

 

Google Apps Admin Settings

L'amministratore del dominio delle Google Apps, deve fare queste due modifiche nella console di Admin:

Sotto Security (se non la vedete nelal pagina iniziale cliccate in basso more), scegliere Advanced Settings (ancora una votla premere more se è nascosta) e il punto di menu Manage API client access

image

Autorizzare il nostro client inserendo il ClientID ottenuto prima e come scope quello che ci serve (read/write o read-only)

image

Siccome il servizio deve poter leggere tutte le informazioni dell'evento (non solo la data) sarà necessario che ogni utente autorizzi quell'email @developer.gserviceaccount.com al setting "See all event details".

Per fare ciò prima però l'admin di dominio deve andare sotto Apps > Google Apps > Calendar e sotto Sharing Settings attivare l'opzione di Share all information anche per gli "external sharing" (di default sono disattivati)

image

Personal Calendar Settings

Come appena specificato, ogni persona deve autorizzare dal proprio calendario l'utente applicativo, tramite la sua email @developer.gserviceaccount.com,  a vedere i propri eventi.

image

Codice .NET

Prima di tutto bisogna autorizzare il nostro client ad accedere alle API tramite le informazioni che abbiamo ricavato dai punti sopra

string serviceAccountEmail = "...fifk39l0@developer.gserviceaccount.com";
string filepath = "MyKeyFile.p12";
var certificate = new X509Certificate2(filepath, "mysecretpwd", X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(new
ServiceAccountCredential.Initializer(serviceAccountEmail)
{
    Scopes =
        new[] { CalendarService.Scope.Calendar }
}.FromCertificate
(certificate));

BaseClientService.Initializer initializer = new
BaseClientService.Initializer();
initializer.HttpClientInitializer = credential;
initializer.ApplicationName = "IntranetGCal";
CalendarService calservice = new CalendarService(initializer);

Poi andremo a fare la richiesta vera e propria (nell'esempio gli eventi da oggi a +7 giorni)

EventsResource.ListRequest req = calservice.Events.List("myEmail@myDomain.com");
req.TimeMin = DateTime.Now.Date;
req.TimeMax = DateTime.Now.AddDays(7).Date;
req.SingleEvents = true;
req.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
Events events = req.Execute();

Otterremo una lista di Event con tutte le proprietà che ci servono; nell'esempio sottostante riempio una mia custom entity CalendarEvent con alcune di esse.

foreach (Google.Apis.Calendar.v3.Data.Event eventdata in events.Items)
{
    if (eventdata.Visibility != "private")
    {
        CalendarEvent item = new CalendarEvent
        {
            GoogleUniqueID = eventdata.Id,
            Title = eventdata.Summary,
            Description = eventdata.Description,
            Location = eventdata.Location,
        };
        EventDateTime start = eventdata.Start;
        item.DateFrom = start.DateTime.HasValue ? start.DateTime : Convert.ToDateTime(start.Date);
        EventDateTime end = eventdata.End;

        item.DateTo = end.DateTime.HasValue ? end.DateTime : Convert.ToDateTime(end.Date);
        item.isAllDay = (start.DateTime == null);
        
        //...
    }
}

Ultima nota: per l'uso delle Google API su una macchina che ha solo il framework 4.0 è necessaria la patch KB2468871:

http://www.microsoft.com/en-us/download/details.aspx?id=3556

Commenti (3) -

  • Luca

    28/02/2018 11:37:37 | Rispondi

    Ciao,
    molto bello il tuo turial. Io avrei bisogno di estrarre magari una datagrid tutti gli eventi di un calendario gmail (lo fare con vb.net ma se l'hai in C# poi lo traduco).
    GRazie mille

  • Fabrizio Pulvirenti

    07/06/2020 14:14:17 | Rispondi

    Ciao e grazie per quanto hai esposto nella dettagliata guida.
    C'è, tuttavia, un problema: le immagini che hai posto come esempio e guida, soprattutto quelle che riportano i metodi per abilitare le APIs,  non sono più disponibili perché Google ha cambiato sensibilmente la struttura. Per tale ragione, tra implementazioni e autorizzazioni (in atto le autorizzazioni per l'accesso e la modifica del calendario prevedono l'utilizzo di OAuth) mi sono perso nei meandri per nulla chiari delle spiegazioni di Google.
    Ci sarebbe la possibilità di un qualche esempio semplice?

    Grazie in anticipo (e comunque)

    • Sandro

      07/06/2020 17:30:50 | Rispondi

      Ciao Fabrizio,
      come vedi dalla data del post, si trattava del 2014, ovvio quindi che le versioni delle API si evolvono anche se la v3 non sembra essere deprecata.

      Ho dei batch nella nostra intranet aziendale che  prendono i dati dai google calendar e li mettono in un db sql e funzionano ancora quitidianamente, quindi il codice C# è sicuramente ancora valido.

      Saluti

Aggiungi Commento

Copyright © 1997-2024 Sandro Rizzetto | All Rights Reserved | Riproduzione delle fotografie vietata | Powered by me