Slackには外部のアプリと連携する強力なAPIが多数用意されています。
その一つであるOutgoing Webhooksを使って、特定キーワードに反応するbotを作ってみました。
こんな感じで、ラーメンに反応してランダムにラーメン画像を投げてくれます。
Outgoing Webhooks
Outgoing Webhooksは、Slackの投稿内容を外部のサーバーにPOSTできる機能です。
また、サーバーの応答内容によって、botからSlackに自動的に投稿を行うこともできます。
今回はAzure App Serviceを使ってサーバーを用意し、Slackから呼び出すような形にします。
なお、サーバーにはこんな感じのPOSTが飛ぶようです。
token=XXXXXXXXXXXXXXXXXX
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
timestamp=1355517523.000005
user_id=U2147483697
user_name=Steve
text=googlebot: What is the air-speed velocity of an unladen swallow?
trigger_word=googlebot:
今回は、textキーの内容を使って投稿内容を制御したいと思います。
Azureを使う意味
- サーバー建てるのが楽
- メンテが楽
- Visual Studioから簡単にデプロイできる
- Microsoft Imagineなら無料!(重要)
とは言いつつ使いこなせてない感があり、この記事でも無理やり動かしている箇所がいくつかあります。
用意するもの
- Visual Studio 2015
- Python Tools for Visual Studio (PTVS)
- 適当なMicrosoft Azure サブスクリプション
Djangoプロジェクトを作成
Visual StudioにPTVSをインストールして、Django Web Projectからプロジェクトを新規作成します。
作成したら、Python環境としてInstall in a virtual environment…を選択してください。
Azure App ServiceへアップロードするにはPython2.7か3.4が必要なため、今回はPython3.4に作成しています。
なお、実を言うとAzure App Serviceに入っているPython3.4には問題があるため、後でPython3.6をAzureのダッシュボードから入れます。
しかしAzureにデプロイするためには実行できる環境が必要なため、とりあえずインストールしておいてください。
インストールが完了したら、virtualenvにrequestsモジュールを入れます。
ソリューションエクスプローラーからPython Environmentsで先ほど作成した環境を右クリックして、「Install Python package」を選択します。
入力画面が出るので、requestsと入力してOKをクリック。
インストール出来たら、いよいよソースコードを変更していきます。
ソースの編集
編集するファイルは、以下の5つとなります。
- app/views.py
- app/get_keyword_image.py (新規作成)
- your_project_name/urls.py
- your_project_name/settings.py
- web.config
app/views.py
以下を追加します。
from django.http.response import JsonResponse
from app.get_keyword_image import get_image_url
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def get_image(request):
keyword = request.POST["text"]
if "ラーメン" in keyword and "ラーメンを検知した" not in keyword:
if len(keyword) > 10:
keyword = "ラーメン"
url = get_image_url(keyword)
return JsonResponse({"text": "ラーメンを検知した {0}".format(url)})
else:
return JsonResponse({})
ラーメン画像のURLを含むテキストをJSONで返すviewを定義しています。
(後でちゃんとトークンでの認証を実装しなければと思いつつ、まだやってない・・・)
app/get_keyword_image.py
import requests
import random
api_key = "your_api_key"
search_engine_id = "your_search_engine_id"
search_format = "https://www.googleapis.com/customsearch/v1" \
"?key={0}&cx={1}&num=10&start={2}&q={3}&searchType=image"
def get_image_url(keyword):
start_from = random.choice(range(20))
res = requests.get(search_format.format(api_key, search_engine_id, start_from, keyword), verify=False)
if res.status_code != 200:
return None
res_json = res.json()
url = random.choice(res_json["items"])["link"]
return url
if __name__ == "__main__":
print(get_image_url("ラーメン"))
ちょっと雑過ぎで申し訳ないですが、ランダムに指定されたキーワードから検索して画像URLを取ってくるプログラムです。
api_keyとsearch_engine_idはこのページやこのページを参考に取得してください。
your_project_name/urls.py
urlpatternsに以下のように追加してください。
urlpatterns = [
~中略~
url(r'^get_image$', app.views.get_image, name='get_image'),
]
your_project_name/settings.py
以下の部分を変更してください。(ALLOWED_HOSTSにはデプロイ時のURLを指定してください)
DEBUG = False
ALLOWED_HOSTS = ["yoursite.azurewebsites.net"]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
念のためSSLに強制的にリダイレクトする設定を追加します。
SECURE_SSL_REDIRECT = True
web.config
ソリューションエクスプローラーからプロジェクト名を右クリックして、「追加」→「既存の項目を追加」を選択し、web.configを追加してください。
web.configのhandersディレクティブを以下のように編集します。
<handlers>
<add name="PythonHandler" path="*" verb="*" modules="FastCgiModule" scriptProcessor="D:\home\python362x86\python.exe|D:\home\python362x86\wfastcgi.py" resourceType="Unspecified" requireAccess="Script"/>
</handlers>
デプロイ
ソリューションエクスプローラーからプロジェクト名を右クリックして、「公開」を選択してください。
発行先をMicrosoft Azure App Serviceに設定し、適当なサブスクリプションを選択し、App Serviceを新規作成してください。
発行が終わるとブラウザが立ち上がりますが、Python3.6がインストールされていないためエラーになっています。
Python3.6のインストール
最後にPython3.6をApp Serviceにインストールします。
AzureダッシュボードからApp Serviceを選択し、拡張機能タブから「追加」を選択します。
その中からPython 3.6.2 x86を選択し、「追加」をクリックしてください。
完了したら、App Serviceのコンソールタブに移動して、以下のコマンドを実行してください。
> cd D:\home\python362x86
> python -m pip install django requests
成功すれば、サイトにアクセスできるようになっているはずです。
curlなどで https://yourapp.azurewebsites.net/get_image にPOSTしてみて、成功するか確認してください。
Slackでの設定
このページの「Slackでの設定」セクションなどを参考にして、Outgoing Webhooksを追加します。
URLには作成したサイトのURLを指定し、Trigger Wordは空にしておきます。
これでいちおうbotが動くようになります。
所感
「サクッと」という肩書きで記事を書きましたが、けっこう手順が煩雑ですね。本当に申し訳ない(
やはりサーバーを用意するのは敷居が高いですよね・・・
最後の方は力尽きてあまり丁寧に書けなかったので、適時追記をしていこうと思います。