6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

岩手県立大学Advent Calendar 2020

Day 16

Node.jsでGmailの最新のメール内容を取得する

Posted at

久しぶりにGmail APIのチュートリアルを見たらアップデートされてたので試してみました。

ここでは、 特定のメールから届いてるメールの最新の値を取得してみます。

認証情報の準備

Google公式ライブラリを利用してNode.jsからGmailの送受信をしてみよう公式チュートリアルを参考に、クレデンシャルトークンの情報を取得しましょう。

スコープ

メソッド的には、gmail.users.messages.listgmail.users.messages.getを利用します。

今回使うトークン取得の際のスコープですが、以下の6種類になります。

https://mail.google.com/
https://www.googleapis.com/auth/gmail.modify
https://www.googleapis.com/auth/gmail.readonly
https://www.googleapis.com/auth/gmail.addons.current.message.metadata
https://www.googleapis.com/auth/gmail.addons.current.message.readonly
https://www.googleapis.com/auth/gmail.addons.current.message.action

コード

環境変数GOOGLE_CREDENTIALSGOOGLE_TOKENにそれぞれ準備した値が入っている前提です。

dotenvなど使うと便利ですね。

'use strict';

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

//認証関数
const authorize = () => {
    const credentials = JSON.parse(process.env.GOOGLE_CREDENTIALS);
    // console.log(credentials);
    const {client_secret, client_id, redirect_uris} = credentials.installed;
    const oAuth2Client = new google.auth.OAuth2(
        client_id,
        client_secret,
        redirect_uris[0]
    );
    oAuth2Client.setCredentials(JSON.parse(process.env.GOOGLE_TOKEN));

    return oAuth2Client;
}

//メッセージ取得関数
const getLastMessage = async (auth) => {
    const gmail = google.gmail({version: 'v1', auth});
    
    //メッセージリスト取得
    const resList = await gmail.users.messages.list({userId: 'me', q: 'from:news@xxxx.com'});
    const lastMessage = resList.data.messages[0]; //最新
    
    //メッセージIDから内容を取得
    const resMes = await gmail.users.messages.get({
      userId: 'me',
      id: lastMessage.id,
      format: 'FULL'
    });
    
    //base64で取得されるのでデコード
    const buf = new Buffer.from(resMes.data.payload.body.data, 'base64');
    const str = buf.toString();

    return str;
}

const main = async () => {
    const auth = authorize();
    const msg = await getLastMessage(auth);
    console.log(msg);
}
main();

トークン作成系のコードは削除しているので、トークン作成をしてから実行しましょう。

解説1: qオプションで検索

users.messages/listのAPIを利用する場合にqというオプションで検索することができます。

Only return messages matching the specified query. Supports the same query format as the Gmail search box. For example, "from:someuser@example.com rfc822msgid:somemsgid@example.com is:unread". Parameter cannot be used when accessing the api using the gmail.metadata scope.
https://developers.google.com/gmail/api/reference/rest/v1/users.messages/list

hogehogeだと hogehogeが含まれているメールを検索
from:someuser@example.comだと someuser@example.comから送られてきているメールを検索 みたいな感じでGmailで検索する際の指定のように扱えます。

解説2: 取得したメッセージはbase64デコード

gmail.users.message.get()で取得したメッセージの本文はbase64形式で返ってきます。

ドキュメントを見ると書いてますね。

string (bytes format)

The body data of a MIME message part as a base64url encoded string. May be empty for MIME container types that have no message body or when the body data is sent as a separate attachment. An attachment ID is present if the body data is contained in a separate attachment.

A base64-encoded string.
REST Resource: users.messages.attachments

ということで、そのままだと読めないのでデコード処理をしています。

//省略

const buf = new Buffer.from(resMes.data.payload.body.data, 'base64');
const str = buf.toString();

//省略

esMes.data.payload.body.dataにbase64文字列が入ってくるのでBufferでデコードしています。strでは通常のメール本文が見れます。

まとめと所感

トークン作成で少しハマりましたが、作成後は割となんなく扱えました。

gmail.users.messages.list()してからgmail.users.messages.get()をするという2ステップで実装してみましたが、もっとスマートなやり方があるような気がするのでもう少しドキュメント眺めてみたい

6
4
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
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?