LoginSignup
4
7

More than 3 years have passed since last update.

IMAPでGmailを受信する(Node.js編)

Last updated at Posted at 2019-06-30

ユーザ登録のフロー(メアド入力、メールの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

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