LoginSignup
1
0

googleapisを利用してGmailをAPIで取得する

Last updated at Posted at 2024-02-10

目的

PlaywrightでGoogle Gmail APIを使用してメールを受信すること。

Playwrightでe2eテストコードを実装する中で、メール認証時の認証コードを取得したかったのでAPIでメールを取得したかった。

前提

  • Googleアカウントがあること

事前準備

まずはgoogleapisでGmailを取得するために必要な認証情報を取得します。

Google Cloud Consoleでプロジェクトを作成

以下にアクセスしてプロジェクトを作成します。

以下の手順でプロジェクトを作成

  1. Google Cloud Consoleへアクセス
  2. プロジェクトを作成ボタンをクリック
  3. 適当にプロジェクト名を入力
  4. 作成ボタンをクリック

Gmail APIを有効化

サイドバーを開き「APIとサービス > ライブラリ」をクリックし、APIライブラリからGmail APIを有効化します。

以下の手順でGmail APIを有効化

  1. APIライブラリへアクセス
  2. 検索窓に「Gmail」と入力
  3. 検索結果の「Gmail API」をクリック
  4. 「有効にする」ボタンをクリック

OAuth 2.0 クライアントIDを作成

「APIとサービス > 認証情報」から認証情報を作成します。

  1. 「認証情報を作成」ボタンをクリック
  2. OAuth クライアントIDをクリック
    1. OAuth同意がまだの場合は設定が必要なので、「OAuth同意画面」へアクセスして設定
  3. 設定
    1. アプリケーションの種類:ウェブアプリケーション
    2. 名前:適当でOK(自分は初期値のままにした)
    3. 承認済のリダイレクトURI: http://localhost:3000/oauth2callback
      1. 後ほどインストールするライブラリでこのように設定するよう記載があります。

認証情報を取得

クライアントIDの作成が完了すると認証情報が作成されます。

後ほど以下の項目を利用します。

  • クライアント ID
  • クライアントシークレット

googleapisでGmailを取得する

プロジェクトにgoogleapisをインストール

googleapisはGoogleが提供するAPIや開発者向けツールなどを含む、Google Cloud Platform(GCP)の一部です。今回はこちらを利用してGmailをAPIで取得します。

  1. pnpm install googleapis でインストール
    1. 利用しているパッケージマネージャでインストール方法は変更してください

認証URLを生成してcodeを取得

アクセストークンを取得するためにアクセス許可を行います。

先ほど作成した認証情報と、設定したリダイレクトURIを利用します。

const oauth2Client = new google.auth.OAuth2(
    'clientID', // クライアントID
    'clientsecret', // クライアントシークレット
    'http://localhost:3000/oauth2callback', // リダイレクトURI
  );

const scopes = ['https://www.googleapis.com/auth/gmail.readonly'];

const url = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // If you only need one scope you can pass it as a string
  scope: scopes,
  prompt: 'consent', 
});
// コンソールにURLを表示して、アクセスし認証をしてもらう
console.log('Authorize this app by visiting this url:', url);
  1. 上記のコードの認証情報の値を先ほど取得した認証情報に変更
  2. 上記のコードを実行
  3. コンソールに出力されたURLにアクセス
  4. 認証
  5. リダイレクトされたURLのcode= 以降を取得

リフレッシュトークンを取得

先ほど取得したcodeを使い、APIを実行するためのリフレッシュトークンを取得します。

const oauth2Client = new google.auth.OAuth2(
    'clientID', // クライアントID
    'clientsecret', // クライアントシークレット
    'http://localhost:3000/oauth2callback', // リダイレクトURI
  );

// URL取得した認証コード
const code =
  'code';
// 認証コードをトークンに交換
const { tokens } = await oauth2Client.getToken(code);
console.log('Tokens:', tokens);
  1. 上記のコードの認証情報の値を先ほど取得した認証情報に変更
  2. 上記のコードのcode='code'の値を先ほど取得したcodeに変更
  3. 上記のコードをを実行
  4. コンソールに出力されたURLからリフレッシュトークンを取得

Gmailを取得

最新のメールを返すgetNewGmailという関数を作成しました。

