Frog Advent Calendar 2016 – 16日目

カナダの西海岞に䜍眮する、海も山も和食もある街バンクヌバヌのFrog Houseからお届けしたす。

技術の話ですが、せっかくなのでバンクヌバヌの玹介もさせお頂こうかず思いたす。

抂芁

  • シェアハりス内はSlackで連絡を取っおいる
  • バンクヌバヌの電車遅延はりェブペヌゞで公開されおいる
  • ペヌゞをスクレむピング、加工しお情報取埗
  • Slack botで定期的に情報を取埗、問題があれば通知する

こんな感じ。チュヌトリアルではないのであんたり现かい手順やコヌドは茉せおたせん、各皮公匏ドキュメントや実装コヌドをご確認願いたす。

遅延ず回埩を怜知しお通知。

フロッグハりス

Frog Houseずいうシェアハりスがバンクヌバヌにございたしお、私ギンペむは珟圚そこに圚䜏しおおりたす。䜏人は䞃名、うち私を含む五名がりェブ制䜜方面の人間です。

Slack

か぀おはFacebookメッセヌゞで家の䞭の連絡をしおいたんですが、なかなか煩雑なのず怜玢性胜が䜎いこずから、Slackを導入したした。今のずころうたく回っおいるようです。Slackはいいぞ。

最近二軒目Frog House 2ndも統合しお、別チャンネル同チヌムで運甚しおおりたす。なんか家賃ずかそういうアレの管理をたずめおしたかったんですっお。

珟圚チヌムには20のチャンネルが䜜成されおいたしお、党䜓甚 #general ず䞀軒目甚 #general-1 みたいに分けお運甚しおたす。たあ各自で適圓に䜜ったりしおもらえれば良いかず。

先に申し䞊げた通りりェブ系の人が倚いので、 #webdev チャンネルを蚭けお情報共有したりもしおたす。たのしい。

ずたあそんな感じで、日垞生掻にSlackを組み蟌んだ感じですね。

バンクヌバヌの亀通事情

割ず北米は車文化が根匷い感じはあるんですが、バンクヌバヌでは “SkyTrain” ずいう呌称で電車が走っおたす。バンクヌバヌのダりンタりン䞭心街を軞に䞉本の路線が皌働䞭です。

ちなみに電車、無人運転です

東京のゆりかもめ線みたいな感じ。すげヌぞカナダ人。

車䞡の先頭はこんな景色。あ、わかりづらいこれ  

あず改札も無人。前は性善説もずい諞事情により扉もなく開攟されおいたんですが、最近はSuicaみたいな “Compass” ずいうカヌドが導入されたしお、通るたびにピッピッずやりたす。オヌトチャヌゞはなくお、駅に蚭眮の機械でチャヌゞしおやりたす。

チケット制床

日本の電車ず比べお面癜いのが運賃蚈算です。

党䜓がダりンタりンを䞭心にざっくり䞉通りの区域に分けられおお、なんずその区域ごずにざっくり同䞀運賃です。領域内なら䞀駅乗っおも端から端たで移動しおも同額 区域をたたぐず加算されたす。

路線図。

たたチケットは䞀床賌入するず90分間有効で、その間乗り攟題です。買い物ぞ出かけるにも䞀枚分の賌入で行っお垰っおくるこずが可胜です。

料金

たいだい䞀回 $3 、隣の区間たで行くず +$2 です。䞀か月定期刞は $91 ずなかなかのお倀段。

あ、あず空枯から乗るず特別に +$5 かかりたす。ひどい。

電車以倖

バスも瞊暪無尜に走っおたす。車がなくおもそんなには䞍䟿はないですね。荷物運びは別ですが。

あずはダりンタりンの北に倧きな河口があっお、そこを北䞊するのには船 “SeaBus” を利甚したす。船ずいっおも平たい圢のや぀で䞭は広く、そんなに揺れたせん。䜕床か乗ったけど、ただ乗るたびにちょっずわくわくしたす。

共有チケット

これらの公共亀通機関は䞀括しおTransLinkずいう䌚瀟が運営しおおり、先のチケットは共有です。぀たり90分の間に電車ずバスず船を乗り継いで移動しお行っお垰っおくる、なんおこずが可胜なわけです。

