Python3の勉強がてらSlackbotを作ってみた
オリジナル
Python3の勉強がてらSlackbotを作ってみた - Qiita
Qiitaからの移行記事です。
はじめに
タイトル通りですが、Pythonの勉強がてらSlack用のBotを作ってみました。 他の方々が記事で書いているので、自分の備忘で残すレベルになります。 Slackの登録方法、Botを使い始めるまで、Herokuの使い方は記載していません。 ソースコードを載せているので、ソースコードの書き方などでお作法的に間違っていることがあれば、指摘してください。
仕様
ぐるなびAPIを利用して、slackで検索ワードを入力してヒットしたURLを返します。 「ご飯 品川 焼き鳥」と打つと、品川の焼き鳥屋っぽい店のURLを返します。
環境などなど
- Slack
- Heroku
- Python3.6.0
- lins05/slackbot
構成
slackbot/ ├ plugins/ │ └ slackbot_restapi.py │ └ restapi.py │ └ gnaviapi.py │ └ run.py └ slackbot_settings.py └ Procfile(Heroku用ファイル) └ runtime.txt(Heroku用ファイル)
実装
run.py と slackbot_settings.py
"""Slack Bot Program.""" # coding: utf-8 from slackbot.bot import Bot def main(): """ Slackbot """ bot = Bot() bot.run() if __name__ == '__main__': main()
""" Configuration file for slackbot """ API_TOKEN = 'YOUR_API_TOKEN' DEFAULT_REPLY = '何言ってんの?' PLUGINS = ['plugins']
ここに書いてある通りです。 run.pyを実行すれば、Slackbotは動き出します。
slackbot_restapi.py
""" Plugin Program """ from requests.exceptions import RequestException from slackbot.bot import listen_to from plugins.gnaviapi import GnaviApi @listen_to('ご飯') def search_restraunt(message): """ 受信メッセージを元にぐるなびを検索してURLを返す """ gnavi = GnaviApi('https://api.gnavi.co.jp/RestSearchAPI/20150630/') key = 'YOUR_API_KEY' search_word = message.body['text'].split() if len(search_word) == 3: params = { 'keyid': key, 'format': 'json', 'address': search_word[1], 'freeword': search_word[2] } try: gnavi.api_request(params) for rest_url in gnavi.url_list(): message.send(rest_url) except RequestException: message.send('ぐるなびに繋がんなかったから、後でまた探してくれ・・・( ´Д`)y━・~~') return except Exception as other: message.send(''.join(other.args)) return else: message.send('↓こんな感じで検索してほしい・・・( ̄Д ̄)ノ') message.send('ご飯 場所 キーワード(文字はスペース区切り)') message.send('例)ご飯 品川 焼き鳥')
Slackで打ち込まれた内容を拾って処理します。 ここで微妙にハマったのは、Slackで入力されたMessageの拾い方がわからなかったことです。 ちょいちょい調べたところ、
message.body['text']
で取得できることがわかりました。 拾ったメッセージをsplit()で分割して、場所とフリーワードをAPIのパラメータとして使います。
restapi.py と gnaviapi.py
Pythonのクラスと継承の勉強で作ってみました。 restapi.pyでは、Requestを投げてResponseを持っとくだけのクラスです。 gnaviapi.pyでは、ResponseからURLのみのリストを作成して返すメソッドを追加しています。 リスト内包表記って便利ですよねー。なんか新鮮でした。
""" REST API CLASS """ # -*- coding: utf-8 -*- import requests from requests.exceptions import RequestException class RestApi(): """ REST API CLASS """ def __init__(self, url): self.url = url self.response_data = None def api_request(self, search_dict): """ API呼び出し """ try: self.response_data = requests.get(self.url, params=search_dict) except RequestException: raise Exception('APIアクセスに失敗しました')
""" ぐるなびAPI """ # -*- coding: utf-8 -*- from plugins.restapi import RestApi class GnaviApi(RestApi): """ ぐるなびAPI用クラス """ def __init__(self, url): super().__init__(url) def url_list(self): """ ResponseからレストランURLのリストを作って返す。 """ json_data = self.response_data.json() if 'error' in json_data: raise Exception('そのキーワードじゃ見つかんなかった・・・(´・ω・`)') return [rest_data['url'] for rest_data in json_data['rest']]
実行結果
こんな感じです。
終わりに
ATNDやdots.など他のAPIで検索できるように、拡張は簡単にできそうです。 pythonで実装するよりも、Herokuの使い方に四苦八苦していた時間の方が長かった気がしますw