Actie Afspraak (Google Calendar)

0000002950     -      20-12-2019

Om deze actie te installeren :

  • Ontzip het ZIP bestand hierbij gevoegd
  • Meer informatie over een snelle installatie
  • Parametreer de Google account om toegang via het API toe te laten (zie hieronder)
  • Plaats het bestand JSON voorzien van de parametrering in de SQL bestanden > Andere
  • Plaats deze DLL’s in de hoofddirectory van Mercator
    • Google.Apis.Auth.dll
    • Google.Apis.Auth.PlatformServices.dll
    • Google.Apis.Calendar.v3.dll
    • Google.Apis.Core.dll
    • Google.Apis.dll
    • Google.Apis.PlatformServices.dll
    • MercatorGoogleCalendarClient.dll
    • Newtonsoft.Json.dll
  • Wijzig de customizer van de actie door de naam van  het bestand JSON en het ID van de agenda die de acties van Mercator moet terug vinden, in te geven.

Het bestand bevat de parameters van de volgende actie: opmaken van een afspraak die in Google Calendar ® zal verschijnen.

Het formulier van deze actie bestaat uit:

  • Onderwerp
  • Begin: datum en uur
  • Einde: datum en uur
  • De inhoud van de afspraak, vrije tekst

Als de afspraak de status “Gedaan” heeft, dan verschijnt er een veld om het verslag in te geven.
Bij het heropenen van een actie van dit type, zal Mercator nakijken als de afspraak in Google Calendar bestaat. Als deze is gevonden, dan zullen eventuele wijzigingen die aan deze afspraak in Google Calendar werden aangebracht in Mercator worden aangepast.

De gewenste aanpassingen voor het personaliseren van de gedragingen van de koppeling naar Google Calendar mogen in de code C# worden aangebracht:

  • van de customizer van de actie
  • van de bronnen van MercatorGoogleCalendarClient.dll (zie hieronder).

Om in een logica van agendabeheer per gebruiker te komen, is het nodig, bij voorbeeld, deze lijn in de customizer te vervangen

Zoom
private const string calendarId = "xxx.yyy@gmail.com";

door deze

Zoom
private string calendarId = MercatorUi.Globals.CurrentUserRecord.CRM_MAIL;

Parametreer de Google account om toegang via het API toe te laten

De eerste stap bestaat uit het aanmaken van een service account. Deze service account kan voor meerdere agenda’s die aan meerdere gebruikers toebehoren worden gebruikt.

  1. Toegang hebben tot de console Google Api en services, en klik op de knop "selecteer"
  2. Kies een project of maak een nieuw project aan
  3. Klik op de knop “Activeer” of “Beheer”
  4. In de linker marge, klik op “Inloggegevens” en nadien op de koppeling “Inloggegevens van de API’s en services”
  5. Klik op het rolmenu “Selecteer een project” en kies “Sleutel Service account”
  6. Geef een naam voor de Service account. Behoud de “JSON” als standaard. Klik op de knop “Maken”
  7. Klik op de knop “maken zonder rol” en laad het bestand JSON die de private sleutel bevat, op.
  8. Plaats het bestand in de SQL bestanden van Mercator (Beheer  > SQL bestanden > Andere).

De tweede stap bestaat uit het toelaten dat de service account wijzigingen aan de agenda kan aanbrengen. Deze procedure dient in de verschillende agenda’s waar Mercator zou kunnen in schrijven te gebeuren.

  1. Ga naar de agenda
  2. Klik op het menu “Instellingen” (tandwiel) > Instellingen
  3. Klik op de naam van jouw agenda links en dan “Delen met specifieke mensen”
  4. Klik op “Mensen toevoegen”
  5. Voeg het mail adres van de service account die in het bestand JSON zit toe (property client_email)
  6. Klik op “De wijzigingen toepassen en het delen beheren”. Sluit af met “Verzenden”
  7. Op dezelfde pagina, noteer de waarde “ID van de agenda” en voeg deze toe in de customizer van de actie (calendarId)

Deze tutorial is gebaseerd op deze pagina deze pagina..


Wijziging van MercatorGoogleCalendarClient.dl

Om de bronnen van MercatorGoogleCalendarClient.dll te wijzigen, dient men in Visual Studio, een nieuwe project van het type “Klassen bibliotheek (.NET Framework)” – FW 4.6 en volgende.

  • Voeg een referentie naar MercatorTunnel.dll toe
  • Voeg NuGet Google.Apis.Calendar.v3 toe

De code van class Unieke Klasse die in deze DLL zit is de volgende :

Zoom
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.Apis.Calendar.v3;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Calendar.v3.Data;
using MercatorApi;

