LINE Messaging API + Rails でサイファーBot

# はじめに

この記事は[チャットボット Advent Calendar 2016](http://qiita.com/advent-calendar/2016/chatbot) の14日目です。

今回は、サイファーBot を作りました。
サイファーとは、フリースタイルのラップバトルのことです。
参考: https://iflyer.tv/ja/article/2016/03/31/cypher-rap/#lang

きっかけは、最近となりの席のT さんが
「Rails できるようになりたい」
「チャットボットで儲けたい」
「サイファーがまじでヤバイ」

などと言っていたため、
「Rails でサイファーボット作らないとまじでヤバイ」
と思うようになり、今回に至りました。

こちらが、サイファーBot、サイのファーさんです。

<img width="303" alt="Screen Shot 2016-12-14 at 03.58.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/27788/4d7a9759-9e2e-06e5-2d32-9fb09ace8d64.png">

目にヤマモトてw

こんなかんじで、適当にRhyme を投げかけると、Rhyme で返してくれます。
人間ほど高度なRhyme はできませんが、そこはサイなので大目に見てください。
ぜひお友達になって、渾身のRhyme を投げかけてみてください

<img width="159" alt="Screen Shot 2016-12-14 at 06.06.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/27788/3799986a-0399-909d-cee4-b3e9038323bc.png">


# サイファーBot のつくりかた

ソースは下記に置いておきました。
https://github.com/masaki925/cypher-bot

## 材料

主なベースとしては、下記を使いました。

- Rails
- Heroku
- LINE Messaging API

また、サイファーを実現するために下記を利用しました。

- Rhymer: https://github.com/suzuki86/rhymer
- WEB 便利ツール: http://kujirahand.com/web-tools/Words.php
- フレンズのスクリプト(文章): http://www.thebelltree.com/archives/2005/12/1_2.html

## 手順

### Rails + Heroku

Heroku の設定はこのあたりに書いてあります。

https://devcenter.heroku.com/articles/git

Rails で使ったコマンドは下記くらいです

```
$ rails new cypher-bot --database=postgresql
$ bundle exec rake db:create
$ rails g controller api/raps battle --no-helper --no-assets --no-view-specs
```

また、LINE が提供している、Ruby 用SDK を利用しています。
https://github.com/line/line-bot-sdk-ruby

### LINE Messaging API

こちらがわかりやすかったです。LINE の管理画面はすぐ迷子になります。。

https://bita.jp/dml/line-messaging-api-exp

### Rhymer

どうやってサイファーしようかなと探しているところに、面白そうな記事を見かけたので、利用してみました。
http://qiita.com/suzuki86/items/2a2801944a3e393464c7

詳細は記事を読んでいただくとよいと思いますが、
`「今日はとても良い天気ですね。こんな日は自然に元気になります。」 ` と入力すると、
`「今日は良い天気 こんな日は自然に元気」` という結果を返してくれます。

注意点として、このライブラリは`natto` に依存していて、`Mecab` のネイティブビルドが必要です。
Heroku でこれを使うためには、buildpack の必要です。
ネットで検索すると既に古くなった情報がヒットしますが、今日時点では下記でいけました。

```
$ heroku buildpacks:set https://github.com/diasks2/heroku-buildpack-mecab
$ heroku config:set LD_LIBRARY_PATH=/app/vendor/mecab/lib
$ heroku config:set MECAB_PATH=/app/vendor/mecab/lib/libmecab.so
```
※ 参考: http://qiita.com/r7kamura/items/3ef8f4fbe6b722674a96#_reference-49538377b07db081eea3


また、ローカル(Mac) で利用しようとした際、下記のエラーが出て悩まされました

```
/usr/local/opt/rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/natto-1.1.1/lib/natto/natto.rb:234:in `initialize': Could not initialize Model with options: '' (Natto::MeCabError)
        from /usr/local/opt/rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/bundler/gems/rhymer-0ab8bc81fc60/lib/rhymer/lyric.rb:13:in `new'
        from /usr/local/opt/rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/bundler/gems/rhymer-0ab8bc81fc60/lib/rhymer/lyric.rb:13:in `mecab'
        from /usr/local/opt/rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/bundler/gems/rhymer-0ab8bc81fc60/lib/rhymer/lyric.rb:7:in `initialize'
        from /usr/local/opt/rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/bundler/gems/rhymer-0ab8bc81fc60/lib/rhymer/parser.rb:10:in `new'
        from /usr/local/opt/rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/bundler/gems/rhymer-0ab8bc81fc60/lib/rhymer/parser.rb:10:in `initialize'
        from fuga.rb:4:in `new'
        from fuga.rb:4:in `<main>'
```

原因は、brew でmecab は入れていたものの、mecab-ipadic を入れていなかったことでした。
エラーメッセージからは非常にわかりにくいので、要注意ですね。

### WEB 便利ツール
http://kujirahand.com/web-tools/Words.php

Rhyme を作るための辞書です。
API が無いようだったので、HTML で返ってきた内容をパースして利用しています。

### フレンズのスクリプト
http://www.thebelltree.com/archives/2005/12/1_2.html

WEB 便利ツールで単語は取得できるようになりましたが、そこから文章(Lyric) を紡ぐ必要があります。
これを0 から練り上げるのは大変なので、何かよいベースが無いかと探していました。
そんなタイミングで、たまたま嫁がフレンズを観ていて、そういえば面白いフレーズがたくさん出てきてたなと思って、試しに使ってみた、という程度で採用しました。
結果、いいかんじにカオスになって、自分としては気に入っています。改善の余地はもちろんありますが。

文章は地道にサイトからコピペして、リクエストを受けるたびにランダムで利用しました。

### フロー

- 1. ユーザーからの入力を受け付ける
- 2. 入力テキストから名詞を抽出
- 3. 抽出した名詞を元に、WEB 便利ツールから韻 を踏むワード群を取得
- 4. フレンズのスクリプトからランダムで文章を抽出
- 5. 入力テキストとスクリプトを結合し、名詞を抽出しておく
- 6. 抽出した名詞と入れ替える単語を韻ワード群からランダムで抽出
- 7. 結合スクリプトに対して、抽出した名詞と抽出した韻ワードを入れ替え
- 8. Rhymer にかけて、Rhyme が生まれるかどうかを確認
- 9. 生まれたら終了。生まれなかったら、スクリプトを選び直して4〜8 を繰り返し。


# おわりに

以上となります。いかがでしたでしょうか。
チャットボットは導入のハードルはすごく下がりましたが、そこからどういうコンテンツが生成できるかはアイデアや工夫が必要だなと感じました。
今回はRhyme の生成にあんまり賢いロジックを入れられてないので、そのあたりをうまいこと処理して、ヴァイブスの高みを目指せるようにしていきたいですね。
それではまた。