D'une manière ou d'une autre, de manière inattendue pour moi, la connexion de mon application nodejs à l'API Google Calendar s'est avérée être une tâche plutôt non triviale. Malgré la description détaillée des options de connexion en russe, j'ai dû parcourir la forêt de différents paramètres et configurations. L'article détaille les étapes à suivre pour que l'intégration réussisse.
L'objectif de l'intégration est de permettre à une application nodejs de publier des événements dans un calendrier spécifique. Dans cet exemple, nous avons utilisé un compte Google personnel régulier.
Créer un calendrier
Tout d'abord, vous devez créer un calendrier dans lequel nous publierons des événements. Accédez à Google Agenda et cliquez sur le bouton " + " à côté de " Autres agendas ", puis sélectionnez l'élément " Créer un agenda ":
remplissez le formulaire et cliquez à nouveau sur " Créer un calendrier ", mais avec le bouton bleu:
Google bruine ses cerveaux depuis longtemps, après quoi il annonce joyeusement que le nouveau calendrier est prêt. Accès aux nouveaux paramètres du calendrier:
Dans les paramètres, nous nous intéressons principalement à l'élément " Intégration du calendrier " :
dans lequel le plus utile est l '" ID de calendrier "
c093hr4fqjuj5k9e6uvvac73ac@group.calendar.google.com
nodejs- API.
" API".
- " ":
- "Habr Demo":
API Google':
Google 3 , :
"calend" , :
"Google Calendar API" :
dashboard API (https://console.developers.google.com/apis/api/calendar-json.googleapis.com/overview?project=habr-demo-293107&supportedpurview=project), , API :
" " , , API:
, :
Google JSON, Google Calendar API:
"". , Google' , API, :
, " / ", . "" JSON- "Downloads" :
JSON- ( ):
{
"type": "service_account",
"project_id": "habr-demo-293107",
"private_key_id": "4ec17ea5f8b606e0535a0623a110111123fd3c33",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "nodejs-app@habr-demo-293107.iam.gserviceaccount.com",
"client_id": "102219376121816220804",
"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/nodejs-app%40habr-demo-293107.iam.gserviceaccount.com"
}
API "Habr Demo" email' "nodejs-app@habr-demo-293107.iam.gserviceaccount.com":
API nodejs- Google googleapis . OAuth2- , scope' . :
const fs = require('fs');
const {google} = require('googleapis');
const CALENDAR_ID = 'c093hr4fqjuj5k9e6uvvac73ac@group.calendar.google.com';
const KEYFILE = 'Habr Demo-4ec17ea5f8b6.json'; // path to JSON with private key been downloaded from Google
const SCOPE_CALENDAR = 'https://www.googleapis.com/auth/calendar'; // authorization scopes
const SCOPE_EVENTS = 'https://www.googleapis.com/auth/calendar.events';
(async function run() {
// INNER FUNCTIONS
async function readPrivateKey() {
const content = fs.readFileSync(KEYFILE);
return JSON.parse(content.toString());
}
async function authenticate(key) {
const jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
[SCOPE_CALENDAR, SCOPE_EVENTS]
);
await jwtClient.authorize();
return jwtClient;
}
async function createEvent(auth) {
const event = {
'summary': 'Habr Post Demo',
'description': ' nodejs- Google Calendar API.',
'start': {
'dateTime': '2020-10-20T16:00:00+02:00',
'timeZone': 'Europe/Riga',
},
'end': {
'dateTime': '2020-10-20T18:00:00+02:00',
'timeZone': 'Europe/Riga',
}
};
let calendar = google.calendar('v3');
await calendar.events.insert({
auth: auth,
calendarId: CALENDAR_ID,
resource: event,
});
}
// MAIN
try {
const key = await readPrivateKey();
const auth = await authenticate(key);
await createEvent(auth);
} catch (e) {
console.log('Error: ' + e);
}
})();
Calendar API:
{
...
"status": 404,
"statusText": "Not Found",
...
}
- .
, , " ", " " email- , :
:
" ", "You need to have writer access to this calendar." API:
:
16:00:
'start': {
'dateTime': '2020-10-20T16:00:00+02:00',
'timeZone': 'Europe/Riga',
}
a 17:00, IT:
Il n'y a que deux difficultés typiques dans la programmation: l'invalidation du cache, les noms d'entités et une erreur par unité
Résumé
C'est tout, la quête est terminée. Heureux, comme on dit, le codage.