LoginSignup
3
1

More than 1 year has passed since last update.

Vue.js / FlaskアプリにSlack for boltを組み込むには

Posted at

フロントエンドをVue.js
バックエンドをFlask(python)
で作っているWebアプリを書いているのですが、そこにSlack botを組み込む必要がありました。
せっかくpythonで書いているので、slack bolt for pythonを使えば簡単にかけるはずです。
https://github.com/SlackAPI/bolt-python

このboltなのですが、 @seratch さんの尽力もあって、Flask用のexampleも書いてあるのです。ありがたや。
https://github.com/slackapi/bolt-python/tree/main/examples/flask

コード自体はそこに書いてあるとおりに書けば良いのですが、今回はもともと作っていたアプリに組み込みたい。そうなると、このままでは書けません。

イメージとしてはここにあるようなものです。
https://qiita.com/y-tsutsu/items/67f71fc8430a199a3efd

backend/main.py
from flask import Flask, render_template

app = Flask(__name__, static_folder='../frontend/dist/static', template_folder='../frontend/dist')

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
    return render_template('index.html')

if __name__ == '__main__':
    app.run()

こんな風になっているので、そこに組み込みましょう。

backend/main.py
from flask import Flask, render_template

app = Flask(__name__, static_folder='../frontend/dist/static', template_folder='../frontend/dist')

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
    return render_template('index.html')

from .bolt import bolt as bolt_blueprint
app.register_blueprint(bolt_blueprint)

if __name__ == '__main__':
    app.run()

bolt用のファイルは、別に分けたいのでblueprintで分割します。
新規に作るファイルはbackend/bolt.pyにします。

backend/bolt.py
import logging
logging.basicConfig(level=logging.DEBUG)

from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler

import os

bolt_app = App(
    token=os.environ.get("SLACK_BOT_TOKEN"),
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)

@bolt_app.event("app_mention")
def event_test(body, say, logger):
    logger.info(body)
    say("What's up?")


@bolt_app.event("message")
def handle_message():
    pass

handler = SlackRequestHandler(bolt_app)

bolt =  Blueprint('bolt', __name__)

@bolt.route("/slack/events", methods=["POST"])
def slack_events():
    return handler.handle(request)

こんな形になります。
blueprintで切り出してbolt.py側に持っていきます。
実はここでめちゃくちゃハマったのですが、ハマりどころがどこだったかというと
flask_app = Flask(__name__)
handler = SlackRequestHandler(app)

この二行ですね。
SlackRequestHandlerに入れるのはflask_appじゃないのです。
slack_boltで生成したappインスタンスなので注意してください。

handler = SlackRequestHandler(app)
flask_app = Flask(__name__)

こんな風に逆に書いてあったほうが勘違いしないかもしれない。

@bolt としたものは、main.pyから呼んだflaskのインスタンスです。
こいつを使ってrouteに設定した/slack/eventsに通ってきたリクエストをhandlerを通じてbolt側に渡して処理する形になっています。

処理の流れが分かってしまえば、理解しやすいのですが、初学者だとtypoに気付くのが辛いかもしれません。
どなたかの理解につながれば幸いです。

3
1
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
3
1