【问题标题】:Interactive response not shown on SlackSlack 上未显示交互式响应
【发布时间】:2019-06-24 16:13:44
【问题描述】:

我正在使用 Python 和 Flask 开发一个简单的 Slack 应用程序。 它应该使用包含按钮的消息响应斜杠命令。它会响应用户点击按钮。

问题是:交互消息请求的响应消息在点击按钮后没有发布到Slack频道。

详情

点击按钮后,我可以看到请求进入我的 Python 控制台,例如

127.0.0.1 - - [24/Jun/2019 17:30:09] "POST /interactive HTTP/1.1" 200 -

我可以在我的 ngrok 检查页面上看到我的应用响应此请求:

HTTP/1.0 200 OK    
Content-Type: application/json    
Content-Length: 25    
Server: Werkzeug/0.14.1 Python/3.7.0    
Date: Mon, 24 Jun 2019 15:41:57 GMT

{
  "text": "Hi there"
}

但响应消息不会显示在 Slack 上。 Slack 上也没有显示服务错误,因此 Slack 正在收到 200 OK 响应。

此外,如果我将交互式回复发送到 response_url,它也可以正常工作。仅仅尝试直接响应 HTTP 请求是不行的。

有趣的是,我使用完全相同的方法来响应斜杠命令和交互式请求。它适用于第一个,但不适用于后者。

设置

我在端口 8000 上的 Python 开发服务器上以调试模式运行我的应用程序。该服务器使用 ngrok 暴露给 Slack。 ngrok 将我的外部 URL 映射到 localhost:8000。该应用是从 Visual Studio Code 中启动的。

请求 URL 已正确配置到斜杠命令和交互操作的相应端点。

代码

import requests
from flask import Flask, json

app = Flask(__name__) #create the Flask app

@app.route('/slash', methods=['POST'])
def slash_response():                
    """ endpoint for receiving all slash command requests from Slack """

    # blocks defintion from message builder
    # converting from JSON to array
    blocks = json.loads("""[
        {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "Please select an option:",
                "emoji": true
            }
        },
        {
            "type": "actions",
            "elements": [
                {
                    "type": "button",
                    "text": {
                        "type": "plain_text",
                        "text": "Click me",
                        "emoji": true
                    },
                    "value": "button_1"
                }
            ]
        }
    ]""")

    # compose response message    
    response = {
        "blocks": blocks
    }

    ## convert response message into JSON and send back to Slack
    return json.jsonify(response)

@app.route('/interactive', methods=['POST'])
def interactive_response():                
    """ endpoint for receiving all interactivity requests from Slack """

    # compose response message    
    response = {
        "text": "Hi there"
    }

     ## convert response message into JSON and send back to Slack
    return json.jsonify(response)

if __name__ == '__main__':
    app.run(debug=True, port=8000) #run app in debug mode on port 8000

【问题讨论】:

    标签: python-3.x flask slack slack-api


    【解决方案1】:

    我在 Slack API 页面上找到了一个部分,它解释了您的交互式组件发生了什么!

    我将要介绍的所有内容都在官方文档的Responding to the interaction 部分。

    响应交互有两个步骤:

    1. 确认响应 - 在收到请求有效负载后 3 秒内将 OK 200 发送回 slack。您随此响应发送的文本不会改变当前松弛消息的内容。
    2. 组合响应 - 使用 POST 请求和它们在请求负载中打包的 response_url 将更新的消息发送到 slack。

    所以 OP 的代码不起作用的原因是 Slack 不再接受完整的消息作为对交互的直接响应。相反,所有响应消息都需要发送到response_url

    但是,为了实现向后兼容性,仍然可以直接响应包含附件的消息,但不能响应包含布局块的消息。

    代码

    这是我用来将原始按钮消息替换为文本“Hi Erik!”的代码

    import requests
    from flask import Flask, json, request
    
    app = Flask(__name__) #create the Flask app
    
    @app.route('/slash', methods=['POST'])
    def slash_response():                
        """ endpoint for receiving all slash command requests from Slack """
    
        # blocks defintion from message builder
        # converting from JSON to array
        blocks = json.loads("""[
            {
                "type": "section",
                "text": {
                    "type": "plain_text",
                    "text": "Please select an option:",
                    "emoji": true
                }
            },
            {
                "type": "actions",
                "elements": [
                    {
                        "type": "button",
                        "text": {
                            "type": "plain_text",
                            "text": "Click me",
                            "emoji": true
                        },
                        "value": "button_1"
                    }
                ]
            }
        ]""")
    
        # compose response message    
        response = {
            "blocks": blocks
        }
    
        ## convert response message into JSON and send back to Slack
        return json.jsonify(response)
    
    @app.route('/interactive', methods=['POST'])
    def interactive_response():                
        """ endpoint for receiving all interactivity requests from Slack """
        # compose response message   
        data = json.loads(request.form["payload"])
        response = {
            'text': 'Hi Erik!', 
            }
    
        requests.post(data['response_url'], json=response)
        return '' 
    
    
    if __name__ == '__main__':
        app.run(debug=True, port=8000) #run app in debug mode on port 8000
    

    【讨论】:

    • 如果您想以这种方式删除临时消息,您可以将响应更改为 response = { 'response_type': 'ephemeral', 'text': '', 'replace_original': 'true', 'delete_original':'true' }
    • 感谢您的努力。答案不是100%清楚,但您确实发现了问题。 Slack 不再接受完整的消息作为直接响应。相反,您必须将它们发送到response_url。我会将该信息添加到您的答案中以使其更清楚。
    猜你喜欢
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多