久しぶりにGmail APIのチュートリアルを見たらアップデートされてたので試してみました。
ここでは、 特定のメールから届いてるメールの最新の値を取得してみます。
認証情報の準備
Google公式ライブラリを利用してNode.jsからGmailの送受信をしてみようや公式チュートリアルを参考に、クレデンシャル
とトークン
の情報を取得しましょう。
スコープ
メソッド的には、gmail.users.messages.list
とgmail.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_CREDENTIALS
とGOOGLE_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ステップで実装してみましたが、もっとスマートなやり方があるような気がするのでもう少しドキュメント眺めてみたい