20
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

run.py
"""Slack Bot Program."""
# coding: utf-8

from slackbot.bot import Bot

def main():
    """
    Slackbot
    """
    bot = Bot()
    bot.run()

if __name__ == '__main__':
    main()
slackbot_settings.py
"""
Configuration file for slackbot
"""
API_TOKEN = 'YOUR_API_TOKEN'

DEFAULT_REPLY = '何言ってんの?'

PLUGINS = ['plugins']

ここに書いてある通りです。
run.pyを実行すれば、Slackbotは動き出します。

##slackbot_restapi.py

plugins/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のみのリストを作成して返すメソッドを追加しています。
リスト内包表記って便利ですよねー。なんか新鮮でした。

plugins/restapi.py
"""
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アクセスに失敗しました')

plugins/gnaviapi.py
"""
ぐるなび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

20
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?