ゲロ安クラウドのCloud At CostにHangoutsBotを導入してみた。

#TL;DR
HangoutBOTのゲロ安クラウドへの導入と、プラグインの作成まで軽く触ります。
誤記や勘違い、もっといい方法があったらぜひ教えてください。

#Cloud At Cost導入
##導入までのいきさつと、サーバー購入
今回の件含めてあれこれいたずらするのにサーバーが欲しかったのですが、
めんどくさいので自宅環境でやろうとしたら **我が家の財務大臣から稟議が下りなかった** ので、
安上がりなのを探しました。
今時自宅環境高いっすからね、機器代電気代もろもろ。
もう一つ、Nuro光を入れたらHuaweiの光ルータがついてきて、いじるのがめんどくさかった。

AWSあたりも見てみましたがコスト感が見えないのと、
商用じゃないので安定性も要らないし、固定支出を増やしたくなかったので却下となりました。

結果、見つけたのがこれ

http://cloudatcost.com/

買い切り型（ただし、別途年に5ドルほどかかるそうです。）で常時セールやってます。
急ぎでなければ80%OFFを待って購入しましょう。
私は嫁に土下座して下から二番目の価格設定のを買ってみました。
**お値段は驚きの3000円**
スペック的には初期設定のMinecraftのサーバー入れて、2，3人入ったらガクガク落ちるレベルです。
あとサーバーが確かカナダあたりの田舎にあるのでpingが160くらいあります。


