チャットワークで1日ごとカウントダウンを喋らせる

たまに、個人のイベントごとのチャットツールでイベントまでのカウントダウンをやりたくなるのでメモです。

# Heroku設定

いつもので立てます。

<a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs#deploy-the-app" title="Getting Started with Node.js on Heroku | Heroku Dev Center" target="_blank">Getting Started with Node.js on Heroku | Heroku Dev Center</a>

# チャットワークアクセストークン設定を外部化

```
heroku config:add CHATWORK_ACCESS_TOKEN=CHATWORK_ACCESS_TOKEN
```

値を設定後にWEBのUIのほうから直します。

![image_20150622_182403_4.png](https://qiita-image-store.s3.amazonaws.com/1560/56170/e680e249-4b44-bcde-157d-edd5064d1f0d.png)

# 他の設定も外部化

```
heroku config:add TARGET_DATE=TARGET_DATE
heroku config:add ROOM_ID=ROOM_ID
heroku config:add EVENT_TITLE=EVENT_TITLE
```

ROOM_IDは発言させたいルームID。URL確認するとわかります。

```ルームID 123456 へ 2015/10/10 に 体育の日``` のカウントダウンをしたい場合。

```
heroku config:add TARGET_DATE=2015/10/10
heroku config:add ROOM_ID=123456
heroku config:add EVENT_TITLE=体育の日
```

# スケジューラーaddonsを設定

```
heroku addons:create scheduler:standard
```

1日ごとに喋らせる

![image_20150622_181559_2.png](https://qiita-image-store.s3.amazonaws.com/1560/56170/6c2dfa53-cedb-cb35-9937-6fc1d7faaf13.png)

UTCになっているので日本時間で動かしたい場合は-9:00した時間で行う。

```
日本時間AM10:00に行いたいときは 1:00 UTC。
```

# 実際のソースコード

```js
var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));

// JSONファイルの読み込み（ローカル用）
var fs = require('fs');
var setting = {};
if( process.env.PORT ) {
    //
} else {
    // .envフォルダはあらかじめ .gitignore 対象にしておく。
    setting = JSON.parse(fs.readFileSync('.env/setting.json', 'utf8'));
}

// 設定読み込み
var ROOM_ID = (process.env.ROOM_ID || setting.ROOM_ID);  // 対象ルーム
var CHATWORK_ACCESS_TOKEN = (process.env.CHATWORK_ACCESS_TOKEN || setting.CHATWORK_ACCESS_TOKEN);  // アクセストークン
var TARGET_DATE = (process.env.TARGET_DATE || setting.TARGET_DATE);  // カウントダウン日付
var EVENT_TITLE = (process.env.EVENT_TITLE || setting.EVENT_TITLE);  // イベントタイトル
console.log("CHATWORK_ACCESS_TOKEN : " + CHATWORK_ACCESS_TOKEN);
console.log("ROOM_ID : " + ROOM_ID);
console.log("TARGET_DATE : " + TARGET_DATE);
console.log("EVENT_TITLE : " + EVENT_TITLE);

// 時間
var unity_base_time = new Date(TARGET_DATE);
console.log(unity_base_time);

// サーバー上の時差を確認
var GMT9 = 9 * 60 * 60 * 1000; //  GMT+0900
var timezoneOffset = new Date().getTimezoneOffset();
console.log("timezoneOffset : " + timezoneOffset + "min");
// それに基づいて時差を修正するミリ秒を生成(timezoneOffset_msec)
var timezoneOffset_msec = timezoneOffset * 60 * 1000 + GMT9;
console.log("timezoneOffset_msec : " + timezoneOffset_msec + "msec");

// 時間比較
function getUnitySpanDate(){
    // 現在の時間
    var d = new Date();
    // 0:00同士で比較しないとちゃんとした値が出ないので補正
    var current_date = new Date(d.getFullYear() + "/" + (d.getMonth()+1) + "/" + d.getDate() );
    // 時間補正
    unity_base_time.setTime( unity_base_time.getTime() + timezoneOffset_msec );
    current_date.setTime( current_date.getTime() + timezoneOffset_msec );
    // 期間(timezoneOffset_msecを使う)
    var span_timestamp = unity_base_time.getTime() - current_date.getTime();
    // 1日(per_day)で割る
    var per_day = 84600 * 1000;
    var ret = Math.floor(span_timestamp / per_day);  // 切り捨て

    return ret;
}

// メッセージ送信
function postMessage(bodyStr){
    var request = require('request');
    var options = {
        headers: {
            'X-ChatWorkToken': CHATWORK_ACCESS_TOKEN
        },
        json: true
    };

    options.url = 'https://api.chatwork.com/v1/rooms/' + ROOM_ID + '/messages';
    options.form = { body: bodyStr };
    request.post(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body);
        }else{
            console.log('error: '+ response.statusCode);
        }
    });
}

app.get('/', function(request, response) {
    response.send('Hello World!');
});

app.get('/check', function(request, response) {

    response.send('check!');
    console.log('check!');
    console.log(new Date().toString());

    var span_date = getUnitySpanDate();

    if( span_date == 0 ) {
        // 当日処理
        var bodyStr = '';
        bodyStr += '[info][title]bot：お知らせ[/title]みなさんおはようございます！' + "\n";
        bodyStr += EVENT_TITLE + ' は(*)本(*)日(*)開(*)催(*)です。[/info]';

        postMessage(bodyStr);
    } else if( span_date > 0 ){
        // 当日までのカウントダウン処理
        var bodyStr = '';
        bodyStr += '[info][title]bot：お知らせ[/title]みなさんおはようございます！' + "\n";
        bodyStr += EVENT_TITLE + ' は ' + TARGET_DATE + ' 開催です。';
        bodyStr += '[info](F)あと ' + span_date + ' 日！(F)[/info][/info]' + "\n";

        postMessage(bodyStr);
    } else {
        // 既に過ぎている場合は何もしない
    }

});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});
```



# 参考記事

* <a href="http://qiita.com/n0bisuke/items/25813fba8120451d40da" title="速報! ChatworkAPIでメッセージ取得が出来るようになったので、メッセージに反応するBOT使ってみました。 - Qiita" target="_blank">速報! ChatworkAPIでメッセージ取得が出来るようになったので、メッセージに反応するBOT使ってみました。 - Qiita</a>
* <a href="http://qiita.com/n0bisuke/items/6a3164b27e3775c81e3c" title="ChatworkAPIでmessageをPOSTしてみる。 - Qiita" target="_blank">ChatworkAPIでmessageをPOSTしてみる。 - Qiita</a>
* <a href="http://qiita.com/n0bisuke/items/c7b82b5b64a3155baed3" title="ChatworkAPIにexpressからrequestモジュールで接続 - Qiita" target="_blank">ChatworkAPIにexpressからrequestモジュールで接続 - Qiita</a>