カテゴリー別アーカイブ: Web開発

AzureでSlackのOutgoing Webhooksを使って特定のキーワードに反応するbotをサクッと作る

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が動くようになります。

所感

「サクッと」という肩書きで記事を書きましたが、けっこう手順が煩雑ですね。本当に申し訳ない(

やはりサーバーを用意するのは敷居が高いですよね・・・

最後の方は力尽きてあまり丁寧に書けなかったので、適時追記をしていこうと思います。

Twitterの「いいね」から画像だけを抽出するWebサービス

AzureでのDjangoの練習も兼ねて作りました。

https://favorite-images.azurewebsites.net

機能としては、Twitterのいいねから画像が添付されているツイートだけを抽出してリスティングするだけです。

画像をまとめて見たい時、自分のプロフィールからツイートをたどるより便利ではないかと思います。

よければご利用ください・・・

bxsliderでスライドが1枚目から3枚目に飛ぶ

表題の通りです。bxslider、とても便利なのですが、以前から気になっていたので解決策を模索しました。

こちらに解決策が書いてありました。

https://github.com/stevenwanderski/bxslider-4/issues/902

cssに

.bx-viewport li { min-height: 1px; min-width: 1px; }
.bx-clone {display: none;}

を追加するとうまくいくようになります。素晴らしい!

【Web】FirefoxとSafariでinput dateのカレンダーが表示されない

普段はChromeで表示確認をしているのですが、確認作業でFirefoxやSafariでフォームのカレンダーが表示されない事がわかりました。

しばらく調べましたが、以下のスクリプトを読みこむようにすると解決するようです。

<script src="http://cdn.jsdelivr.net/webshim/1.12.4/extras/modernizr-custom.js"></script>
<!-- polyfiller file to detect and load polyfills -->
<script src="http://cdn.jsdelivr.net/webshim/1.12.4/polyfiller.js"></script>
<script>
  webshims.setOptions('waitReady', false);
  webshims.setOptions('forms-ext', {types: 'date'});
  webshims.polyfill('forms forms-ext');
</script>

中身で何をやっているか、詳しくは見ていませんが、CDNからwebshimsが提供するスクリプトを読み込んでいるようですね。

調べてみるとこれらはブラウザに欠けているUIなどの機能の代替を提供してくれるスクリプトらしいです。

ここではmodernizr-custom.jsという拡張ライブラリとpolyfiller.jsというポリフィルライブラリを読み込んでいますね。

これでカレンダーが表示されるようになりました。便利ですね〜