Mautic x Node-REDでデータ連携

[Mautic Advent Calendar 2017](https://adventar.org/calendars/2303) の14日目を担当します、kolinzことNishikawa([プロフィール](https://8card.net/p/knishikawa))です。

#概要
Mauticに新規コンタクトやフォーム送信時にSlack通知する場合、公式にはZapier Integrationを使います。とはいえ、Zapierは日本語提供はしていませんし、無料枠では連携で2ステップまでなど制限があります。
ということで、日本語で使えて各種APIやWebサービス、データ連携に使える「Node-RED」を用いてみます。

#Node-REDを準備する
Node-REDは、Node.jsで動きますのでどこでも動きます。Raspberry Pi用OSのRaspbianにはNode-REDが標準搭載されています。

##Mauticとは別サーバーに用意する場合
このケースでは、無料のIBM Cloud ライトアカウント([こちら](https://www.ibm.com/cloud-computing/jp/ja/bluemix/lite-account/))を使うとNode-REDのセキュリティ設定もまとめて出来て簡単です。

##独自に用意する場合
別途用意するといった場合は、ポート1880を使用しますので、Webブラウザでアクセスできるようにファイアウォール等を設定します。またセキュリティ設定が個別に必要になることがあります。Ubuntu系はまた手順が異なります。別の機会に紹介できればと思います。

CentOS系の場合

```
$ sudo yum install curl
$ sudo yum install -y gcc-c++ make
$ curl -sL https://rpm.nodesource.com/setup_8.x | bash -
$ sudo yum install -y nodejs
$ sudo npm install -g --unsafe-perm node-red
$ sudo npm install -g pm2
$ sudo pm2 start /usr/bin/node-red -- -v
```

Node-REDにアクセスした時にログイン画面が表示されない場合は、セキュリティ設定を有効にする必要があります。

```
$ nano /ユーザー名/.node-red/settings.js

adminAuth: {
        type: "credentials",
        users: [{
            username: "admin",
            password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
            permissions: "*"
        }]
    },

上記で、各行の //を外し保存します。
```
password部分は、ハッシュ化されておりデフォルトでは、password になっています。settings.js設定後はサーバーを再起動します。

##Node-REDにアクセス
Webブラウザで、IBM Cloud ライトアカウントをご使用の場合は、ダッシュボードから作成したNode-RED環境を選択し「アプリのURL」からアクセスできます。
独自に用意する場合は、たとえばホスト名 node、ドメイン名 example.com で運用している場合は、http://node.example.com:1880 でアクセスします。


#Mautic Webhookの準備
今回は、Mauticにログインし、設定のWebhooks にて、フォーム送信時に発動するようにイベントを指定するとともに「Webhook Post URL」に、Node-REDのURL/mautic とし、このURLでJSON形式でデータを受け、Node-REDで定義した処理が実行されます。

![mautic_webhook.PNG](https://qiita-image-store.s3.amazonaws.com/0/41414/d586a93e-841f-2bc1-bce3-cc8ac9216630.png)


#連携例
## Webhook例：Slack通知

この例は、Mauticのフォームに回答されたデータが、Slackに通知されるというものです。Slackを社内メール代わりに使っている人や組織にとっては便利でしょう。

![mautic_webhook_slack投稿.PNG](https://qiita-image-store.s3.amazonaws.com/0/41414/7ba5b8ef-05ab-5112-5aab-a1d69628ca71.png)

Node-REDに下記ノードを追加します。

- node-red-contrib-slack

サンプルコード

- Node-RED画面で、画面右上「三」→読み込み→クリップボードでサンプルコードを読み込みます。

```
[{"id":"c0cfe794.e26f18","type":"tab","label":"Webhook : Mautic to Slack","disabled":false,"info":""},{"id":"e9ffcde3.c5d7f","type":"http in","z":"c0cfe794.e26f18","name":"","url":"/mautic","method":"post","upload":false,"swaggerDoc":"","x":127,"y":110,"wires":[["3fda7d8d.6705a2","bac4a32f.9be1b"]]},{"id":"f07b7441.805da8","type":"http response","z":"c0cfe794.e26f18","name":"","statusCode":"","headers":{},"x":661,"y":53,"wires":[]},{"id":"3fda7d8d.6705a2","type":"debug","z":"c0cfe794.e26f18","name":"debug webhook","active":true,"console":"false","complete":"payload","x":432,"y":169,"wires":[]},{"id":"bac4a32f.9be1b","type":"function","z":"c0cfe794.e26f18","name":"Convert to Slack","func":"msg.payload = \"新規DL通知です。\" + \" https://your-mauticdomain/s/contacts/view/\" + msg.payload[\"mautic.form_on_submit\"][0].submission.lead.id + \"\";\nreturn msg;","outputs":1,"noerr":0,"x":434,"y":110,"wires":[["afc370b1.e39c2","34066082.2feb","f07b7441.805da8"]]},{"id":"afc370b1.e39c2","type":"debug","z":"c0cfe794.e26f18","name":"","active":true,"console":"false","complete":"false","x":678,"y":172,"wires":[]},{"id":"34066082.2feb","type":"slack","z":"c0cfe794.e26f18","name":"","channelURL":"","username":"","emojiIcon":"","channel":"","x":664,"y":109,"wires":[]}]
```

## DB接続例：セルフホスティング版MauticのDBからCSV出力

次は、Node-REDサーバーをMauticサーバーと同じネットワーク上に別サーバーとして設置し、MauticサーバーとNode-REDサーバーがプライベートIPで通信できるものとします。同時に外部向けにはMySQLポートを開かないものとします。
この状態で、MauticのDBを読み込み、クエリーを実行してCSV出力するサンプルです。CSV出力することで、BI(Business Intelligence)システムに引き渡す等が実現しやすくなります。

![mautic_mysql.PNG](https://qiita-image-store.s3.amazonaws.com/0/41414/f0dd97a6-690f-525f-95b9-c2b6f4c44a4a.png)

Node-REDに下記ノードを追加します。

- node-red-node-mysql

サンプルコード

- Node-RED画面で、画面右上「三」→読み込み→クリップボードでサンプルコードを読み込みます。

```
[{"id":"733c1fb0.2d612","type":"tab","label":"Connect MySQL & Output CSV","disabled":true,"info":""},{"id":"c9400462.fa4e78","type":"mysql","z":"733c1fb0.2d612","mydb":"f94f0d84.1e4ca","name":"mautic database","x":470,"y":40,"wires":[["75ece866.0d3d08","aaf74525.8a6f18"]]},{"id":"f45e5d16.fcf6a","type":"inject","z":"733c1fb0.2d612","name":"","topic":"","payload":"","payloadType":"date","repeat":"3600","crontab":"","once":true,"x":130,"y":40,"wires":[["1cae3f15.ea56a1"]]},{"id":"1cae3f15.ea56a1","type":"function","z":"733c1fb0.2d612","name":"query","func":"msg.topic =\"SELECT id as contact_id ,date_added ,date_modified ,points ,firstname ,lastname ,company ,email ,country ,state ,twitter FROM leads WHERE email IS NOT NULL AND date_modified IS NULL\";\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":40,"wires":[["c9400462.fa4e78"]]},{"id":"75ece866.0d3d08","type":"debug","z":"733c1fb0.2d612","name":"","active":true,"console":"false","complete":"payload","x":700,"y":40,"wires":[]},{"id":"aaf74525.8a6f18","type":"csv","z":"733c1fb0.2d612","name":"","sep":",","hdrin":"","hdrout":true,"multi":"one","ret":"\\n","temp":"contact_id,date_added,date_modified,points,lastname,firstname,company,email,conuntry,state,twitter","x":580,"y":140,"wires":[["d95b3f31.aa6d5","26b0aa89.913c86"]]},{"id":"d95b3f31.aa6d5","type":"debug","z":"733c1fb0.2d612","name":"debug csv","active":true,"console":"false","complete":"payload","x":737,"y":145,"wires":[]},{"id":"26b0aa89.913c86","type":"file","z":"733c1fb0.2d612","name":"","filename":"/usr/local/output_mysql.csv","appendNewline":true,"createDir":true,"overwriteFile":"true","x":766,"y":93,"wires":[]},{"id":"f94f0d84.1e4ca","type":"MySQLdatabase","z":"","host":"プライベートIP","port":"3306","db":"mautic database","tz":""}]
```

##Amazon Echo?

Node-REDで追加出来るノードには、Alexaに関わるものもあります。Mauticで発生したイベントをAmazon Echoに反応させることができるかもしれません。私の手元にAmazon Echoがありませんが、面白そうな題材です。

![node-red-node-alexa.PNG](https://qiita-image-store.s3.amazonaws.com/0/41414/e403d879-b8af-44dc-12a9-8cc214fcb0e1.png)

#まとめ

Mauticとのデータ連携、WebhookであればSaaS版でも実装できますし、セルフホスティング版であればDB連携も実現できます。Node-REDを使うことで、Mauticからデータを出力して外部システム連携することに関しては、コードを書くよりもロジックに集中することができます。