背景

受託開発先の方からLLMを使って問い合わせや予約業務の自動化ができないかと聞かれた。 もちろんできますよ、と僕は答えたわけです。 しかし、一回gmailの内容をローカルに持って来ないと始まりませんよね?? なので、gmailのメールをサーバに持ってくるためにgoogle apiを叩きます。

構成

webフロントエンド -> サーバ(アプリ) -> google api

google apiの設定方法

1. プロジェクト作成

  1. https://console.cloud.google.com/ にアクセス
  2. 以下の写真のgoogle cloudロゴの隣にあるボタンをクリック。この画像で言うと、gmail api access(ここから新しいプロジェクトを作る) google cloudロゴ
  3. プロジェクト名(例:gmail-auto-reply)を入力し、「作成」

2. Gmail API を有効にする

  1. google cloudロゴの隣にあるボタンから、先ほど作ったプロジェクトにプロジェクトを変更する
  2. 左側メニュー「APIとサービス」 → 「ライブラリ」を押す
  3. 検索ボックスに Gmail API と入力し、クリック。 これ
  4. enableボタンを押す enable button

3. OAuth 同意画面を設定する

  1. 左側メニュー「APIとサービス」→「OAuth同意画面」 これ

次のような画面が出てくる。get startedを押す get started

  1. 以下の情報を入力する
ユーザータイプ	外部(基本はこれでOK)
アプリ名	任意(例:Auto Mailer)
サポートメール	自分のGmailでOK
開発者連絡先情報	自分のメールアドレス

4. 認証情報を作成(OAuth 2.0 クライアントID)

  1. 左メニュー「認証情報」→「+認証情報を作成」→「OAuth クライアントID」 get started get started

  2. 以下を入力する

  • アプリケーションの種類 → 「Web アプリ」
  • 名前は何でもOK(例:auto-mail-backend)
  • 「承認済みのリダイレクトURI」に以下を追加:
  1. 作成ボタンを押す。クライアントシークレットが表示されるのでめももしくはダウンロード

5 スコープを追加(必要なら)

ここまでで設定が完了。次にやることは以下。

  1. Node.js や Python での認証コード
  2. クライアントID・シークレットを使って Gmail にアクセス

認証 & アクセス

必要モジュールのインストール

npm install express googleapis cookie-session

コードを書く

const fs = require('fs');
const path = require('path');
const express = require('express');
const { google } = require('googleapis');
const session = require('cookie-session');

const app = express();
const port = 4444;

// 認証情報を読み込み(ファイル名はサーバにあるもの)
const CREDENTIALS_PATH = path.join(__dirname, 'cred.json');
const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH));
const { client_id, client_secret, redirect_uris } = credentials.web;


const oauth2Client = new google.auth.OAuth2(
  client_id,
  client_secret,
  redirect_uris[0]  // 例: http://localhost:3000/auth/google/callback
);

// cookie-sessionの初期化
app.use(session({
  name: 'session',
  keys: ['your-session-secret'],
}));

// ステップ1: 認証画面にリダイレクト
app.get('/auth/google', (req, res) => {
  const url = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: [
      'https://www.googleapis.com/auth/gmail.readonly',
      'https://www.googleapis.com/auth/gmail.modify',
      'https://www.googleapis.com/auth/gmail.send',
    ],
  });
  res.redirect(url);
});

// ステップ2: コールバックでトークン取得・保存
app.get('/auth/google/callback', async (req, res) => {
  const { tokens } = await oauth2Client.getToken(req.query.code);
  oauth2Client.setCredentials(tokens);
  req.session.tokens = tokens;
  res.send('✅ 認証成功!これでGmail APIが使えます。');
});

// メール一覧取得(簡易サンプル)
app.get('/api/messages', async (req, res) => {
  if (!req.session.tokens) return res.status(401).send('未認証です');

  oauth2Client.setCredentials(req.session.tokens);
  const gmail = google.gmail({ version: 'v1', auth: oauth2Client });
  const result = await gmail.users.messages.list({ userId: 'me', maxResults: 5 });
  res.json(result.data);
});

app.listen(port, () => {
  console.log(`✅ Server running at http://localhost:${port}`);
});

これだと、まだ認証されないのでテストユーザを追加する

追加

https://hogehoge.ingenboy.com/auth/google

にアクセス。 nginxで以下のプロキシ設定を入れておくのを忘れずに


    location /auth/ {
        proxy_pass http://localhost:4444/auth/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

以下のようなのが出てくるので、continueを押す 追加

こんな画面が出てくる

✅ 認証成功!これでGmail APIが使えます。

oauth2の仕組みについては昔自分が記事を書いたのでこれをみて。意外とすんなり入ってきた

使い方のイメージ

さて、今回建てたサーバですが、gmail-proxyですね。クライアントの代わりに認証などを全て済ませてくれているプロキシサーバを使います。

つまりこんな感じで使う。

(gmail-proxy-clinet) -> gmail-proxy -> gmail inbox

Gmail API を「無限に使い続ける」ための設定

前述の通り、**テスト公開中(Publishing status: Testing)では、取得できるリフレッシュトークン(refresh_token)に有効期限(7日間)**が付いてしまいます。

つまり、1週間経つとまた認証し直さないといけない。これは面倒だし、運用にも向きません。

✅ 解決方法:アプリを「本番公開(In production)」する Google Cloud Console の OAuth 同意画面設定で以下を行います:

「ユーザータイプ」が External(外部) であることを確認

「Publishing status(公開状態)」を “In production”(本番) に変更

自分以外に使わせたくない場合は、コード側でメールアドレスを制限

const ALLOWED_EMAIL = 'your.email@example.com';

const oauth2 = google.oauth2({ version: 'v2', auth: oauth2Client });
const userinfo = await oauth2.userinfo.get();

if (userinfo.data.email !== ALLOWED_EMAIL) {
  return res.status(403).send('許可されたユーザー以外は使えません');
}

こうしておけば、本番公開しても自分以外の認証は拒否できるので安心です。

無期限のリフレッシュトークンを確認する方法

認証後に生成された tokens.json の中身を見て、以下のようになっていれば成功です。

{
  "access_token": "...",
  "refresh_token": "...",
  "scope": "...",
  "token_type": "Bearer",
  "expiry_date": 1747464247450
}

❌ 以下のように refresh_token_expires_in がある場合は失敗

"refresh_token_expires_in": 604800

これは7日間の有効期限がある証拠です。テスト公開状態で認証したときだけ起こります。