Ⅰ. はじめに
Gmailは2022年5月30日に「安全性の低いアプリ」からのアクセスを終了します。
例えばSMTPでパスワード認証を利用している場合が該当します。
この記事ではOAuth認証をする事によって2022年5月30日以降もメールを送信する方法を紹介します。
Ⅱ. 手順
1. OAuth用の認証情報を作成する
https://console.cloud.google.com/apis/credentials
※「アプリケーションの種類」は「デスクトップアプリ」を選択する
※プロジェクトの新規作成を求められた場合は新規作成する。
スコープを指定する必要はない。
※OAuth同意画面の新規作成を求められた場合は新規作成する。
公開ステータスがテストの場合はテストユーザーを追加する。
2. 「クライアントID」「クライアントシークレット」をメモする
3. 以下スクリプトを実行して「リフレッシュトークン」を取得する
※2022/03/31 追記
「urn:ietf:wg:oauth:2.0:oob」が非推奨になったようです
以下スクリプトはテスト環境のみで動作します
https://takuya-1st.hatenablog.jp/entry/2022/03/14/171939
index.mjs
// Node v18.9.1で動作確認 // npm install open node-fetch import readline from 'node:readline/promises' import open from 'open' import fetch from 'node-fetch' function generateQueryString (parameters) { return parameters.map(x => `${x.key}=${encodeURI(x.value)}`).join('&') } (async () => { const clientId = 'ENTER_YOUR_CLIENT_ID' const clientSecret = 'ENTER_YOUR_CLIENT_SECRET' const redirectUri = 'urn:ietf:wg:oauth:2.0:oob' const parameters = [ { 'key': 'client_id', value: clientId }, { 'key': 'redirect_uri', value: redirectUri }, { 'key': 'response_type', value: 'code' }, { 'key': 'scope', value: 'https://mail.google.com/' } ] const url = `https://accounts.google.com/o/oauth2/auth?${generateQueryString(parameters)}` open(url) const rl = readline.createInterface({ input: process.stdin, output: process.stdout }) const code = await rl.question('Enter code:'); console.log(code) const response = await fetch('https://www.googleapis.com/oauth2/v4/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: generateQueryString([ { 'key': 'client_id', 'value': clientId }, { 'key': 'client_secret', 'value': clientSecret }, { 'key': 'redirect_uri', 'value': redirectUri }, { 'key': 'grant_type', 'value': 'authorization_code' }, { 'key': 'code', 'value': code } ]) }) const json = await response.json() console.log(json) })()
4. 以下スクリプトを実行してメールを送信する
index.mjs
// npm install nodemailer import nodemailer from 'nodemailer' (async () => { const clientId = 'ENTER_YOUR_CLIENT_ID' const clientSecret = 'ENTER_YOUR_CLIENT_SECRET' const to = 'user001@example.com' const myGmailAddress = 'user002@gmail.com' const refreshToken = 'ENTER_YOUR_REFRESH_TOKEN' const transporter = nodemailer.createTransport({ host: 'smtp.gmail.com', port: 465, secure: true, auth: { type: 'OAuth2', clientId: clientId, clientSecret: clientSecret, } }) transporter.on('token', token => { console.log(`AccessToken: ${token.accessToken}`) console.log(`Expires: ${new Date(token.expires)}`) }) const response = await transporter.sendMail({ to: to, subject: 'Subject', text: 'Hello world!', auth: { user: myGmailAddress, // accessToken: 'ya29....', refreshToken: refreshToken } }) console.log(response) })()
実行結果
省略