Webhook APIを使って添付ファイル付きメールを処理する(Node.js編)

Customers Mail Cloudではプログラム側からデータを取得したり、メールを送信するWeb APIの他に、Customers Mail Cloudでメールを受信した時にイベントを伝えてくれるWebhook APIが用意されています。

Webhook APIを使うことで、自前でメールサーバを立てずにメール受信のタイミングでシステムを起動させられるようになります。メールサーバを安定して動作させ続けるのはメンテナンスコストが大きいですが、Customers Mail Cloudを使うことで簡単にメールと連携したシステムが作れるようになるでしょう。

今回はNode.jsとExpressを使ってメールを処理する流れを紹介します。

フォーマットはJSONとマルチパートフォームデータ

Webhookの形式として、JSONとマルチパートフォームデータ(multipart/form-data)が選択できます。この二つの違いは、添付ファイルがあるかどうかです。JSONの場合、添付ファイルは送られてきません。メールに添付ファイルがついてくる可能性がある場合は、後者を選択してください。

f:id:moongift:20200227212807p:plain
Webhook設定ダイアログ

今回は添付ファイル付きのメールを処理してみます。

サーバ側のコード

Expressで作ったサーバ側のコードは次のようになります。まず必要なライブラリを読み込みます。 multer は送信されてきたファイルを処理するライブラリです。

const express     = require('express');
const bodyParser  = require('body-parser');
const fs = require('fs');
const multer  = require('multer');

続いてライブラリの初期化をします。通常、ExpressではボディデータをJSON化するのが便利ですが、今回はデータがmultipartで送られてきます。そのため、JSONとそれ以外の場合で2つ定義します。

const upload = multer();
const app = express();
app.use(express.json({ type: 'application/*+json' }));

app.use(express.urlencoded({
  extended: false,
  type: 'application/x-www-form-urlencoded'
}));

実際の処理部分です。メールの件名と本文、送信元と送信先アドレスを出力しています。また、添付ファイルは upload.any() を定義しておくことで、 req.files に入ってきます。後はその内容をファイルとして書き出しています。

app.post('/', upload.any(), function(req, res) {
  const params = req.body;
  console.log(`件名: ${params.subject}`);
  console.log(`本文(テキスト): ${params.text}`);
  console.log(`本文(HTML): ${params.html}`);
  console.log(`送信元: ${params['envelope-from']}`);
  console.log(`送信先: ${params['envelope-to']}`);
  for (let file of req.files) {
    fs.writeFileSync(`./files/${file.originalname}`, file.buffer);
  }
  res.send('success');
});

app.listen(3000);

具体的なデータ構造は次のようになっています。

{
    "filter": "info@smtps.jp",
    "headers": [
      :
    ],
    "subject": "テストメール",
    "envelope-to": "info@smtps.jp",
    "server_composition": "sandbox",
    "html": "<div dir=\"ltr\">これはテストのメールです。<div>...</div></div>",
    "text": "これはテストのメールです。\r\n\r\n--\r\n...",
    "envelope-from": "admin@smtps.jp"
}

添付ファイルはattachmensに添付ファイルの数、attachment1、attachment2にそれぞれ添付ファイルの内容が入ってきます。構造は次のようになります。

  • attachments
  • attachment1
    • filename
    • type
    • name
    • tempfile
    • head:
      • Content-Disposition
      • filename
      • Content-Type
      • Content-Transfer-Encoding

ただし、multerで処理すると次のようになっています。

{
  "fieldname": "attachment1",
  "originalname": "package.json",
  "encoding": "binary",
  "mimetype": "application/json",
  "buffer": <Buffer 7b 0d ... 218 more bytes>,
  "size": 268
}

Webhookの結果は管理画面で確認

Webhookでデータが送信されたログは管理画面で確認できます。送信時のAPIキー設定など、HTTPヘッダーを編集するといった機能も用意されていますので、運用に応じて細かなカスタマイズが可能です。

f:id:moongift:20200227212832p:plain
Webhookログ

画像は添付ファイルになりません

メールの添付ファイルとしてはZipファイルやJSONファイルなどは送れたのですが、画像を添付しても添付ファイルとして認識されなかったので注意してください。

まとめ

メールと連携したシステムはよくあります。通常、メールサーバを立てて、その中で処理することが多いのですが、メールサーバが落ちてしまうとシステムが稼働しなくなったり、メール文面の解析が煩雑でした。Customers Mail Cloudを使えばそうした手間なくJSONで処理できて便利です。

受信サーバ | Customers Mail Cloud