ほんじゃら堂

めんどくさい仕事をラクにする作業自動化レシピ集

Node.jsとGruntでフォルダ監視ツールを作る

f:id:piro_suke:20160414001322j:plain

コミュニケーションというのはなかなか難しいもので、

「急いで確認したいから資料ができたら共有フォルダに入れて、すぐ連絡してよ」

と強めに伝えても、

資料はとっくにできてるのに

やれ後で連絡するつもりだっただの、

もうちょっと確認してから連絡するつもりだっただの、

今メール書いてただので、

一本内線をくれるだけで良いのになかなか連絡がもらえないことがある。

そんなストレスフルな行き違いは

「このやろう!」と毎回怒りを爆発させるよりも

ツールを使って解決の仕組みを用意してしまうに限る。

ということで今回は指定したフォルダを監視して、

ファイルが追加されたり更新されたりしたら

自動で通知してくれるスクリプトをつくってみたい。

以前別の記事で紹介したNode.jsのタスクランナー、Gruntを使えば

割と簡単にファイル監視ツールを作ることができる。

blog.honjala.net

「grunt-contrib-watch」パッケージを使ったフォルダ監視と、

「メール通知」「チャットワーク通知」をそれぞれ組み合わせて

監視&通知ツールを作ってみよう。

フォルダを監視して変更があったらメールで通知する

指定したフォルダにファイルが追加されたり、変更、削除されたら

メール通知してくれるスクリプトを作成する。

GMailアカウントと固有パスワードを用意してもらえれば、

下記のGruntfile.jsをちょっと書き換えてすぐに使っていただけるはず。

「file_change_mail_notifier」というフォルダを作って、

下記のファイルを保存する。

package.json

{
  "name": "file_change_mail_notifier",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-watch": "^1.0.0",
    "grunt-run": "^0.5.2",
    "nodemailer": "^2.3.2"
  }
}

mailer.js

var nodemailer = require('nodemailer');

if (process.argv.length < 3) {
    console.log("argument error.");
    return;
}

var transport = process.argv[2];
var from = process.argv[3];
var to = process.argv[4];
var subject = process.argv[5];
var message = process.argv[6];

var transporter = nodemailer.createTransport(transport);

var mailOptions = {
    from: from,
    to: to,
    subject: subject,
    text: message
};

transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
        return console.log(error);
    }
    console.log("Message sent: " + info.response);
});

Gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        watch: {
            docs: {
                files: ["**/*"],
                tasks: ["run:notify_change"],
                options: {
                    spawn: false,
            cwd: {
                files: "<監視したいフォルダを絶対パスで指定>"
            }
                }
            }
        },
        run: {
            notify_change: {
                args: [
                    'mailer.js'
                ]
            }
        }
    });
    grunt.loadNpmTasks("grunt-run");
    grunt.loadNpmTasks("grunt-contrib-watch");

    grunt.registerTask("default", "watch");

    grunt.event.on("watch", function (action, filepath) {
        grunt.config("run.notify_change.args", [
            "mailer.js",
            'smtps://<GMailアカウント名>%40gmail.com:<GMail固有パスワード>@smtp.gmail.com',
            '"<送信元ユーザー名>" <<送信元メールアドレス>>',
            '<送信先メールアドレス>',
            'file_change_mail_notifierからのメール', //メール件名
            "[" + filepath + "]が更新されました"
        ]);
    });
};

「<>」で囲まれた部分を状況に合わせて変更していただきたい。

監視先フォルダの指定方法は、Windowsなら下記のように指定する。

ローカルフォルダなら:

C:/Users/testuser/Desktop/sample

共有フォルダなら:

//192.168.x.xxx/テスト共有フォルダ/sample

上記の3ファイルを作成後、

コマンドプロンプトで

npm install

を実行すると必要なパッケージがインストールされる。

監視を開始する時は

grunt

を実行すれば監視が開始される。

試しに監視対象のフォルダにファイルを追加してみると、

指定したメールアドレスに即座にメールで通知されるはずだ。

「Ctrl+c」でgruntを停止するまで監視してくれる。

フォルダを監視して変更があったらチャットワークの特定ルームに通知する

メール通知版とほとんど一緒なのだけど、

メールうざい、という場合はこちらを利用すると良い。

チャットワークのAPIを利用しているので、使用するには

チャットワーク上からAPIを申請する必要がある。

今度は「file_change_chatwork_notifier」というフォルダを作成し、

下記のファイルを配置しよう。

package.json

{
  "name": "file_change_chatwork_notifier",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-watch": "^1.0.0",
    "grunt-http": "^2.0.1"
  }
}

Gruntfile.js

module.exports = function(grunt) {
    grunt.initConfig({
        watch: {
            docs: {
                files: ["**/*"],
                tasks: ["http:notify_change"],
                options: {
                    spawn: false,
            cwd: {
                files: "<監視したいフォルダを絶対パスで指定>"
            }
                }
            }
        },
        http: {
            notify_change: {
                options: {
                    url: "https://api.chatwork.com/v1/rooms/<チャットワークのルームID>/messages",
                    method: "POST",
                    headers: {
                         "X-ChatWorkToken": "<チャットワークのAPIキー>"
                    },
                    form: {
                        body: "ファイルが更新されました"
                    }
                }
            }
        }
    });
    grunt.loadNpmTasks("grunt-http");
    grunt.loadNpmTasks("grunt-contrib-watch");

    grunt.registerTask("default", "watch");

    grunt.event.on("watch", function (action, filepath) {
        grunt.config("http.notify_change.options.form.body", "[" + filepath + "]が更新されました");
    });
};

こちらもメール通知の場合と同様、

npm install

で必要なパッケージをインストールし、

grunt

で起動する。

監視対象のフォルダのファイルを変更したら、

どのファイルが変更されたかが即座に指定したチャットワークルームに

通知されるはずだ。

おわり

今回のサンプルはそのままコピペして「<>」の中さえ変更すれば使えるようにしたが、

ここで利用しているGruntパッケージ

フォルダ監視のための「grunt-contrib-watch」、

www.npmjs.com

nodeプログラムを実行するための「grunt-run」、

www.npmjs.com

HTTPアクセスするための「grunt-http」

www.npmjs.com

はどれも作業自動化する上で覚えておいて損はないパッケージなので、

自分でスクリプトを作成される場合はぜひ色々作ってみていただきたい。