Cloudflare Email Workers でメールを受信したら Chatwork に通知する
はじめに
この記事はCloudflare Email Workers に関する記事です。
- Email受信をトリガーにしてCloudflare Workersを実行したい
- Cloudflare WorkersでChatworkに通知したい
上記に当てはまる方のお役に立てるかと思います。
Cloudflare 周りの説明
Cloudflare Workers とは
Cloudflare Workersは、サーバーレスコードをデプロイすることで、優れたパフォーマンス、信頼性、および拡張性をグローバルに提供するプラットフォームです。
このプラットフォームを使用することで、最新のクラウド向けアプリケーションを構築することが可能となります。
Cloudflare Email Workers とは
Cloudflare Email Workersは、Route to Workers 機能を利用して、受信したメールを EmailEvent として Workers ロジックを経由して転送する機能を提供します。
この機能は、特定の前提条件として Email Routing の設定が必要となります。
Cloudflare Email Routing を始めるには
以下のURLを参照いただければと思います。
Wrangler とは
Wranglerは、Cloudflare Workers用のコマンドラインインターフェース(CLI)ツールで、簡単なコマンド入力でWorkers用プロジェクトの作成からビルド、デプロイまでを行うことができます。
Wrangler のインストール
npmで wrangler をインストール
npm install -g wrangler
wrangler バージョンの確認
wrangler -v
2023年10月時点で 3.13.2 が確認できます
⛅️ wrangler 3.13.2
-------------------
wrangler でプロジェクトを作成しデプロイする
wrangler ログイン
以下のコマンドでブラウザの認証画面からログインが可能です
wrangler login
wrangler プロジェクトの作成
以下のコマンドでプロジェクトの作成ができます
wrangler init chatwork-notify
postal-mime のインストール
プロジェクトディレクトリへ移動し、 postal-mime
をインストールします
cd chatwork-notify
npm install postal-mime
index.js の編集
chatwork-notify/src/index.js
を編集しメールを受けた際に
- Chatworkへ通知
- リストの配送先に転送
を実装します
const PostalMime = require('postal-mime');
const CW_API_ENDPOINT = "https://api.chatwork.com/v2/rooms/";
export default {
async email(message, env, ctx) {
ctx.waitUntil(notifyMessage(message, env));
}
};
const streamToArrayBuffer = async (stream, streamSize) => {
let result = new Uint8Array(streamSize);
let bytesRead = 0;
const reader = stream.getReader();
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
result.set(value, bytesRead);
bytesRead += value.length;
}
return result;
};
const buildNotifyMessage = async (message, parsedEmail, relayEmails) => {
return `
[info]
[title]Notifications from Cloudflare Mail Email Workers[/title]
From: ${message.from}
To: ${message.to}
[code]
Message-id: ${message.headers.get('message-id')}
Received: ${message.headers.get('received')}
Date: ${message.headers.get('date')}
[/code]
[info]
Title: ${message.headers.get('subject')}
Body:
${parsedEmail.text}
[/info]
[code]
# Forwarding Email Addresses
${relayEmails.join(', ')}
[/code]
[/info]`;
};
const sendChatwork = async (notifyMessage, env) => {
try {
const cwBody = new URLSearchParams({
body: notifyMessage,
});
const cwHeaders = new Headers();
cwHeaders.append("Content-Type", "application/x-www-form-urlencoded");
cwHeaders.append("X-ChatWorkToken", env.CHATWORK_TOKEN);
const cwRequest = new Request(`${CW_API_ENDPOINT}${env.CHATWORK_ROOM}/messages/?${cwBody.toString()}`, {
headers: cwHeaders,
method: 'POST',
});
let cwResponse = await fetch(cwRequest);
console.log(cwResponse);
} catch (e) {
console.error(e);
}
};
const notifyMessage = async function (message, env) {
try {
const relayEmails = JSON.parse(env.RELAY_EMAILS);
const rawEmail = await streamToArrayBuffer(message.raw, message.rawSize);
const parser = new PostalMime.default();
const parsedEmail = await parser.parse(rawEmail);
const notifyMessage = await buildNotifyMessage(message, parsedEmail, relayEmails);
console.log('parsedEmail: ', parsedEmail);
await Promise.all(relayEmails.map(email => message.forward(email)));
await sendChatwork(notifyMessage, env);
} catch (e) {
console.error(e);
}
};
wrangler.toml の編集
環境変数を設定するために wrangler.toml
を編集します
以下の情報へ変更して下さい
-
CHATWORK_TOKEN
は Chatwork API のトークン -
CHATWORK_ROOM
は Chatwork のルームID -
RELAY_EMAILS
は 転送先のメールアドレスの配列
name = "chatwork-notify"
main = "src/index.js"
compatibility_date = "2023-10-01"
#node_compat = true
vars = { CHATWORK_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", CHATWORK_ROOM = "XXXXXXXXX", RELAY_EMAILS = '["email1@example.com", "email2@example.com"]' }
Cloudflare Workers へデプロイ
以下のコマンドでログイン中のアカウントへデプロイが可能です
npx wrangler deploy
最後に
Cloudflare Email Workers でメールを受信したら Chatwork に通知する方法をご紹介しました。
Cloudflare Email Routing の設定を行い、受信から Workers へ流すだけで Chatwork への通知とメールの転送が可能になりました。
メールを受信したら PDF化し R2への保存、添付ファイルのR2への保存なども今後やっていきたいと思います。
最後まで読んでいただき、ありがとうございました!
Discussion