Aizu LT 0x09に出た

出てきた.そして発表した.

今回作ったものの紹介も兼ねて,今回の記事を書こうと思います.

今回作ったものは Slack bot を作りました.その名も Hatsonくん.某IBM人工知能とグラハムベルの助手のワトソンくんをかけています.

f:id:flying_hato_bus:20171112165306p:plain

なぜ作った

11月11日にLT会が行われる予定だったんですが,LT会が開催されるのを11月10日の夜9時ごろに知りました.

実は来週にもLT会を控えていて,それと予定を勘違いしていました.

時間がない

ということで,以前ちょっと作ってそのまんまにしていたSlack Botを急遽作ることに.

最近のあくんが「自分のslack teamを作って,好きなASMR配信者の配信開始の時間に通知送ってくれるようにしたらね,捗ってしゃーない」って言っていたのと,webの知識を取り入れたいと思っていたのでAPIを叩く練習にもちょうどいいかなと思って,これを作ることにしました.

使ったもの

  • サーバー Raspberry pi 3
  • 言語 python3 (ver 3.4.5)
  • 使用ライブラリ slackbot
  • 使用API OpenWeatherMap Google calender API

サーバーとして使ったのは安心と安定のラズパイ,どうせずっと起動させるしちょうどいいですね,言語はpython3,ライブラリにめちゃくちゃ手軽にslackbotを作ることができるライブラリがあるのでpythonを使った.(pythonしか使えない人でもある)

使用したライブラリはこちら

github.com

slackbotにリプライ送ったり,設定した言葉を発言すると,それを受け取って,任意の行動をしてくれます.

今回は「〇〇の天気」と言ったらその場所の天気を表示してくれるようにしました.Google calender APIを叩こうと思いましたが,うまく叩けませんでした,

実装

作成方法はラズパイをセッテイングして,python3にして,ライブラリを入れればおk.

pyenv install 3.4.5でpython3.4.5にバージョンをインストールして,pyenv global 3.4.5にして,sudo pip3 install slackbotでライブラリを入れられます.

slackbot 用のディレクトリを作って,ファイルを以下のように設定します.

f:id:flying_hato_bus:20171112174416p:plain

最低限動かすならば,以下のようにしていく. run.pyに以下のように記載します.

from slackbot.bot import Bot
def main():
    bot = Bot()
    bot.run()

if __name__ == "__main__":
    main()

つぎはslackbot_settings.py

# botアカウントのトークン
API_TOKEN = "xxxx-xxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"

# このbot宛のメッセージで、どの応答にも当てはまらない場合の応答文字列
DEFAULT_REPLY = "ポッポ〜(意味不明)"

# プラグインスクリプトを置いてあるサブディレクトリ名のリスト
PLUGINS = ['plugins']

これだけで動いてしまうのでめちゃくちゃ楽だった.

python run.pyでもうslackbotを起動できる.

f:id:flying_hato_bus:20171112181141p:plain

こんな感じで動いてくれる.かわいいね.かわいいんだよ.ほら!!!かわいいだろ!!!かわいい!かわいい!

かわいいって言えよ!!!! なあ!!!

これからはハトソンくんはかわいいと定義します.

そんなことは言わないで,ここからbotを育てて行きます.

使う関数は以下のを流用していけばなんとかなる.

from slackbot.bot import respond_to     # @botname: で反応するデコーダ
from slackbot.bot import listen_to      # チャネル内発言で反応するデコーダ
from slackbot.bot import default_reply  # 該当する応答がない場合に反応するデコーダ

@respond_to("hoge")
def mention_func(message):
    message.reply('I catched hoge.') # メンションをつけて返事する.

@listen_to('hogehoge')
def listen_func(message):
    message.send('Someone posted hogehoge')      # ただ投稿をするだけ
    message.reply('Are you posted?')                           # メンションをつけて返事する

この二つで大体のことは事足りる.

例えば時間を知りたかったら,timeとかdatetimeとかをimportして.

f:id:flying_hato_bus:20171113104821p:plain

