SendGridとNode-REDを利用した空メール登録システムのサンプルアプリケーションです。記事はSendGridのブログにて公開しています。
今回利用したツールとそのバージョンは次の通りです。
- Node.js:v16.5.0
- Node-RED:v2.0.6
- Gitクライアント:v2.31.1
- ngrok:v2.3.35
- Docker Engine:v20.10.8
- docker-compose:v2.0.0-rc.2
- SendGridアカウント
MacOSおよびAmazon Linux上で動作確認しています。各ツールのインストールを完了させます。
まずはじめに、Inbound Parse Webhookを受信するためにngrokを起動します。1880はNode-REDの待ち受けポート番号です。
$ ngrok http 1880
起動すると自動的にホスト名が付与されるのでメモしておきます。このホスト名は後でいくつかの場所に設定していきます。
![]() |
|---|
ドキュメントの手順に従ってInbound Parse Webhookを設定します。ポイントは以下のとおりです。
- Receiving Domain
- メールの宛先ドメイン
- Destination URL
- 「https://+ngrokの待受ホスト名+/inbound 」のフォーマットで指定します
- 例:https://5eae-101-110-33-89.ngrok.io/inbound
- Additional Option
- チェックはすべてOFFにします
![]() |
|---|
ドキュメントの手順に沿ってAPIキーを作成します。必要なパーミッションは「Mail Send」の「Full Access」です。
![]() |
|---|
作成したAPIキーは、次の手順で使用するためクリップボードにコピーしておきます。
![]() |
|---|
環境変数に以下のキーと値を登録します。
| キー | 値 |
|---|---|
| HTTP_HOSTNAME | ngrokのホスト名 例:5eae-101-110-33-89.ngrok.io |
| API_KEY | SendGridのAPIキー 例:SG.xxxxxxxxxxxxx.xxxxxxxxxxxxxx |
以下は「~/.bash_profile」に登録する例です。sourceコマンドで設定したファイルの内容を読み込んでおきます。
$ less ~/.bash_profile
export HTTP_HOSTNAME="5eae-101-110-33-89.ngrok.io"
export API_KEY="SG.xxxxxxxxxxxxx.xxxxxxxxxxxxxx"
$ source ~/.bash_profile
Node-REDを起動して設定ファイルなどを自動生成します。ポート番号1880がngrokの待ち受けポートと一致することを確認します。
$ cd ~
$ node-red
〜〜省略〜〜
6 Sep 18:10:05 - [info] フローを開始します
6 Sep 18:10:05 - [info] フローを開始しました
6 Sep 18:10:05 - [info] サーバは http://127.0.0.1:1880/ で実行中です
起動したらCtrl+Cキーで一旦Node-REDを停止します。
^C6 Sep 18:12:07 - [info] フローを停止します
6 Sep 18:12:07 - [info] フローを停止しました
Node-REDのsettings.jsファイルを編集します。
$ vi ~/.node-red/settings.js
「editorTheme > projects > enabled」の値を「true」に変更してプロジェクト機能を有効化します。
editorTheme: {
projects: {
enabled: true
}
},
settings.jsファイルを編集ししたらNode-REDをもう一度起動します。
$ node-red
〜〜省略〜〜
6 Sep 18:10:05 - [info] フローを開始します
6 Sep 18:10:05 - [info] フローを開始しました
6 Sep 18:10:05 - [info] サーバは http://127.0.0.1:1880/ で実行中です
ブラウザから「http://localhost:1880/ 」にアクセスしてNode-REDのフローエディタを表示します。プロジェクトの初期設定画面が表示されるので「Clone Repository」を選択します。
GitHubの「Username」と「Email」を設定して「Next」を選択します。
![]() |
|---|
以下のように設定して「Clone project」を選択します。
- Project name
- node-red-example
- Git repository URL
![]() |
|---|
いくつかのノードタイプがない旨エラーメッセージが表示されますが、ここではひとまず「Close」を選択して閉じます。
![]() |
|---|
画面右上のメニューから「Projects > Project Settings」を選択します。
![]() |
|---|
「Dependencies」を選択して、それぞれの依存関係をインストールします。
![]() |
|---|
「Close」を選択して設定画面を閉じます。
![]() |
|---|
一度ブラウザの画面をリロードします。
![]() |
|---|
以下のコマンドでMySQL環境を構築します。
$ cd ~/.node-red/projects/node-red-example/
$ docker-compose up -d --force-recreate --build
Building mysql
Step 1/4 : FROM mysql
---> 0716d6ebcc1a
Step 2/4 : EXPOSE 3306
---> Using cache
---> ac70f8c41da4
Step 3/4 : ADD ./my.cnf /etc/mysql/conf.d/my.cnf
---> Using cache
---> dc43457ed364
Step 4/4 : CMD ["mysqld"]
---> Using cache
---> ef69d0e239e3
Successfully built ef69d0e239e3
Successfully tagged mysql:inbound
Recreating noderedexample_mysql_1 ... done
MySQL環境構築のために1分ほど待ってから、以下のコマンドでMySQLが起動していることを確認します。
$ docker-compose logs
〜〜省略〜〜
mysql_1 | 2021-09-08T08:24:40.537761Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysql_1 | 2021-09-08T08:24:40.538093Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.26' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
MySQLが起動したら環境構築は完了です。
Inbound Parse Webhookで設定した受信ドメイン宛に空メールを送ります。ローカルパートは適当な文字列を指定します。
![]() |
|---|
ngrokがInbound Parse Webhookを受信すると「200 OK」が表示されます。
![]() |
|---|
Node-REDの画面上で「debug」ボタンを選択すると、デバッグログが確認できます。この中に「statusCode: 202」の表示があれば、SendGridに対するメール送信リクエストが成功しています。
![]() |
|---|
しばらく待つとユーザー登録用メールが届くので、メール本文内のURLにアクセスします。
![]() |
|---|
ブラウザ上にユーザー登録フォームが表示されるので、適当なニックネームを入力して「送信」を選択します。
![]() |
|---|
登録に成功すると以下のようなメッセージが表示されます。
![]() |
|---|
一方、既に同じメールアドレスが登録済みなど、登録に失敗した場合は以下のようなメッセージが表示されます。
![]() |
|---|
![]() |
|---|
以上で動作確認完了です。
このサンプルを利用する際の注意点は以下の通りです。
- データベースのパスワードはdocker-compose.ymlに直書きしてあるので、環境変数から読み込むようにするなど、パスワードが晒されないようにしてください
- ノードのプロパティに保存する認証情報を暗号化する場合は、Node-REDのセキュアパラメータ暗号化機能を有効化してください



