また、認証情報等の値は.envで管理するよう修正してあります。


import dotenv from 'dotenv';
import { google } from 'googleapis';
import type { gmail_v1 } from 'googleapis';

/** Read environment variables from file. https://github.com/motdotla/dotenv */
dotenv.config();

export async function getNewGmail(): Promise<null | gmail_v1.Schema$Message> {
  try {
    // OAuth2 クライアントを設定
    const oauth2Client = new google.auth.OAuth2(
      process.env.GOOGLE_CLIENT_ID, // クライアントID
      process.env.GOOGLE_CLIENT_SECRET, // クライアントシークレット
      'http://localhost:3000/oauth2callback', // リダイレクトURI
    );

    // 保存されたトークンをセット(事前に取得しておく必要があります)
    oauth2Client.setCredentials({
      refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
    });

    // Gmail APIクライアントを初期化
    const gmail = google.gmail({ version: 'v1', auth: oauth2Client });

    // メールを取得
    const res = await gmail.users.messages.list({
      userId: 'me', // 自分自身
      maxResults: 10, // 最大取得数
    });

    // メールのIDを取得
    const messages = res.data.messages;
    if (!messages) return null;

    // 最初のメールの詳細を取得
    const message = await gmail.users.messages
      .get({
        userId: 'me',
        id: messages[0].id!,
      })
      .then((response) => response.data);
    return message;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}
  1. 上記のコードの認証情報の値を先ほど取得した認証情報に変更
  2. 上記のコードをを実行

自分の場合は特定のエイリアス付きメールアドレス(sample+1@gmail.comのように+付きのメールアドレス)宛に届いた最新のメールを取得したかったので以下のように変更

import dotenv from 'dotenv';
import { google } from 'googleapis';
import type { gmail_v1 } from 'googleapis';

/** Read environment variables from file. https://github.com/motdotla/dotenv */
dotenv.config();

/**
 * 特定のメールアドレス宛の最新のGmailのメールを取得する
 *
 * @param   toEmail
 * @returns         null | gmail_v1.Schema$Message
 */
export async function getNewGmail(
  toEmail: string,
): Promise<null | gmail_v1.Schema$Message> {
  try {
    // OAuth2 クライアントを設定
    const oauth2Client = new google.auth.OAuth2(
      process.env.GOOGLE_CLIENT_ID, // クライアントID
      process.env.GOOGLE_CLIENT_SECRET, // クライアントシークレット
      'http://localhost:3000/oauth2callback', // リダイレクトURI
    );

    // 保存されたトークンをセット(事前に取得しておく必要があります)
    oauth2Client.setCredentials({
      refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
    });

    // Gmail APIクライアントを初期化
    const gmail = google.gmail({ version: 'v1', auth: oauth2Client });

    // エイリアスを含むメールを検索するクエリを設定

    const query = `to:${toEmail}`;

    // メールを取得
    const res = await gmail.users.messages.list({
      userId: 'me', // 自分自身
      maxResults: 10, // 最大取得数
      q: query, // 検索クエリ
    });

    // メールのIDを取得
    const messages = res.data.messages;
    if (!messages) return null;

    // 最初のメールの詳細を取得
    const message = await gmail.users.messages
      .get({
        userId: 'me',
        id: messages[0].id!,
      })
      .then((response) => response.data);
    return message;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

最後に

はじめは捨てメールアドレス生成サービスを利用してメールを受診しようとしたが使い方がわからず、Gmailなら方法があるだろうとGmailでのメール取得してみたらいけた。


メールが取得できなくなった

リフレッシュトークンの期限切れ

昨日までメールの取得ができていたのにできなくなった場合は、リフレッシュトークンの期限が切れている可能性があります。

codeの取得から再度やり直し、リフレッシュトークンを再取得してみてください。

迷惑メールフォルダに入っている

メールが取得できない前に、届いていない。

いつの間にか迷惑メールフォルダに振り分けられていてメールの取得ができなくなっていました。

迷惑メールフォルダにメールが届いていないか確認し、振り分けられていた場合は「迷惑メールではありません」ボタンをクリックするなどして迷惑メールフォルダに振り分けられないようにしてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0