こんな感じに現在時刻を取得,POSTするようにすれば.

f:id:flying_hato_bus:20171113104938p:plain

時間を教えてくれるようになる.

天気情報の取得

天気の情報の取得には OpenWeatherMapを使用した.

openweathermap.org

日本国内のAPIを使おうとしたが,有料なのといい感じのが見つからなかったのでこれを使用した.

有料版もあるが,無料版にした.

メールアドレスを登録してちょっとやればAPIキーを発行できる.

料金体系はこんな感じ,まあ一人くらいだし一分間に60もAPIを叩くことはないでしょうということで,無料版にした.

f:id:flying_hato_bus:20171113105645p:plain

基本的にはhttp://api.openweathermap.org/data/2.5/forecastというURLのエンドポイントにいろいろ付け足していけばAPIを叩くことができる.

都市の天気を知るためには,二つの方法があった.一つは都市名を指定する方法,もう一つは緯度経度を指定する方法.

都市名でやろうとしたら結構都市名を検知するところがガバガバで,きちんとした都市の結果が表示されなかったので,

ある程度ガバガバでも緯度経度を算出してくれるpythonのGeocoderでやった.

地名を入れてくれると,緯度経度が 返ってくるのでとても便利.

例えば,会津若松市の緯度経度を知りたかったら.

from pygeocoder import Geocoder
address = '会津若松市'
results = Geocoder.geocode(address)
print(results[0].coordinates)

result = Geocoder.reverse_geocode(*results.coordinates, language="ja")

これで,緯度経度,住所が返ってくる.今回は会津若松市の市庁舎の住所が返ってきた.

print(result)

=> (37.4947611, 139.9298096)
=> 日本、〒965-0872 福島県会津若松市東栄町3−46 会津若松市役所本庁舎

タプルで緯度経度が返ってきて,あとはこれをエンドポイントにくっつけてあげて,APIを叩く.

あとはHatsonくんがどうやって都市名を取得するかだが,slackbotライブラリの反応する言葉には正規表現が使えたので.

「(.*)の天気」で「〇〇の天気」の「〇〇」を抽出できる.

実装としてはこうなる. f:id:flying_hato_bus:20171113111414p:plain

mode = jsonとしているので,json形式でデータがくる.

データとしては

{
    'coord': {'lon': 139.93, 'lat': 37.49}, 
    'weather': [{'id': 500, 'main': 'Rain', 'description': 'light rain', 'icon': '10n'}], 
    'base': 'stations', 
    'main': {'temp': 10.11, 'pressure': 929.48, 'humidity': 80, 'temp_min': 10.11, 'temp_max': 10.11, 'sea_level': 1017.83, 'grnd_level': 929.48},
    'wind': {'speed': 2.01, 'deg': 252.004}, 
    'rain': {'3h': 0.725},
    'clouds': {'all': 92}, 
    'dt': 1510342842, 
    'sys': {'message': 0.0101, 'country': 'JP', 'sunrise': 1510262103, 'sunset': 1510299179},
    'id': 1854742,
    'name': 'Ōdera',
    'cod': 200
}

と返ってきていて,ここでweatherとtempを表示している.ここに返ってきている情報は全部使用が可能なので,もっといろんなことに使える.

実際Hatsonくんはどうかと言うと...

f:id:flying_hato_bus:20171113113359p:plain

会津の天気はまだしも,平壌の天気も取得してくれる.

神だった

さすがHatsonくんでした.これはすごい,濡れた.

こんな感じで天気の部分は実装した.あとはgoogle calenderだ!と思ったけど,なんか触ってみたらエラーしか返ってこないので悲しくて,時間がなくなってきたのでやめた.

今後の展望としては,なんとかしてGoogle calender APIを叩いて今日やることの確認,ゴミだしの日を教えてくれるように変更したい.

というわけでこれをLT会で発表してきた.発表してきた時のスライドはこちらになります.

www.slideshare.net

API叩くの難しいと思いました.おわり!!!