如何在Slack Bolt处理器中访问Flask Session?
解决Slack Bolt处理器中访问Flask Session的问题
问题根源在于:Slack Bolt的处理器函数默认不会继承Flask的请求上下文,即便SlackRequestHandler是在Flask路由内调用的,直接访问session仍会因脱离请求上下文而报错。以下是两种可行的解决方法:
方法一:通过线程本地存储传递请求对象
利用线程本地存储(每个请求对应独立线程)将Flask请求对象传递给Bolt处理器,再手动激活请求上下文操作session:
import threading from flask import Flask, request, session from flask_session import Session from slack_bolt import App from slack_bolt.adapter.flask import SlackRequestHandler import os flask_app = Flask(__name__) SESSION_TYPE = "filesystem" flask_app.config.from_object(__name__) Session(flask_app) # 创建线程本地存储对象,用于传递请求 local_storage = threading.local() bolt_app = App(token=os.environ['SLACK_TOKEN'], signing_secret=os.environ['SIGNING_SECRET']) handler = SlackRequestHandler(bolt_app) @flask_app.route('/route1', methods=['POST']) def route1(): # 将当前Flask请求存入线程本地存储 local_storage.flask_request = request # 修正原代码:session赋值需放在return之前,否则不会执行 session['test'] = 'value1' return handler.handle(request) @bolt_app.command('/route1') def handle_route1(body, ack, respond, client, logger): ack() # 从线程本地存储取出请求对象,激活请求上下文 flask_request = local_storage.flask_request with flask_app.request_context(flask_request): session['test'] = 'value2' logger.info(f"当前session值:{session.get('test')}")
方法二:通过Slack Bolt中间件注入请求对象
编写Bolt中间件,在请求处理流程中自动将Flask请求对象注入Bolt上下文,再在处理器中取出并激活上下文:
from flask import Flask, request, session from flask_session import Session from slack_bolt import App from slack_bolt.adapter.flask import SlackRequestHandler import os flask_app = Flask(__name__) SESSION_TYPE = "filesystem" flask_app.config.from_object(__name__) Session(flask_app) bolt_app = App(token=os.environ['SLACK_TOKEN'], signing_secret=os.environ['SIGNING_SECRET']) handler = SlackRequestHandler(bolt_app) # 定义中间件,将Flask请求对象注入Bolt上下文 def inject_flask_request(context, next): # 中间件在Flask请求上下文内执行,可直接获取request context["flask_request"] = request return next() # 注册中间件 bolt_app.use(inject_flask_request) @flask_app.route('/route1', methods=['POST']) def route1(): session['test'] = 'value1' return handler.handle(request) @bolt_app.command('/route1') def handle_route1(body, ack, respond, client, logger, context): ack() # 从Bolt上下文取出请求对象 flask_request = context.get("flask_request") if flask_request: with flask_app.request_context(flask_request): session['test'] = 'value2' logger.info(f"session已更新为:{session.get('test')}") else: logger.error("无法从Bolt上下文获取Flask请求对象")
注意事项
原代码中session['test'] = 'value1'写在return handler.handle(request)之后,这行代码永远不会被执行,需调整到return语句之前。
内容的提问来源于stack exchange,提问作者Ellen3424
相关产品推荐
相关产品推荐

