ユーザ登録のフロー(メアド入力、メールのURL開く、ユーザ情報入力)をE2Eテストしたかったのですが、gmailをプログラムで受信する検証をしていました。
要件
- 2017-01-01以降に送信され、送信者に「corec.jp」を含むメール
- gmailアカウントやパスワードは .env ファイルから読み込む
- vscodeでdebugできる
準備
- gmailの設定で「IMAPを有効」及び「安全性の低いアプリからのアクセスの許可」をオンにしておく
検証環境
- Windows10
- chocolateyでnode10系をインストール
node -v
v10.16.0
- 文字エンコーディングがiso-2022-jpのメールをUTF-8に変換するのに iconv を使った。
- simpleParserはiso-2022-jpに対応していないiconv-liteを使っている。
- Windowsでiconvをインストールするには下記のビルドツールを事前にインストールする必要があった。
- python2.7がインストールされる。python3系がすでにインストール済みの場合は注意が必要かも。
npm install --global --production windows-build-tools
npm install -g node-gyp
ソースコード
package.json
{
"name": "imap-gmail-sample",
"version": "1.0.0",
"description": "imap-gmail-sample",
"main": "gmail.js",
"scripts": {
"start": "env-cmd node gmail.js"
},
"keywords": [],
"author": "oharato",
"license": "MIT",
"dependencies": {
"env-cmd": "^9.0.3",
"iconv": "^2.3.4",
"imap-simple": "^4.3.0",
"mailparser": "^2.7.1"
}
}
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "nodejs",
"envFile": "${workspaceFolder}/.env",
"program": "${workspaceFolder}/gmail.js"
}
]
}
.env.sample
ACCOUNT=example@gmail.com
PASSWORD=example
gmail.js
// https://github.com/chadxz/imap-simple
const imaps = require('imap-simple');
const simpleParser = require('mailparser').simpleParser;
const iconv = require('iconv');
const config = {
imap: {
user: process.env.ACCOUNT,
password: process.env.PASSWORD,
host: 'imap.gmail.com',
port: 993,
tls: true,
}
};
// https://github.com/mscdex/node-imap#connection-instance-methods
const searchCriteria = [['FROM', 'corec.jp'],['SINCE', '2017-01-01']];
// https://github.com/chadxz/imap-simple#usage-of-mailparser-in-combination-with-imap-simple
const fetchOptions = {bodies: ['']};
(async()=>{
const connection = await imaps.connect(config);
await connection.openBox('INBOX');
const messages = await connection.search(searchCriteria, fetchOptions);
console.log('search results: '+messages.length);
for(let message of messages){
const part = message.parts.find(part => part.which === '');
// https://github.com/chadxz/imap-simple#usage-of-mailparser-in-combination-with-imap-simple
const mail = await simpleParser(`Imap-Id: ${message.attributes.uid}\r\n${part.body}`);
// simpleParserはiconv-liteを使っているのでiso-2022-jpを正しく変換できない
// charsetを見てiconvで変換
const match = mail.headerLines.find(o => o.key === "content-type").line.match(/charset="(.+)"/);
const charset = match ? match[1] : null;
if(charset){
const conv = new iconv.Iconv(charset, "UTF-8");
if(mail.subject) console.log('subject: ' + conv.convert(mail.subject).toString());
if(mail.text) console.log(conv.convert(mail.text).toString());
// if(mail.html) console.log(conv.convert(mail.html).toString());
}else{
console.log('subject: ' + mail.subject);
console.log(mail.text);
// console.log(mail.html);
}
// break;//テスト用に1件だけで止めたいときにコメントアウト外す
}
await connection.end();
})();
実行
cp .env.sample .env
# .env を任意のエディタで開き、ACCOUNTとPASSWORDを編集する
npm install
npm start
参照
さくっと手元で試したい人はこちらをgit cloneしてどうぞ
https://github.com/oharato/imap-gmail-sample