#クラウドへのCendOS導入
##OS側初期設定
OSはいくつか選択肢があります。
私はCentOSを入れましたが、初期設定はこちらのサイトを参考にしました。
[【人柱】激安VPSのCloud at Costを試してみた。800円で一生使い放題だ！ - ghost_in_the_info](https://ghostinthe.info/cloudatcost/)


さて、適当に終わらせたので適当にたたいていきます。

```shell
yum update
```

ああ気持ちいい。(4時間くらいかかりました。)

適当にログイン用のユーザーを
あとはおまじないとしてsshからrootログインできないようにしておきましょう。
ログを見る限り、セキュリティの甘いIoT機器を狙うのが最近のトレンドのようではありますが、
それでも連番でサーバが並んでるところでrootログインするのは超危険です。

一個ログイン用ユーザーをaddした後、rootを殺します。
[Linuxにユーザーを追加する](https://qiita.com/Tooooomin/items/c063cee80227a5f1d95b)

```vim:/etc/ssh/sshd_config
# vi /etc/ssh/sshd_config
･･･
PermitRootLogin no
```
以降作業は別usrでログインしてから
`su root`
して実施しましょう。
厳密にいうとrootでbot運用するのも望ましくないんですが、まあその辺は商用じゃないし適当に。

##BOT側インストール準備
さてさて、BOTを動かすうえで足りないパッケージはこの辺。

日本語化パッケージ
(参照：https://www.server-world.info/query?os=CentOS_7&p=japanese)

python3,pip3
デフォルトで入っているのはpython2なのでyumした後おまじない

```shell
$ ln -s /bin/python3 /bin/python
$ ln -s /bin/pip3.6 /bin/pip
```

Git
引っ張ってくるのに必要です。

##HangoutsBotのインストール
この辺を入れ終わったらとりあえず動くはずなので、
/usr/src/あたりで適当にえいっ！

```
git clone -b v3.0 https://github.com/hangoutsbot/hangoutsbot.git
cd hangoutsbot
pip3 install -r requirements.txt
```

これで動きます。

`python hangupsbot/hangupsbot.py`

初回ログイン時にGoogleログインのIDとパスワードを聞かれるので、
適当にアカウント作って渡しましょう。
既存アカウントに入れて、都合の悪い発言を **「Botがやりました」** ともみ消す手もありますが、
セキュリティ等の理由であまりおすすめはできません。

最近Googleアカウントも厳しくて、カナダからのログインは通してくれませんので、
https://accounts.google.com/b/0/displayunlockcaptcha
ログイン前にここでボタンを押してセキュリティ解除しましょう。
b/#のところが複数アカウントの識別用です。普段Googleアカウント一つしか使っていなくて、
BOTアカウントを初めて入れなおしたなら、2個目なので1。
https://accounts.google.com/b/1/displayunlockcaptcha
こんな感じで0スタートの連番。

動き始めたらシェルでログがだーっと流れますが、
動いてるかどうかはハングアウトで確認します。

![9dd2a8a2af8909dc464511270ccf5a9f.png](https://qiita-image-store.s3.amazonaws.com/0/211046/5e1f57d3-fd37-1cea-f21c-a2b0ead0474e.png)

よしよし。
これで基本機能はOKです。

##死活管理
続いて、死活管理です。
SSHを切ると落ちちゃいますので、その辺の対策。
設定ファイルはrootでインストールした場合、
/root/.local/share/hangupsbot/
に入っています（大事）（3時間ハマった）

```bash:/root/.local/share/hangupsbot/hangupsbot.sh
#!/bin/sh

python3 /usr/src/hangoutsbot/hangupsbot/hangupsbot.py
```

```bash
chmod 744 hangupsbot.sh
nohup ./hangupsbot.sh & 
```

これで一応バックグラウンドで動きますが、このBOTは気づくとセミレベルの頻度で死ぬので、もう一個シェル作って

```bash:boot_hobot.sh
#!/bin/bash

VAR=`ps -u root |grep hangupsbot`
echo $VAR

if [ -z $VAR ]; then
        /root/.local/share/hangupsbot/hangupsbot.sh
fi
```

`ps`で拾えなかったら自動起動という設定を超適当に書きまして、これをclontabで実行
参考：[crondでプログラムを自動実行する / CentOS](https://qiita.com/yukikimoto/items/e167dbea7ea11a0081ac)

これで大体心配いらなくなると思います。
ここまでやっても時々CloudAtCost自体が死んでどうにもならないことがありますが、仕様なのであきらめましょう。


#HangoutsBotで遊ぶ
##Admin設定
さて、前置きが長くなりましたが、せっかく入れてみたので遊びましょう。
さっきも書きましたし、ちゃんと説明を見ると書いてはありますが、
BOTの設定でインストールしたディレクトリのconfig.jsonを直書きしても反映されません。
/root/.local/share/hangupsbot/config.json
こちらをいじり倒しましょう

まずはroot設定です。

![c5d044b8b918cac9af2eee1cabb3d0fc.png](https://qiita-image-store.s3.amazonaws.com/0/211046/380c902c-8ccb-b86e-aaa4-04071df3ab70.png)

`/bot whoami`
と哲学的なコマンドを投げるとIDをくれるので、これをjsonに反映。

```json:hangupsbot.sh
  "admins": ["10443-------------------"],
  ...
```

これでBOTを再起動すると、以降設定の読みこみ直しは
![6829d603444cf5a0a6b1b2939b6f5eb4.png](https://qiita-image-store.s3.amazonaws.com/0/211046/591894f7-4bb9-43e2-2e8d-dc6791176d87.png)
超簡単になります。

##Autoreply
この後はまずオートリプライの設定です。
さっきのjsonを弄るだけですので、

```json:config.json
…
      [
        "regex:.*ちん(ぽ|こ).*",
        "regex:.*チン(ポ|コ).*"
      ],
      [
        "そいや！",
        "そいや！",
        "そいや！",
        "そいや！",
        "そいや！",
        "そいや！",
        "そいや！",
        "そいや！",
        "くいっ！"
      ]
    ],
…
```

![851b072f086756385148d9ab7ef7eca6.png](https://qiita-image-store.s3.amazonaws.com/0/211046/ff3fe71d-c927-c1f6-49a1-f68caaddb149.png)
やった！僕にもお話相手ができました！！

基本的にはキー側はメッセージの前方一致で、
`"regex:.*ちん(ぽ|こ).*"`のように正規表現での表記もできます。 ~~性器だけにな！！！~~
回答のほうは確率で列記しているもののうち1個を返します。

```json:config.json
…
    [
      [
        "おみくじ",
        "omikuji",
        "/omikuji"
      ],
      [
        "今日の運勢は大凶です。ラッキーアイテムは一万円札。お金の力で災いを防ご
う",
        "今日の運勢は末吉。人生万事塞翁が馬です。ブロックされてもそのうちいいこ
とあるよ！",
        "今日の運勢は大吉。話は変わりますが、人間昇り詰めたらあとは落ちるだけで
す。気を付けましょう",
        "今日の運勢はマジ吉。オタク用SNSのG+で大暴れしてみよう。きっと人生が広が
りますよ。" ,
        "今日の運勢は大吉。やることなすこときっとうまくいきますが、最終的にはあ
なた次第です。",
…
```

100項目ほどおみくじを実装してみましたが、流石に飽きてきたので、次のあれこれを実装です。

グループHOからのIn/Outの検出

```json:config.json
…
    [
      "JOIN",
      "{event.user.full_name}さん、ようこそ<b>{conv_title}</b>へ！ここはアウトサ
イダーの掃きだめです。行動や話題は何も制限されませんが、履歴のONと招待リンクの無
効化はやめてね！なんでも聞いてみてください。"
    ],
    [
      "LEAVE",
      "わたしの弟、諸君らが愛してくれた{event.user.full_name}は死んだ！！なぜだ
！？"
    ],
…
```

この辺は色々機構が用意されていて簡単でした。
入室/退出すると名前付きでご案内等飛ばせます。
相手に直接個別チャットを送ったりもできますが、その辺は割愛。


##プラグイン作成
さて、追加のプラグインですが、
`/usr/src/hangoutsbot/hangupsbot/plugins`
に全部入っています。追加するのもここでよさげーなので、ファイルを一個作って追加。

みんな大好きビットコインの値段を拾ってくる奴を適当に作成してみました。

```python:getbitcoinprice.py
# coding: utf-8
"""
Get bitcoin/yen Price from zaif
c.f. http://techbureau-api-document.readthedocs.io/

"""

import plugins
import urllib.request
import json


def _initialize(bot):
    plugins.register_user_command(['bitcoin'])


def bitcoin(bot, event, *args):
    get_bitcoin_url = "https://api.zaif.jp/api/1/last_price/btc_jpy"
    bitcoin_req = urllib.request.Request(url=get_bitcoin_url)

    with urllib.request.urlopen(bitcoin_req) as bitcoin_price:
        body = json.load(bitcoin_price)

    yield from bot.coro_send_message(event.conv_id, 'BTC/JPY = {}'.format(body['last_price']))
```

ログ取ったりもあるのだけど、めんどくさかったのでやってないです。

読んだ感じの仕様としては、メインのほうからコマンド定義を読みに来るのを
`    plugins.register_user_command(['bitcoin'])`
で設定して、eventIDと一緒にメッセージを返す感じですね。

関数のほうは
`def bitcoin(bot, event, *args):`
前二つはメインからの情報引き渡しで固定値です、変えると動きません。
*argsで、コマンド後の引数を渡します。今回は引数使いません。

とまあやってることはそんな難しくないですね。

更にjsonのほうにも

```json:hangupsbot.sh
…
  "plugins": [
    "botaliases",
    "default",
    "subscribe",
    "autoreply",
    "dnd",
    "mention",
…
    "getbitcoinprice"
  ]
}
```

流すとこんな感じです。

![00ecc6048c22c5d29fdd1e3079d85fa1.png](https://qiita-image-store.s3.amazonaws.com/0/211046/e7d05e77-c935-4d9d-246a-6807fb432a1d.png)

あれ、また下がってね？ってのは興味ないので置いといて、
割と簡単ですし、Pythonなのでよそからモジュール引っ張ってくれば工夫次第であれこれ使えますね。
APIで拾うにせよ何にせよすごい簡単になってきました。いい時代になったもんです。

#あとがき
とりあえず自分がやってみたことはこんな感じです。
長くなりましたが最後まで読んでいただきありがとうございました。
次は「私の現在位置をもとに嫁に通知を送る」あたりを実装予定です。
面白いネタがあったら試してみるので教えてくださいませ。

BOTを試しに使ってみたいという方がいらっしゃいましたら、
https://twitter.com/Ovis_meme
ご連絡を頂ければ対応します。