#はじめに
タイトル通りですが、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