namespace MercatorGoogleCalendarClient
{
    public static class Class
    {
        public static bool InsertOrUpdateEvent(string jsonCredentialsFile, string calendarId, EventDescriptor descriptor, out string errorMessage)
        {
            var service = getCalendarService(jsonCredentialsFile, calendarId, out errorMessage);
            if (service == null)
                return false;

            if (!string.IsNullOrWhiteSpace(descriptor.Id) && !descriptor.IsIdValid())
            {
                errorMessage = "Ongelig ID ! (mag enkel en alleen cijfers en kleine letters bevatten - min. 5)";
                return false;
            }

            var eventEntry = new Event
            {
                Id = string.IsNullOrWhiteSpace(descriptor.Id) ? Api.NewId().Replace("-", "").ToLower() : descriptor.Id,
                Summary = descriptor.Summary,
                Description = descriptor.Description,
                Start = new EventDateTime { DateTime = descriptor.Start },
                End = new EventDateTime { DateTime = descriptor.End },
            };

            if (string.IsNullOrWhiteSpace(descriptor.Id)) //Dit is een evenement dat nog nooit in de Google-agenda is aangemaakt
            {
                descriptor.Id = eventEntry.Id; // renvoyer le nouvel ID à l'appelant
                try
                {
                    var insertRequest = service.Events.Insert(eventEntry, calendarId);
                    insertRequest.Execute();
                }
                catch (Exception ex)
                {
                    errorMessage = "Toevoegen aan Google-agenda : " + ex.Message + (ex.InnerException != null ? "\r\n" + ex.InnerException.Message : "");
                    return false;
                }
            }
            else // Afspraak dewelke normaal al bestaat in de Google-agenda
            {
                try
                {
                    var updateRequest = service.Events.Update(eventEntry, calendarId, descriptor.Id);
                    updateRequest.Execute();
                }
                catch (Exception ex) // on gère ici l'exception levée si l'event n'existe pas dans le calendrier Google -> on crée un nouvel event
                {
                    if (ex.Message.Contains("404"))
                    {
                        try
                        {
                            var insertRequest = service.Events.Insert(eventEntry, calendarId);
                            insertRequest.Execute();
                        }
                        catch (Exception ex2)
                        {
                            errorMessage = "Toevoegen aan de Google-agenda : " + ex2.Message + (ex2.InnerException != null ? "\r\n" + ex2.InnerException.Message : "");
                            return false;
                        }
                    }
                    else
                    {
                        errorMessage = "Update van de Google-agenda : " + ex.Message + (ex.InnerException != null ? "\r\n" + ex.InnerException.Message : "");
                        return false;
                    }
                }
            }
            return true;
        }

        public static EventDescriptor GetEvent(string jsonCredentialsFile, string calendarId, string eventId, out string errorMessage)
        {
            var service = getCalendarService(jsonCredentialsFile, calendarId, out errorMessage);
            if (service == null)
                return null;

            Event eventEntry;
            try
            {
                var getrequest = service.Events.Get(calendarId, eventId);
                eventEntry = getrequest.Execute();
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("404"))
                    return null; // we beheren de uitzondering die hier wordt opgeworpen als het evenement niet bestaat in de Google-agenda -> we maken een nieuw evenement.
                {

                errorMessage = "Selectie Google-agenda : " + ex.Message + (ex.InnerException != null ? "\r\n" + ex.InnerException.Message : "");
                return null;
            }

            return new EventDescriptor
            {
                Id = eventEntry.Id,
                Summary = eventEntry.Summary,
                Description = eventEntry.Description,
                Start = eventEntry.Start.DateTime ?? new DateTime(1900, 1, 1),
                End = eventEntry.End.DateTime ?? new DateTime(1900, 1, 1)
            };
        }

        private static CalendarService getCalendarService(string jsonCredentialsFile, string calendarId, out string errorMessage)
        {
            errorMessage = null;
            string jsonCredentialsContent = Api.FileToStr("<Other\\" + jsonCredentialsFile);
            if (string.IsNullOrEmpty(jsonCredentialsContent))
            {
                errorMessage = string.Format("Bestand niet gevonden \"<Other\\{0}\" !", jsonCredentialsFile);
                return null;
            }

            JsonCredentialParameters jsonCredentialParameters;
            try
            {
                jsonCredentialParameters = Google.Apis.Json.NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(jsonCredentialsContent);
            }
            catch (Exception ex)
            {
                errorMessage = $"Uitlezen van {jsonCredentialsFile} : " + ex.Message + (ex.InnerException != null ? "\r\n" + ex.InnerException.Message : "");
                return null;
            }
            ServiceAccountCredential serviceAccountCredential = new ServiceAccountCredential
            (
                new ServiceAccountCredential.Initializer(jsonCredentialParameters.ClientEmail)
                {
                    Scopes = new string[1] { CalendarService.Scope.Calendar },
                }.FromPrivateKey(jsonCredentialParameters.PrivateKey)
            );

            CalendarService calendarService;
            try
            {
                calendarService = new CalendarService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = serviceAccountCredential,
                    ApplicationName = "MercatorGoogleCalendarClient"
                });
            }
            catch (Exception ex)
            {
                errorMessage = "Aanmaken CalendarService Google : " + ex.Message + (ex.InnerException != null ? "\r\n" + ex.InnerException.Message : "");
                return null;
            }

            Calendar calendar;
            try
            {
                calendar = calendarService.Calendars.Get(calendarId).Execute();
            }
            catch (Exception ex)
            {
                errorMessage = $"Selectie Google-Agenda : " + ex.Message + (ex.InnerException != null ? "\r\n" + ex.InnerException.Message : "");
            }

            return calendarService;
        }
    }

    public class EventDescriptor
    {
        public string Id { get; set; }
        public string Summary { get; set; }
        public string Description { get; set; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }

        public bool IsIdValid()
        {
            if (Id == null)
                return false;
            else
                return System.Text.RegularExpressions.Regex.Match(Id, "^[a-z0-9]{5,1024}$").Success;
        }
    }
}


Te laden : 0000002950.zip (377 Kb - 25-11-2019)