読者です 読者をやめる 読者になる 読者になる

Hubotでビットコインbotを作る

Hubot Bitcoin Twitter Heroku

参考: http://qiita.com/hkusu/items/36ce56f3df4e7a0937cb

今回作ったもの

自然言語処理 bot (@hubot_uraway) | Twitter

必要なもの

  • Herokuのアカウントと基礎知識
  • TwitterのBot用アカウント
  • NPM

基本方針

  • Herokuにデプロイ(無料枠だと24時間のうち6時間スリープしてしまう)
  • リフォローする
  • 定期的にツイートする
  • リプライに返信する

こんな感じのbotを作ります。

Hubotジェネレーター

npmでインストールします。

$ npm install -g generator-hubot

Hubotの雛形を作成。

$ yo hubot
? Owner:
? Bot name:
? Description:
? Bot adapter: twitter-userstream

一旦Hubotを起動して、動作を確認しよう

$ ./bin/hubot
hubot> hubot ping
hubot> PONG

Twitterアプリケーションの登録

Bot用のアカウントを取得後、ログインしたまま https://apps.twitter.com/ にアクセスして、アプリケーションを登録し、次の情報を控えておきます。

  • Consumer Key (API Key)
  • Consumer Secret (API Secret)
  • Access Token
  • Access Token Secret

ローカルで動作させる

Hubot起動スクリプトを作成します。

local_run.sh

#!/bin/sh

export HUBOT_TWITTER_KEY="key"
export HUBOT_TWITTER_SECRET="key_secret"
export HUBOT_TWITTER_TOKEN="token"
export HUBOT_TWITTER_TOKEN_SECRET="token_secret"
export HUBOT_NAME = "hubotのスクリーンネーム"

bin/hubot -a twitter-userstream

起動スクリプトに実行権限を付与して、実行します。

$ chmod +x local_run.sh
$ ./local_run.sh

実行中はTwitter Hubotが常に起動しています。botスクリプトに変更を加えた時の確認に便利です。

Herokuにデプロイ

先ほどのlocal_run.shと同じ立ち上げ方をHeroku上で出来るようにしましょう。

Procfile

web: bin/hubot -a twitter-userstream

gitでコミットします。トークン等を記載しているので、local_run.shをコミットしないように注意しましょう。

$ git init
$ git add .
$ git commit -m "firs comment"

Herokuへプッシュします。

$ heroku create
$ git push heroku master

アプリケーションのページを確認します。エラーが出ているはずです。

$ heroku open

環境変数を追加してから、もう一度$ heroku openして、エラーが出ていなければ、Twitterで動作を確認しましょう。

$ heroku config:add HUBOT_TWITTER_KEY="key"
$ heroku config:add HUBOT_TWITTER_SECRET="secret"
$ heroku config:add HUBOT_TWITTER_TOKEN="token"
$ heroku config:add HUBOT_TWITTER_TOKEN_SECRET="token_secret"
$ heroku config:add HUBOT_NAME="hubotのスクリーンネーム"

このような表記であれば、Hubotは動作しています。

Botを作成する

scriptsディレクトリにスクリプトを記述したファイルを作成すれば、自動で読み取ってくれます。

次のことを実行するスクリプトを記述します。

  • リフォローする
  • 定期的にツイートする
  • リプライに返信する

リフォローする

Botをフォローしたユーザーをフォローし返すには、twitter-userstream が提供する followed イベントを使用します。

module.exports = (robot) ->
  robot.on 'followed', (event) ->
    robot.logger.info "followed #{event.user.name}!"
    robot.adapter.join event.user

定期的にツイートする

定期的にツイートするには node-cron を利用します。今回は node-zaif を使って取得したビットコインのlast_price(終値)をツイートするスクリプトを記述します。

cronJob = require('cron').CronJob
zaif = require('zaif.jp')
publicApi = zaif.PublicApi

module.exports = (robot) ->
  cronjob = new cronJob(
    # 実行する時間。今回は10分毎
    cronTime: "00 00,10,20,30,40,50 * * * *"
    # 自動発火するかどうか
    start:    true
    # タイムゾーン
    timeZone: "Asia/Tokyo"
    # cronが実行する関数
    onTick: ->
      publicApi.lastPrice('btc_jpy')
        .then (res) ->
          robot.send {room: 'Twitter'}, "1 BTC = #{res.last_price} JPY"
        .catch (e) ->
          robot.send {room: 'Twitter'}, "ERROR: #{e}"
  )

詳しくはそれぞれのドキュメントで。

リプライに返信する

便利なAPIが用意されているので、一度目を通す。正規表現でリプライの内容を取得できる。

module.exports = (robot) ->
  # 「おみくじ」リプライを受け取ると、結果をランダムにツイートする
  robot.respond /おみくじ/i, (msg) ->
    msg.send msg.random ["大吉", "中吉", "小吉", "凶"]
  # タイムラインに「疲れた」が流れると、「頑張って」とツイートする
  robot.hear /疲れた/i, (msg) ->
    msg.send "頑張って!"
  # 「x BTC」リプライを受けると、JPYを計算して結果を対象ユーザーに返信する
  robot.respond /(.*) BTC/i, (res) ->
    btc = res.match[1]
    publicApi.lastPrice('btc_jpy')
      .then (response) ->
        jpy = btc*response.last_price
        res.reply "#{btc} BTC = #{jpy} JPY"
      .catch (e) ->
        res.reply "ERROR: #{e}"
  「x JPY」リプライを受けると、BTCを計算して対象ユーザーに返信する
  robot.respond /(.*) JPY/i, (res) ->
    jpy = res.match[1]
    publicApi.lastPrice('btc_jpy')
      .then (response) ->
        btc = jpy/response.last_price
        res.reply "#{jpy} JPY = #{btc} BTC"
      .catch (e) ->
        res.reply "ERROR: #{e}"

最後に

このBot、Herokuの無料枠だと問題がある。

説明にある通り無料枠だと、

  • 30分間のアクセスがないとスリープ状態に
  • 24時間のうち、必ず6時間はスリープ

ひとつ目の、アクセスに関してはcronやこれを使えば問題なさそうだが、ふたつ目の問題は有料版を使う以外に解決策がない。うーん...

ソースコード

自然言語処理 bot (@hubot_uraway) | Twitter

ソースコード

MITライセンス。終値や計算結果、このbotを利用したことによる損害の責任を保証しない。