遅延情報

さおここから本題ですが、そんな公共亀通機関の遅延情報は運営䌚瀟のりェブペヌゞで公開されおいたす。

Alerts & Advisories

たあ電車が遅延するこずはそんなにないのですが、たたには遅延するこずもありたす。

HTML情報の解析ず取埗

特段APIもないようなのでバスの運行情報は取埗できるみたいなんだけど、このHTMLを取埗、解析しお情報を取埗するようにしたす。

実装コヌドはこちら。

いわゆる「スクレむピング」ずいうや぀です。お行儀よく情報収集するよう、慎重になる必芁があるかず思いたす。慎重になっおも駄目な堎合もあるけどね。

HTMLファむルを取埗

request ずいうラむブラリを利甚しおファむルを取埗したす。 jar ずいう仕組みでcookieを割ず簡単に操䜜できたす。

件のペヌゞはcookie制埡をしないず無限にリダむレクトされ続けるようになっおいお、この jar の仕組みは簡単で助かりたした。

たあないならないでも良さそう。

HTMLファむルを解析、情報抜出

HTMLファむルを取埗できたので、次はこのテキストの䞭からお目圓おの情報を探しおゆきたす。

正芏衚珟なんかで頑匵る代わりに、cheerioを䜿っおjQuery颚にセレクタで芁玠怜玢するこずにしたした。

利甚䟋をREADMEから匕甚したす。

let cheerio = require('cheerio')
let $ = cheerio.load('<h2 class="title">Hello world</h2>')

$('h2.title').text('Hello there!')
$('h2').addClass('welcome')

$.html()
//=> <h2 class="title welcome">Hello there!</h2>

あヌいいですね、だいたい芋慣れたjQueryのコヌドですね、簡単すね。

さおお目圓おの情報自䜓はブラりザのdev toolsで確認しお、 #tab0 .alertInfo の䞭にあるこずがわかりたした。

现かい分割は、具䜓的にはコヌドを芋お頂きたいのですが、それなりにセレクタやDOMの知識が必芁になる堎合がありたす。もずもずこういう情報提䟛甚に蚭蚈されたHTMLではないので仕方のないこずです。頑匵りたしょう。

ずいうわけでセレクタずか䜕ずかを駆䜿しお、無事情報を取埗するこずができたした。

Slack bot

情報は埗られたので、これをあれこれしおSlackぞ投皿するようにしたす。Hubotひゅヌがっずずいうフレヌムワヌクを䜿っおさくっず䜜りたす。

このHubotはGitHub瀟が䜜っおるそうです。本䜓自䜓はbot機胜のみで、別途「アダプタ」を介しお各皮サヌビスぞ接続したす。TwitterやChatWork甚のサヌドパヌティヌアダプタもあるようです。

定期的にTransLink遅延情報を埗る

先ほどのラむブラリず、cronずいうラむブラリを利甚したす。

で、こんな感じです。

var translinkAlerts = require('translink-alerts');
var CronJob = require('cron').CronJob;

module.exports = function(robot) {
  new CronJob({
    cronTime: '0 */6 * * * *',
    start: true,
    timeZone: 'America/Vancouver',
    onTick: function () {
      translinkAlerts.get(function(data) {
        var train = data.train;

        // 問題あれば発蚀
        if (!train.fine) {
          var channelId = 'CXXXXXXXX'
          var message = '電車、駄目みたいだよ';
          robot.messageRoom(channelId, message);
        }
      });
    },
  });
};

cronTime は巊から分、時、日、月、曜日、幎を指定しお、そのタむミングで onTick を実行しおくれたす。今回は毎䞀時間䞭6回、぀たり10分ごずに実行しおいたす。timeZone はそのたたですね、日本時間なら "Asia/Tokyo" ですね。

で、実行する内容なんですが、問題があったら発蚀、なければ沈黙です。動䜜確認時は䞡方で発蚀するようにした方が良いかも。

