SlackのBot経由でメッセージAPIに登録したメッセージを読み上げる

# できたもの

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/hyY-iRMAt58/0.jpg)](http://www.youtube.com/watch?v=hyY-iRMAt58)


# 用意したもの

- Raspberry Pi3(microSD、電源ケーブルは別途必要です)
- Bose SoundLink Mini Bluetooth speaker II
 
# 制作手順

## 1. RaspberryPi3のセットアップ

- OSなどのインストールは他のQiita記事を参考にしてください
 
- OSインストールできたらSSH接続してみます

```shell-session
pi@raspberrypi:~ $ ssh pi@192.xxx.xxx.xxx　 * RaspberryPi3 IPを確認
pi@192.168.11.16's password: raspberry * 初期パスワード

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Feb 24 21:51:21 2017 from 192.168.11.7
pi@raspberrypi:~ $ 
```
- パスワードは変更しておいたほうがよさそうです
 
```
pi@raspberrypi:~ $ sudo passwd pi
Enter new UNIX password:  * 新しいパスワード
Retype new UNIX password: * 新しいパスワード
passwd: password updated successfully
```

- スピーカの電源を入れてペアリングモードして、Bluetoothスピーカーと接続してみます
 
```shell-session
pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller B8:27:XX:XX:XX:XX raspberrypi [default]
[NEW] Device 64:A9:XX:XX:XX:XX 64-A9-D7-XX-XX-XX
[NEW] Device 65:5F:XX:XX:XX:XX 65-5F-6F-XX-XX-XX
....
[NEW] Device 04:52:XX:XX:XX:XX Bose Mini II SoundLink 

-- 初回はpairが必要かも
[bluetooth]# pair ０４:５２:XX:XX:XX:XX 　＊ 上記Bose Mini II SoundLinkのID
Attempting to pair with ０４:５２:XX:XX:XX:XX

-- 接続
[bluetooth]# connect 04:52:XX:XX:XX:XX
Attempting to connect to 04:52:XX:XX:XX:XX
[CHG] Device 04:52:XX:XX:XX:XX Connected: yes
Connection successful

-- （参考） 接続解除したいときは...
[bluetooth]# disconnect 04:52:XX:XX:XX:XX
Attempting to disconnect from 04:52:XX:XX:XX:XX
Successful disconnected
```

- (事前準備)音量調節とサンプルのサウンド再生をしてみる

```shell-session
pi@raspberrypi:~ $ alsamixer 

pi@raspberrypi:~ $ aplay /usr/share/sounds/alsa/Front_Center.wav
再生中 WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, レート 48000 Hz, モノラル
```

- AquesTalk Piをインストールして音声合成してみる

```
pi@raspberrypi:~ $ wget http://www.a-quest.com/download/package/aquestalkpi-20130827.tgz
pi@raspberrypi:~ $ tar xzvf aquestalkpi-20130827.tgz
pi@raspberrypi:~ $ cd aquestalkpi
pi@raspberrypi:~ $ ./AquesTalkPi "今日はいい天気ですね。" | aplay
pi@raspberrypi:~ $ 再生中 WAVE 'stdin' : Signed 16 bit Little Endian, レート 8000 Hz, モノラル
```

- 外人さんが片言の日本語で話しかけてきたらOKです

- 定期実行したいのでcronを使えるようにしておきます

```shell-session

pi@raspberrypi:~ $ sudo /etc/init.d/cron start
[ ok ] Starting cron (via systemctl): cron.service.
```

- 自動起動の設定もしておきます

```shell-session

pi@raspberrypi:~ $ sudo apt-get install chkconfig
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  chkconfig
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 119 個。
9,766 B のアーカイブを取得する必要があります。
この操作後に追加で 59.4 kB のディスク容量が消費されます。
取得:1 http://mirrordirector.raspbian.org/raspbian/ jessie/main chkconfig all 11.4.54.60.1debian1 [9,766 B]
9,766 B を 0秒 で取得しました (12.1 kB/s)
以前に未選択のパッケージ chkconfig を選択しています。
(データベースを読み込んでいます ... 現在 128178 個のファイルとディレクトリがインストールされています。)
.../chkconfig_11.4.54.60.1debian1_all.deb を展開する準備をしています ...
chkconfig (11.4.54.60.1debian1) を展開しています...
man-db (2.7.0.2-5) のトリガを処理しています ...
chkconfig (11.4.54.60.1debian1) を設定しています ...

pi@raspberrypi:~ $  sudo chkconfig cron
cron  on

```

## 2. Message APIをHeroku動かす

- Message APIをscaffoldします(DBはpostgresに変更)

```rb

$ rails new t-taira-messages
$ rails g scaffold message content:text invoked_at:datetime repeat:boolean
```

- モデルに処理を追加しました
 
```rb
class Message < ApplicationRecord
  # nowメッセージを取得
  scope :now, -> { where(invoked_at: Time.now.strftime('%Y-%m-%d %H:%M'))  }

  class << self
    # repeatフラグを見て、次の日のメッセージを作成
    def generate
      Message.where(repeat: true).each do |m|
        Message.create(content: m.content, invoked_at: m.invoked_at + 1.day, repeat: true)
        m.destroy
      end
    end
  end
end
```

- type=nowをリクエストしたら、メッセージを取得するようにしました

```rb

class MessagesController < ApplicationController
  def index
    @messages = Message.all
    @messages = Message.now if params[:type] == 'now' # ここ追加
  end
end
```

- repeatフラグがONのものは、毎日次の日のメッセージを作成するタスクを追加しました

```rb

# 次の日のメッセージを作成するタスク(lib/tasks/scheduler.rake)
desc "This task is called by the Heroku scheduler add-on"
task :generate_messages => :environment do
  puts "Generating messages..."
  Message.generate
  puts "done."
end
```

- Message APIをHerokuで動かせるようにします

```
$ git init
$ git add .
$ git commit -m 'first commit'


$ heroku create t-taira-message
Creating ⬢ t-taira-message... done
https://t-taira-message.herokuapp.com/ | https://git.heroku.com/t-taira-message.git

$ heroku config:add TZ='Asia/Tokyo'

$ heroku config:add TZ='Asia/Tokyo'
Setting TZ and restarting ⬢ t-taira-message2... done, v3
TZ: Asia/Tokyo

$ git push heroku master
$ heroku run rake 
db:migrate

　$ heroku open
```

- こんな画面表示されればOKです
<img width="548" alt="スクリーンショット 2017-02-26 9.24.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/42805/82e163f2-cd76-69e0-f5e4-fdc8d1907d57.png">

- hubot設定

```
$ heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=https://t-taira-bob.herokuapp.com/
$ heroku config:add HUBOT_HEROKU_WAKEUP_TIME=8:00
$ heroku config:add HUBOT_HEROKU_SLEEP_TIME=24:00
```

- 次の日のメッセージを作成するタスクのスケジュールする設定をします

```
$ heroku addons:create scheduler:standard
$ heroku addons:open scheduler:standard
```

<img width="656" alt="スクリーンショット 2017-02-26 6.24.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/42805/beb07dde-07ed-0f26-a8eb-12b6569c824c.png">


## 3. Slackのbotを仕込む

- 必要なモジュールをnpm経由でインストールします
 
```
$ npm install -g hubot yo generator-hubot coffee-script
```

- hubotの作成をします

```
$ mkdir hubot-bob
$ cd hubot-bob/
$ yo hubot
                     _____________________________  
                    /                             \ 
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             / 
 ======= |[^_/\_]|   /----------------------------  
  |   | _|___@@__|__                                
  +===+/  ///     \_\                               
   | |_\ /// HUBOT/\\                             
   |___/\//      /  \\                            
         \      /   +---+                            
          \____/    |   |                            
           | //|    +===+                            
            \//      |xx|                            

? Owner Takao Taira <takao.taira@gmail.com>
? Bot name hubot-bob
? Description A simple helpful robot for your Company
? Bot adapter campfire
   create bin/hubot
   create bin/hubot.cmd
   create Procfile
   create README.md
   create external-scripts.json
   create hubot-scripts.json
   create .gitignore
   create package.json
   create scripts/example.coffee
   create .editorconfig
```

- Message APIを操作するscriptを追加します

```
querystring = require "querystring"
url = 'https://t-taira-message.herokuapp.com/messages.json'

module.exports = (robot) ->
  robot.respond /message list/i, (msg) ->
    request = msg.http(url).get()
    request (err, res, body) ->
      data = JSON.parse body
      message = ''
      for value in data
        robot.logger.info value
        message += value.content
      robot.send message

  robot.respond /message post (.*) (.*)/i, (msg) ->
    content = msg.match[1]
    invoked_at = msg.match[2]
    data = querystring.stringify({'message[content]': content, 'message[invoked_at]': invoked_at})
    msg.http(url)
      .post(data) (err, res, body) ->
        response = JSON.parse(body)
        robot.logger.info response
        msg.send 'うっす'
```


　- Herokuで動かしたいので、sleepしないように設定追加

```json
{
  "name": "bob",
  "version": "0.0.0",
  "private": true,
  "author": "Takao Taira <takao.taira@gmail.com>",
  "description": "A simple helpful robot for your Company",
  "dependencies": {
    "hubot": "^2.19.0",
    "hubot-diagnostics": "0.0.1",
    "hubot-google-images": "^0.2.6",
    "hubot-google-translate": "^0.2.0",
    "hubot-help": "^0.2.0",
    "hubot-heroku-keepalive": "^1.0.2", # ここ追加
    "hubot-maps": "0.0.2",
    "hubot-pugme": "^0.1.0",
    "hubot-redis-brain": "0.0.3",
    "hubot-rules": "^0.1.1",
    "hubot-scripts": "^2.17.2",
    "hubot-shipit": "^0.2.0",
    "hubot-slack": "^4.3.2"
  },
  "engines": {
    "node": "0.10.x"
  }
}

```

- Massage APIを同様にHerokuにデプロイします

```
$ git init
$ git add .
$ git commit -m 'fitst commit'

$ heroku create t-taira-bob
$ heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=https://t-taira-bob.herokuapp.com/
$ heroku config:add HUBOT_HEROKU_WAKEUP_TIME=8:00
$ heroku config:add HUBOT_HEROKU_SLEEP_TIME=24:00

$ git push heroku master
```

- SlackでHubotを設定する方法は、ほかのQiita記事を参考にしてみてください。設定ができると以下の様な感じでSlackからMeaage APIにリクエストしてメッセージの登録ができます
 <img width="547" alt="スクリーンショット 2017-02-26 10.04.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/42805/ebf29f01-3ff1-a42d-7286-2f78b4820f93.png">

## 4. RaspberryPi3のcron設定

- もう一息ですw 登録されたメッセージを読み上げるスクリプトを作成します（Python初心者なので微妙なコードですみません）

```py
pi@raspberrypi:~ $ vi now.py 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
import os

URL = 'https://t-taira-message.herokuapp.com/messages.json?type=now'
r = requests.get(URL).json()
content = r[0]['content'].encode('utf-8')
print(content)
os.system('~/aquestalkpi/AquesTalkPi "' + content + '" | aplay')
```

- crontabの設定（1分毎に起動する）

```
pi@raspberrypi:~ $ crontab -e

*/1 * * * * python /home/pi/now.py
```

## 参考

- http://qiita.com/mochidamochiko/items/29c2d77715d8a1ff062a