怒Mは思いつきでモノを言う

やったことメモなどなど

Python3の勉強がてらSlackbotを作ってみた

オリジナル

Python3の勉強がてらSlackbotを作ってみた - Qiita

Qiitaからの移行記事です。

はじめに

タイトル通りですが、Pythonの勉強がてらSlack用のBotを作ってみました。 他の方々が記事で書いているので、自分の備忘で残すレベルになります。 Slackの登録方法、Botを使い始めるまで、Herokuの使い方は記載していません。 ソースコードを載せているので、ソースコードの書き方などでお作法的に間違っていることがあれば、指摘してください。

仕様

ぐるなびAPIを利用して、slackで検索ワードを入力してヒットしたURLを返します。 「ご飯 品川 焼き鳥」と打つと、品川の焼き鳥屋っぽい店のURLを返します。

環境などなど

構成

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']]

実行結果

こんな感じです。

スクリーンショット 2017-05-16 1.45.09.png

終わりに

ATNDやdots.など他のAPIで検索できるように、拡張は簡単にできそうです。 pythonで実装するよりも、Herokuの使い方に四苦八苦していた時間の方が長かった気がしますw