Ruboty | Brain ボットの脳にデータを記憶 #ruboty #chatops

# Ruboty | Brain ボットの脳にデータを記憶 #ruboty #chatops
## 概要
Ruboty の Brain でボットの脳にデータを記憶します。

Ruboty は Brain を利用することでデータの永続化が可能です。
標準では Ruboty::Brains::Memory クラスの data というインスタンス変数に Hash で値を保持しています。

Ruboty::Brains::Memory はメモリに Hash を保持するだけなので、
Ruboty を再起動するとデータは消失します。

再起動も加味した永続化をしたい場合など、 Brains::Base を継承して新たなクラスを作成することで、
独自の永続化機能を追加することも可能です。
例えば、 Redis を利用した [ruboty-redis](https://github.com/r7kamura/ruboty-redis) があります。

## 試用
### 仕様
* increase, decrease で増減するカウンタ Handler + Action を作成
* gem: ruboty-counter
* Handlers: Ruboty::Handlers::CounterHandler
* Actions: Ruboty::Counter::Actions::IncreaseAction
* Actions: Ruboty::Counter::Actions::DecreaseAction

ひな形の作成には、 [ruboby-gen](https://github.com/blockgiven/ruboty-gen) を利用します。

### 手順

* ruboty-gen で自動生成を行います

~~~bash
$ ruboty-gen g counter increase decrease
      create  ruboty-counter/Gemfile
      create  ruboty-counter/Rakefile
      create  ruboty-counter/LICENSE.txt
      create  ruboty-counter/README.md
      create  ruboty-counter/.gitignore
      create  ruboty-counter/ruboty-counter.gemspec
      create  ruboty-counter/lib/ruboty/counter.rb
      create  ruboty-counter/lib/ruboty/counter/version.rb
Initializing git repo in /cygdrive/d/project/study/qiita/ruboty-counter
      create  ruboty-counter/lib/ruboty/handlers/counter.rb
      create  ruboty-counter/lib/ruboty/counter/actions/increase.rb
      create  ruboty-counter/lib/ruboty/counter/actions/decrease.rb
~~~

* IncreaseAction を実装

~~~ruby:ruboty-counter/lib/ruboty/counter/actions/increase.rb
module Ruboty
  module Counter
    module Actions
      class Increase < Ruboty::Actions::Base
        def call
          brain = message.robot.brain
          brain.data['counter'] ||= 0
          brain.data['counter'] = brain.data['counter'] + 1
          message.reply(brain.data['counter'])
        end
      end
    end
  end
end
~~~

* DecreaseAction を実装

~~~ruby:ruboty-counter/lib/ruboty/counter/actions/decrease.rb
module Ruboty
  module Counter
    module Actions
      class Decrease < Ruboty::Actions::Base
        def call
          brain = message.robot.brain
          brain.data['counter'] ||= 0
          brain.data['counter'] = brain.data['counter'] - 1
          message.reply(brain.data['counter'])
        end
      end
    end
  end
end
~~~

* Handler は description だけ変更

~~~
require "ruboty/counter/actions/increase"
require "ruboty/counter/actions/decrease"

module Ruboty
  module Handlers
    class Counter < Base
      on /counter (increase|\+)/, name: 'increase', description: 'increase counter'
      on /counter (decrease|\-)/, name: 'decrease', description: 'decrease counter'

      def increase(message)
        Ruboty::Counter::Actions::Increase.new(message).call
      end

      def decrease(message)
        Ruboty::Counter::Actions::Decrease.new(message).call
      end
    end
  end
end
~~~

* private gem server に公開

~~~
$ rake build
# geminabox で作成した private gem server にアップ
$ gem inabox ./pkg/ruboty-qiita_scouter-0.0.1.gem
~~~

* bot 確認用ディレクトリの作成

~~~
$ cd "ボットを作成する任意のディレクトリ"
$ ruboty -g
$ cd ruboty
~~~

* Gemfile の編集

~~~
source "http://your private gem server or rubygems/"

gem 'ruboty-counter'
~~~

* ruboty の起動、試行

~~~
$ ruboty
> ruboty help
ruboty /counter (decrease|\-)/ - decrease counter
ruboty /counter (increase|\+)/ - increase counter
ruboty /help( me)?\z/i         - Show this help message
ruboty /ping\z/i               - Return PONG to PING
ruboty /who am i\?/i           - Answer who you are
> ruboty counter increase
1
> ruboty counter increase
2
> ruboty counter decrease
1
> ruboty counter decrease
0
> ruboty counter decrease
-1
> ruboty counter +
0
> ruboty counter +
1
> ruboty counter -
0
> ruboty counter -
-1
~~~


## 参照
[Ruboty GitHub](https://github.com/r7kamura/ruboty)
[Ruboty RubyGems](https://github.com/r7kamura/ruboty)
[ruboty-gen GitHub](https://github.com/blockgiven/ruboty-gen)
[ruboty-gen RubyGems](http://rubygems.org/gems/ruboty-gen)
[Ruboty | 自作 Handler gem の作成](http://qiita.com/tbpgr/items/a7ac8aaec55ee1bf79f0)