SYSTEM NOTICE

Auto translation by AI. Be sure, accuracy, nuances and authorial intent may not be fully reflected.
見出し画像

# 🕊️ The Day the "Mai Calendar" Began to Dance: A Record of Breaking Through the Labyrinth of Voice Calendar and Google Integration

The AI made this for me... though I'm actually thinner than this in real life...

Introduction

In the rural countryside of Yamaguchi Prefecture, I grow pesticide-free rice while working a part-time job at a supermarket in the early morning. During the day, I work as a solo developer, self-teaching and operating the Android/Web app "Voice Calendar." This app continues to evolve daily as a "personal planner" that allows users to register schedules via voice input.

This challenge was implementing the integration feature with Google Calendar. I aimed for the moment when the Voice Calendar and Google would join hands so that schedules would "dance" into my life.


Technologies and Architecture Used

  • Node.js (v22.12.0)

  • Express

  • Google Calendar API v3

  • OAuth2 Authentication (for desktop apps)

  • Save authentication information in `token.json`

  • Implement API integration logic in `server.js`


Authentication Information (Actually Used)

const oAuth2Client = new google.auth.OAuth2(
  '*******************.apps.googleusercontent.com', // クライアントID
  'GOCSPX-****************************', // クライアントシークレット
  'urn:ietf:wg:oauth:2.0:oob' // デスクトップアプリ用リダイレクトURI
);

Contents of `token.json` (upon successful retrieval)

{
  "access_token": "ya29.a0AQQ_BDSB0hpM-...",
  "refresh_token": "1//0ez2KjAKorWLoCgYIARAAGA4SNwF-...",
  "scope": "https://www.googleapis.com/auth/calendar",
  "token_type": "Bearer",
  "refresh_token_expires_in": 604799,
  "expiry_date": 1757917487404
}

Completed `server.js` (excerpt)

const fs = require('fs');
const { google } = require('googleapis');
const express = require('express');

const app = express();
const PORT = 8080;

app.use(express.json());
app.use(express.static('public'));

const credentials = JSON.parse(fs.readFileSync('token.json'));
const oAuth2Client = new google.auth.OAuth2(
  '*******************.apps.googleusercontent.com',
  'GOCSPX-****************************',
  'urn:ietf:wg:oauth:2.0:oob'
);
oAuth2Client.setCredentials(credentials);

// 予定追加と取得のAPI処理(省略)

Troubles and Breakthroughs

❌ `unauthorized_client`

Cause: Used `token.json` with an old client ID
Solution: Re-authenticated with the new ID and secret for "Desktop App"

❌ `No access, refresh token...`

Cause: The calling order of `setCredentials()` was incorrect
Solution: Fixed to call `setCredentials()` immediately after defining `oAuth2Client`

✅ The Moment of Success

When the event "Test" appeared on my Google Calendar, I couldn't help but shout, "It danced!"




いいなと思ったら応援しよう!