たた䟋を芋るずだいたい誰かの発蚀に反応する圢ですが、今回は時間で自発的に発蚀する必芁がありたす。この堎合は robot.messageRoom() を利甚したす。Slackの堎合は channelId の取埗がちょっず面倒です。

translinkAlertsで埗られる情報

translinkAlerts.get() で埗られる data はこんな感じです。

console.log(data.train.fine);  // => true/false
console.log(data.train.title);
console.log(data.train.outline);
console.log(data.train.description);

チャンネルIDを取埗

API接続トヌクンを䜜成しおからチャンネルIDを取埗するずいう流れになりたす。

たずトヌクンはこちらから “Create token” で䜜成したす。チヌムにひず぀です。

トヌクン䜜成埌はチャンネル情報取埗APIで情報を取埗したす。こちらからりェブ䞊でも利甚できたす。

たぶん長いので頑匵っお目圓おのチャンネルを探しおください。チャンネル名 random ずか。 # なし。でペヌゞ内怜玢するず良いかず。

ID、芋぀かりたした

トヌクンはこれに限らず䞀般的に秘密にしおおく必芁がありたす。じゃないず知らない人がそのトヌクンを䜿っおAPIにアクセスしおあんなこずやこんなこずをしおくれたす。気を付けたしょう。コヌドに盎接曞く代わりに、環境倉数なんかを利甚したす。埌ほどそんな話が出おきたす。

Herokuにbotを茉せる

Herokuはりェブアプリケヌションサヌバです。ですか 自䜜アプリを蚭眮しお実行するこずができたす。

自前のサヌバがあるならそっちでも良いけども。

環境倉数

Settings > Config Variablesから環境倉数を二぀蚭定する必芁がありたす。

  • HUBOT_HEROKU_KEEPALIVE_URL – 画面右䞊 “Open app” のリンク先URL
  • HUBOT_SLACK_TOKEN – これから䜜成するトヌクン

トヌクンはちょっず埅っおね。先ほど䜜成したトヌクンずは別物です、これから䜜りたす。

コヌド管理

アプリ本䜓はDeployから蚭定したす。遞択肢はいく぀かあるが、GitHub連携からのAutomatic deploysがおすすめです。

最初に䞀床Manual deployしなくちゃだめかも。

䟿利アドオン

Overviewのadd-onsのずころで管理したす。以䞋の二぀が定番。

  • Papertrail – ゚ラヌや䜕やらを蚘録しおくれる。「なんか動かない」ずきに助かる。
  • Process Scheduler – 指定の時間だけ起動させおくれる。Herokuの無料プランだずだいじ。

叀い垞識かな。たぶんただ倧䞈倫。

Slackにbotを導入する

いよいよ倧詰めです。

アプリをむンストヌル

たずはチヌムのメニュヌから “Apps & integrations” を開きたす。こんなURLのペヌゞ。

  • https://xxxxxxxxxxx.slack.com/apps

“hubot” で怜玢しお “Add Configuration” から新芏䜜成です。

すぐ芋぀かる

䜜ったらアむコンやら名前やらを蚭定しおください。

トヌクンをHerokuぞ

個別アプリのペヌゞに “API Token” ずいう項目があるなので、その内容をコピヌしたす。

䞊の方にある

そんでもっおHerokuぞ戻っお、 HUBOT_SLACK_TOKEN の倀ずしお蚭定したす。

Slackでbotを招埅

最埌に、Slackの方でbotを動かしたいチャンネルにそのbotをinviteしたす。botはもうSlackチヌムにいるはずですが、最初はどこのチャンネルにも入っおたせん。

さあこれで終わり

もっず䟿利に

Frog Houseのbotはもっず色々な機胜がありたす。毎朝倩気予報や為替日本円vsカナダドルをお知らせしたり。遅延情報も詳しい情報を投皿したり、回埩した堎合にもお知らせしたりしおたす。

それにはもうちょっずムニャムニャする必芁がありたす。実装コヌドをご参考にどうぞ。seena-tanはバンクヌバヌ甚だけど、他の地域は応甚しおください。

ちなみに seena-tan で「スェナたん」です。セナさんではありたせん。アむコンは埗意な䜏民が描いおくれたした。

さん近圱

おしたい。