エクセル自動作成・添付ファイル付きメール送信¶
様々な形式のファイル(テキスト、画面スクショ、外部画像、動的生成Excelなど)をメールに添付して送信するサンプルフローです。
業務での自動レポート送付、システム異常検知時のエビデンス送付、さらにはデータからのExcelファイル自動生成・添付などに活用できます。
以下の「サンプルフローのJSONコードを展開する」をクリックし、中のJSONデータをコピーしてロボシュタインのメニューから「インポート」を実行してください。
サンプルフローのJSONコードを展開する
[{"id":"f5fe8e976ad740ad","type":"tab","label":"フロー 2","disabled":false,"info":"","env":[]},{"id":"d3fa28043075ee36","type":"comment","z":"f5fe8e976ad740ad","name":"【パターン①】テキストデータをその場でファイル化して添付送信","info":"injectで指定したテキストを、changeノードでファイル名を設定して送信します。","x":300,"y":120,"wires":[]},{"id":"bbd4a5580fc2d325","type":"comment","z":"f5fe8e976ad740ad","name":"【パターン②】Webサイトのスクリーンショットを撮影して添付送信","info":"Webサイト情報取得ノードで画面を撮影し、画像バイナリデータをファイル添付して送信します。","x":310,"y":200,"wires":[]},{"id":"9369d1aeeef9df05","type":"comment","z":"f5fe8e976ad740ad","name":"【パターン③】外部のWeb上にある画像URLを指定してダウンロード添付送信","info":"メール送信ノード内でURLを直接指定して、自動ダウンロード添付します。","x":330,"y":280,"wires":[]},{"id":"a685331ac316e074","type":"comment","z":"f5fe8e976ad740ad","name":"【パターン④】エクセルを動的作成し、ファイル保存せず直接添付送信","info":"","x":310,"y":380,"wires":[]},{"id":"49f48f745425c16a","type":"comment","z":"f5fe8e976ad740ad","name":"【パターン⑤】エクセルを作成後、ファイル保存(/users.xlsx)してからパス指定で添付送信","info":"保存しているファイル名が異なっていても送れます","x":380,"y":480,"wires":[]},{"id":"613d576afee0d09a","type":"inject","z":"f5fe8e976ad740ad","name":"実行","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"これはNode-REDから送信された添付ファイルの内容です。","payloadType":"str","x":190,"y":160,"wires":[["57cb049d20c9fb43"]]},{"id":"57cb049d20c9fb43","type":"change","z":"f5fe8e976ad740ad","name":"メール情報の設定","rules":[{"t":"set","p":"content","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"filename","pt":"msg","to":"test_document.txt","tot":"str"}],"x":400,"y":160,"wires":[["184c8d802b9c0f70"]]},{"id":"184c8d802b9c0f70","type":"awsses-send","z":"f5fe8e976ad740ad","name":"メール送信(テキスト)","from":"","to":"","toType":"str","detailSettings":false,"cc":"","ccType":"str","bcc":"","bccType":"str","inReplyTo":"","inReplyToType":"str","replyTo":"","replyToType":"str","references":"","referencesType":"str","subject":"","subjectType":"str","format":"text","body":"","bodyType":"str","files":[],"x":630,"y":160,"wires":[["2e85081f61b6e636"]]},{"id":"2e85081f61b6e636","type":"debug","z":"f5fe8e976ad740ad","name":"ログ出力(テキスト添付)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":880,"y":160,"wires":[]},{"id":"3e22fecfc9d6654b","type":"inject","z":"f5fe8e976ad740ad","name":"実行","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":240,"wires":[["70222871b4a4472b"]]},{"id":"70222871b4a4472b","type":"site-login","z":"f5fe8e976ad740ad","name":"Webサイト情報取得","viewwidth":1280,"viewheight":720,"url":"https://www.google.com/","urlType":"str","timeout":30000,"waitfor":3000,"useragent":"","formactions":[],"conditions":[{"f":"page.screenshot","o":"screenshot","ot":"msg"}],"x":430,"y":240,"wires":[["24bc029076178b1d"]]},{"id":"24bc029076178b1d","type":"awsses-send","z":"f5fe8e976ad740ad","name":"メール送信(スクショ)","from":"","to":"","toType":"str","detailSettings":false,"cc":"","ccType":"str","bcc":"","bccType":"str","inReplyTo":"","inReplyToType":"str","replyTo":"","replyToType":"str","references":"","referencesType":"str","subject":"","subjectType":"str","format":"text","body":"","bodyType":"str","files":[{"name":"sample.png","nameType":"str","select":"data","content":"screenshot","contentType":"msg"}],"x":660,"y":240,"wires":[["a88591f8d80934ce"]]},{"id":"a88591f8d80934ce","type":"debug","z":"f5fe8e976ad740ad","name":"ログ出力(スクショ添付)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":920,"y":240,"wires":[]},{"id":"029f5d12a060e74b","type":"inject","z":"f5fe8e976ad740ad","name":"実行","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":320,"wires":[["95b2e0329701fed0"]]},{"id":"95b2e0329701fed0","type":"awsses-send","z":"f5fe8e976ad740ad","name":"メール送信(URL指定)","from":"","to":"","toType":"str","detailSettings":false,"cc":"","ccType":"str","bcc":"","bccType":"str","inReplyTo":"","inReplyToType":"str","replyTo":"","replyToType":"str","references":"","referencesType":"str","subject":"","subjectType":"str","format":"text","body":"","bodyType":"str","files":[{"name":"sample.png","nameType":"str","select":"path","content":"https://manual.robostein.io/images/send-email02.png","contentType":"str"}],"x":380,"y":320,"wires":[["f50ce88217370a0c"]]},{"id":"f50ce88217370a0c","type":"debug","z":"f5fe8e976ad740ad","name":"ログ出力(URL添付)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":680,"y":320,"wires":[]},{"id":"45951a3a9b1b04fe","type":"inject","z":"f5fe8e976ad740ad","name":"実行","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":420,"wires":[["84dab6c7a5107775"]]},{"id":"84dab6c7a5107775","type":"function","z":"f5fe8e976ad740ad","name":"エクセル作成ノード","func":"const wb = XLSX.utils.book_new();\n\nconst ws = XLSX.utils.json_to_sheet([\n { name: \"田中\", age: 30 },\n { name: \"佐藤\", age: 25 }\n]);\n\nXLSX.utils.book_append_sheet(wb, ws, \"users\");\nmsg.content = XLSX.write(wb, {\n type: \"buffer\",\n bookType: \"xlsx\"\n});\nmsg.filename = \"users.xlsx\";\n//msg.contentとmsf.filenameに適切な値が格納されていれば、\n//後続のRSメール送信ノードの添付ファイルに設定する必要はありません\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"XLSX","module":"xlsx"}],"x":390,"y":420,"wires":[["40e4453798b6ca39"]]},{"id":"40e4453798b6ca39","type":"awsses-send","z":"f5fe8e976ad740ad","name":"メール送信(Excelメモリ添付)","from":"","to":"","toType":"str","detailSettings":false,"cc":"","ccType":"str","bcc":"","bccType":"str","inReplyTo":"","inReplyToType":"str","replyTo":"","replyToType":"str","references":"","referencesType":"str","subject":"","subjectType":"str","format":"text","body":"","bodyType":"str","files":[],"x":650,"y":420,"wires":[["0cdaed3a76a6a297"]]},{"id":"0cdaed3a76a6a297","type":"debug","z":"f5fe8e976ad740ad","name":"ログ出力(Excelメモリ添付)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":950,"y":420,"wires":[]},{"id":"2d7a4e80d1c56fd3","type":"inject","z":"f5fe8e976ad740ad","name":"実行","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":520,"wires":[["2c858d6cf439f8df"]]},{"id":"2c858d6cf439f8df","type":"function","z":"f5fe8e976ad740ad","name":"エクセル作成ノード","func":"const wb = XLSX.utils.book_new();\n\nconst ws = XLSX.utils.json_to_sheet([\n { name: \"田中\", age: 30 },\n { name: \"佐藤\", age: 25 }\n]);\n\nXLSX.utils.book_append_sheet(wb, ws, \"users\");\nmsg.payload = XLSX.write(wb, {\n type: \"buffer\",\n bookType: \"xlsx\"\n});\nmsg.filename = \"users.xlsx\";\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"XLSX","module":"xlsx"}],"x":390,"y":520,"wires":[["4540166f839de07a"]]},{"id":"4540166f839de07a","type":"rs-file","z":"f5fe8e976ad740ad","name":"RSファイル保存ノード","filename":"","appendNewline":false,"overwriteFile":"true","encoding":"none","x":670,"y":520,"wires":[["4bef5ecd249acd83"]]},{"id":"4bef5ecd249acd83","type":"debug","z":"f5fe8e976ad740ad","name":"ログ出力(ファイル保存完了)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":970,"y":520,"wires":[]},{"id":"f3e32aa905cd890b","type":"inject","z":"f5fe8e976ad740ad","name":"実行","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":560,"wires":[["4800e5354245f533"]]},{"id":"4800e5354245f533","type":"awsses-send","z":"f5fe8e976ad740ad","name":"メール送信(パス指定添付)","from":"","to":"","toType":"str","detailSettings":false,"cc":"","ccType":"str","bcc":"","bccType":"str","inReplyTo":"","inReplyToType":"str","replyTo":"","replyToType":"str","references":"","referencesType":"str","subject":"","subjectType":"str","format":"text","body":"","bodyType":"str","files":[{"name":"users.xlsx","nameType":"str","select":"path","content":"/users.xlsx","contentType":"str"}],"x":420,"y":560,"wires":[["66df4ad751ee4598"]]},{"id":"66df4ad751ee4598","type":"debug","z":"f5fe8e976ad740ad","name":"ログ出力(パス指定送信)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":740,"y":560,"wires":[]}]
上記をインポートすると、以下のように用途に合わせた処理フローが展開されます。

各送信パターンの概要¶
添付ファイルの準備および指定方法に応じて、以下の送信パターンが用意されています。用途に合わせて最適なパターンを選択してください。
| パターン | トリガー | 主な処理内容 | 添付されるファイル形式 |
|---|---|---|---|
| ① テキストデータの添付 | 実行(1段目) | 任意の文字列をその場で test_document.txt としてファイル化して添付 |
プレーンテキスト(.txt) |
| ② スクリーンショットの添付 | 実行(2段目) | Webサイト情報取得ノードで画面を撮影し、バイナリデータをそのまま添付 | 画像データ(.png) |
| ③ 外部URLファイルの添付 | 実行(3段目) | 外部のWeb上にあるファイルをURLから自動ダウンロードして添付 | URL先のファイル(.png 等) |
| ④ Excel自動生成・メモリ直接添付 | 実行(4段目) | Functionノードで配列データからExcel(.xlsx)を動的作成し、ファイル保存せずメモリ上で直接添付送信(推奨) |
エクセル(.xlsx) |
| ⑤ Excel作成・ファイル保存後のパス指定添付 | 実行(5〜6段目) | 動的作成したExcelを RSファイル保存ノード で /users.xlsx に書き出した後、パス指定で添付送信 |
エクセル(.xlsx) |
💡 パターン①・④における添付データの自動認識仕組み¶
パターン①(テキスト)およびパターン④(Excelメモリ添付)のラインでは、メール送信ノードの添付ファイル設定(プロパティ)を空欄のままにしてあります。
メール送信ノードは、引き渡されたメッセージオブジェクト(msg)内に以下のプロパティが存在する場合、自動的にそれを検知してメール添付する仕様になっています。
msg.content: 添付したいデータ(テキスト文字列、またはバイナリBufferデータ)msg.filename: 受信者に表示される添付ファイル名(例:test_document.txtやusers.xlsx)
パターン①(changeノードでのマッピング)¶
inject ノードから届いたテキスト(msg.payload)を、change ノード(表示名:メール情報の設定)を使って msg.content にセットし、msg.filename にファイル名を代入しています。
パターン④(FunctionノードでのExcel動的作成)¶
XLSX ライブラリを使用してデータを組み立て、バイナリバッファーとして msg.content に格納しています。
const wb = XLSX.utils.book_new();
// JSON配列データからワークシートを作成
const ws = XLSX.utils.json_to_sheet([
{ name: "田中", age: 30 },
{ name: "佐藤", age: 25 }
]);
XLSX.utils.book_append_sheet(wb, ws, "users");
// バッファーデータとして msg.content に格納
msg.content = XLSX.write(wb, {
type: "buffer",
bookType: "xlsx"
});
// 添付ファイル名を指定
msg.filename = "users.xlsx";
return msg;
💡 パターン⑤(ファイル保存を経由する場合)の手順¶
生成したExcelファイルをバックアップとしてサーバー上に保存しておきたい場合は、RSファイル保存ノード を挟みます。
- Functionノード: バイナリデータを
msg.payloadに格納します。 - RSファイル保存ノード: 保存先パス(例:
/users.xlsx)を指定してファイルを書き出します。 - RSメール送信ノード: プロパティの「添付ファイル」設定で
ファイルパスを選び、/users.xlsxを指定して送信します。
使用している主要ノードの解説
本フローの制御には、以下のノードの仕組みを利用しています。ノードの詳しい仕様や応用的な使い方については、それぞれの専門ページをご確認ください。
- データ加工・プロパティ変更: changeノードの解説
- 画面キャプチャ・自動操作の要: Webサイト情報取得ノードの解説
- メールの送信・連携設定: メール送信ノードの解説
- ファイルのディスク保存処理: ファイル保存ノードの解説
実行結果の確認(デバッグ)¶
すべての送信ラインの末尾には debug ノードが接続されています。
それぞれの「実行」ボタンを押下後、正常に送信処理が完了すると、AWS SESから返却されたメッセージID(messageId)やレスポンスを含むメタデータオブジェクトが画面右側のデバッグタブに出力されます。
確認のポイント
エラーが発生した場合は、デバッグタブに赤文字でエラー原因(認証エラーやアドレス未検証など)が出力されます。正常に msg オブジェクトが返却されているか、ログのプロパティ階層を展開して確認してください。