メディア配信ボット、BOT TREE for MEDIA(β)を使ってみました


先日[ZEALS](http://zeals.co.jp/)が[BOT TREE for MEDIA](http://zeals.co.jp/bottree/)を公開しました。メディア配信用のボット作成に特化したサービスで、エンジニアでなくとも運用できるサービスを目指しているようです。

[参考1:メディア向けボット開発運用ツール「BOT TREE for MEDIA」が正式ローンチ](http://jp.techcrunch.com/2016/06/10/bot-tree-for-media-launch/)
[参考2:登録100社超のチャットボット版ワードプレス「BOT TREE for MEDIA(あなたのメディアを5分でBOTに)」の提供を開始](http://prtimes.jp/main/html/rd/p/000000007.000019209.html)

国産のボット作成サービスということで、前々から気になっていたので試しに使ってみました。

# 機能確認

## 準備

まずは会員登録が必要です。[ここ](http://zeals.co.jp/bottree/)から新規登録します。ログインできたら右のプロフィール設定を選択し、プロフィール画面を開きます。画面下部にある"APIキー"をメモしておきましょう。

また、今回はBot実装にあたって、Ruby、sinatra、heroku、LINE BOT API等を利用しています。
[参考1](http://www.sakana.tech/entry/2016/04/12/112700) [参考2](http://qiita.com/EastResident/items/d1b572f00c29f907b743)

## 動作検証

Botを作る前にとりあえず通信してみます。以下のようなパラメータを<https://bottree.tokyo>に向けてJSONでPOSTすればいいようです。

```js
{"api": "your_api_key", "content": {"userid": "1", "text": "こんにちは"}}
```

"api"はプロフィールページに記載してあるAPIキーです。"userid"はサービス側でユーザーを認識するためのIDです。例えばLINEのBotを作成する場合は、基本LINEのMIDを入力すればOKですが、ユーザーを識別できるユニークな値なら何でも良いです。

それでは試しにPOSTして、結果を受け取ってみましょう。

```rb
require 'json'
require 'rest-client'

request_content = {"api": "your_api_key", "content": {"userid": "1", "text": "こんにちは"}}
content_json = request_content.to_json

rest = RestClient.post('https://bottree.tokyo', content_json)
result = JSON.parse(rest)
p result
```

上記のコードを実行すると、以下のような結果が出力されました(実際はインデントされていません)。

```json
{"userid"=>"1",
    "contents"=>[
        {"content"=>"はじめして！あなたにオススメの記事を紹介できるよう頑張ります！あなたに合った記事を紹介するのに、あなたのことを少しだけ教えてください。", "type"=>0}, 
        {"content"=>"ニックネームを教えていただけませんか？", "type"=>0},
        {"content"=>"", "type"=>0}
    ]
}
```

デフォルトのプロフィール取得用メッセージを含むJSONが返ってきました。

## プロフィール取得会話設定

BOT TREE for MEDIAに新規のuseridでリクエストが送られると、ユーザーの情報を取得するために、一連の質問が繰り返されます。この質問はBOT TREE for MEDIAのトーク管理から編集可能です。
![スクリーンショット 2016-06-11 00.40.37.png](https://qiita-image-store.s3.amazonaws.com/0/79302/84dbb919-d31c-de40-b96c-5420844cc9eb.png)

どうやらユーザーが最初にリクエストを送ると、順番が0の質問文と順番が1の質問文が連続して返信され、ユーザーが応答すると順番が2の質問が返信される・・・そして質問1~X(最大9)に対するユーザーの応答は、各ユーザーのプロフィール情報として保存されるようです。

ユーザー管理からは、取得したプロフィール情報と会話内容が閲覧できます。
![スクリーンショット 2016-06-11 00.48.43.png](https://qiita-image-store.s3.amazonaws.com/0/79302/822a7f64-12cf-bfaf-324a-cd7915640e62.png)

## 記事の管理

連番(1-9)の質問が終わったら、順番が"最後"の質問文が返信され、記事の紹介に移行します。紹介する記事は、記事管理から追加・編集できます。

試しにTechCrunchの記事をいくつか登録してみました。
![スクリーンショット 2016-06-11 01.05.13.png](https://qiita-image-store.s3.amazonaws.com/0/79302/3e6f249e-675b-422e-ba52-a8b08c3b94b5.png)

各記事には最大で5個のキーワードを設定できます。ユーザーが送信したテキスト内に、このキーワードが含まれる記事が選択されるという仕組みのようです。

例えば、"LINEの最新情報教えて"というテキストを送信すると、以下のようなJSONが返ってきます。

```json
{"userid"=>"xxxx", "contents"=>[
    {"content"=>"こんな記事はいかがですか？？", "type"=>0},
    {"content"=>"LINE、東証とNYSEの同時上場へ——時価総額は約5880億円\nhttp://jp.techcrunch.com/2016/06/10/line-ipo/", "type"=>0},
    {"content"=>"いかがでしたか？また何か気になれば話しかけてくださいね！", "type"=>0}
]}
```

## 雑談機能

いずれの記事のキーワードにも含まれないテキストをユーザーが送信すると、botが雑談してくれるみたいです。

例えば、"眠い"と送信すると、

```json
{"userid"=>"xxxx", "contents"=>[{"content"=>"僕も眠くて今にも寝そうです…", "type"=>0}, {"content"=>"", "type"=>0}, {"content"=>"", "type"=>0}]}
```

と返ってきました。

# 実装

では実際に実装していきます。今回は、Ruby、Sinatra、heroku、LINE BOT APIを使用しています。このあたりの詳しい使用方法に関しては先人の方々がまとめてくださっているので、詳しくは割愛します。

[参考1:LINE botでオウム返しをブラウザ上で作る全手順](http://www.sakana.tech/entry/2016/04/12/112700)
[参考2:LINE BOT APIでgoogle検索ボットを作った](http://qiita.com/EastResident/items/d1b572f00c29f907b743)

## ファイル構成
ファイル構成は以下のような感じです。

- working_folder
  - Gemfile
  - config.ru
  - main.rb

## Gemfileの編集

Gemfileを以下のように編集し、'bundle install'を実行します。

```
source "https://rubygems.org"

gem 'sinatra'
gem 'json'
gem 'rest-client'
gem 'sinatra-contrib'
```

## config.ruの編集

config.ruは、以下のように編集します。こちらに処理を書いてもいいのですが、今回はmain.rbのほうに処理を書いていきます。

```rb
require './main.rb'

run Main
```

## 環境変数に追加
API KEYやID等の情報をherokuの環境変数に追加します。
LINE developersで作成したアカウントのBasic informationから、Channel ID、 Channel Secret、 MIDの3つ、herokuのFixieアドオンのproxy_URL、そしてBOT TREE for MEDIAのAPI キーを登録します。

```
heroku config:add LINE_CHANNEL_ID="your_channel_id"
heroku config:add LINE_CHANNEL_SECRET="your_channel_secret"
heroku config:add LINE_CHANNEL_MID="your_channel_mid"
heroku config:add BOT_TREE_API_KEY="your_api_key"
heroku config:add FIXIE_URL="your_proxy_url"
```

## main.rbの編集

main.rbを以下のように編集します。

```rb
require 'bundler/setup'
require 'sinatra/base'
require 'json'
require 'rest-client'

class Main < Sinatra::Base

  post '/linebot/callback' do
    @params = JSON.parse(request.body.read)['result'].first

    post_bot_tree

  end

  private

  def post_text(post_messages)
    line_pipe = {
      'Content-Type': 'application/json; charset=UTF-8',
      'X-Line-ChannelID': ENV['LINE_CHANNEL_ID'],
      'X-Line-ChannelSecret': ENV['LINE_CHANNEL_SECRET'],
      'X-Line-Trusted-User-With-ACL': ENV['LINE_CHANNEL_MID']
    }

    RestClient.proxy = ENV['FIXIE_URL']
    endpoint_uri = 'https://trialbot-api.line.me/v1/events'

    post_message = post_messages.join
    request_content = {
      to: [@params['content']['from']],
      toChannel: 1383378250,
      eventType: '138311608800106203',
      content: {contentType:1, toType:1, text: post_message }
    }
    content_json = request_content.to_json

    RestClient.post(endpoint_uri, content_json, line_pipe)
  end

  def post_bot_tree
    word = @params['content']['text']
    request_content = {"api" => ENV['BOT_TREE_API_KEY'], "content" => {"userid" => @params['content']['from'], "text" => word}}
    content_json = request_content.to_json

    rest = RestClient.post('https://bottree.tokyo', content_json)
    result = JSON.parse(rest)
    messages = result['contents'].map{ |message| message['content'] + "\n"}
    post_text(messages)
  end
end
```

## 動作確認

LINE上で会話してみました。

![スクリーンショット 2016-06-11 22.43.06.png](https://qiita-image-store.s3.amazonaws.com/0/79302/ead2c709-5868-cfce-47c0-c5af71532653.png)

# 感想

## 非エンジニアにも運用できると言うが・・・

サービスの概要として、

>はじめにセッティングさえ行えば、非エンジニアの方がノンプログラミングでLINE, Facebook Messenger, Slack, Skype等のプラットフォーム上で機能するチャットボットの中身を作り、運用することができるダッシュボード(管理画面)・雑談機能を提供するAPI。[引用：prtimes.jp](http://prtimes.jp/main/html/rd/p/000000007.000019209.html)

とありますが、LINE等プラットフォームとの接続部分はプログラミングする必要が当然あります。非エンジニアが使用できるようなドキュメントが充実していれば間口が広がるかもしれません。

## ユーザー管理機能は良いけど・・・

ユーザーの一覧と会話履歴が見られるGUIが提供されているのは便利ですね。ただ、現状ユーザーのプロフィール取得時にバリデーションもなければ形態素解析で必要な情報のみを抽出してくれるわけでもないので、そのあたりは各プログラマーが独自に実装する必要があります。このあたりは今後に期待です。

## 記事管理は正直微妙

記事検索に必要なキーワードは最大5個ですし、手動で入力する必要があります。当然、タイトルや記事内の文章を用いた検索もできません。このAPIをBOTとして実装できる技術があるなら、記事配信の部分も独自に実装したほうが有意義かもしれません。

## 雑談機能はおまけ程度

試しに色々話しかけてみましたが、雑談機能は実用レベルではないかなと感じました。以下は一例です。

![スクリーンショット 2016-06-11 23.27.54.png](https://qiita-image-store.s3.amazonaws.com/0/79302/2f18f4dd-9c77-0cdd-aabd-9e3fc8b20047.png)

特定の言葉に関しては適切な答えが返ってきますが、意味のない返答が大多数ですね。使い続けると学習してくれたりするのでしょうか？

## 総括

非エンジニアから見るとちょっと敷居が高く、エンジニアの助けなしで導入するのは難しそう。かといってエンジニアが介入するのなら、別のサービス・APIを選んだほうが良い気がします。なので、ちょっとしたメディアサイトを個人レベルで運営している非エンジニアが、ちょっと勉強してLINE等で配信するためのボットを作る・・というような用途しか思い浮かばないですね。

これから機能・ドキュメントが充実してくれば革新的なサービスになりえるかもしれないので、今後に期待です！