首页 > 解决方案 > 用于搜索外部数据源的 Slack 对话框

问题描述

我有几个关于松弛对话的问题。我开发了一个表格来完成和提交。一个字段正在使用外部数据源,我可以在下拉列表中看到选项。

为了进一步增强这一点,我想知道我们是否可以使用搜索功能,例如如果用户键入“abc”,它会显示在匹配“abc”的那些选项上。

我的另一个问题是,在相同的表单中,有多个字段,我们能否以这样一种方式配置对话框,即基于一个值,另一个选项集必须查询和更改。

请在这部分提供帮助。谢谢你。

当前使用的对话框 json:

    {
        "label": "ProjectName",
        "type": "select",
        "name": "prjname",
        "data_source": "external",
    "min_query_length":3
    },

标签: slackslack-apislack-dialog

解决方案


概念

搜索功能

每个带有外部源的选择菜单都旨在提供搜索功能。一旦用户至少输入了min_query_length字符,它就会自动开始匹配您的输入。但是,实际匹配必须由您的应用程序完成。Slack 将向您的应用程序发送用户输入的字符,并且您的应用程序需要使用匹配列表进行响应。如果正确实施,这将导致搜索功能。

提交前更新元素

用户必须在他的输入被注册并发送到您的应用程序之前单击“提交”。在用户提交之前无法获取元素的中间状态或更新它们。

示例代码

下面是一个示例,展示了如何为带有外部数据的动态菜单提供数据。该示例在 Python 中使用 Flask 和标准 Slackclient。

此示例将显示一个动态选择元素“City”。一旦用户在搜索字段中输入文本,城市列表就会根据用户输入进行动态过滤。例如“Li”将只显示“London”和“Lisabon”。

import os
import slack
from flask import Flask, json, request

app = Flask(__name__) #create the Flask app

@app.route('/slash', methods=['POST'])
def dialog_show():        
    """shows the dialog"""
    # define dialog
    dialog = {
        "callback_id": "ryde-46e2b0",
        "title": "Request a Ride",
        "submit_label": "Request",
        "notify_on_cancel": True,
        "state": "Limo",
        "elements": [
            {
                "type": "text",
                "label": "Pickup Location",
                "name": "loc_origin"
            },
            {
                "type": "text",
                "label": "Dropoff Location",
                "name": "loc_destination"
            },
            {
                "label": "City",
                "name": "city",
                "type": "select",
                "data_source": "external"
            }
        ]
    }

    # open the dialog
    client = slack.WebClient(token=os.environ['SLACK_TOKEN'])
    response = client.dialog_open(
        trigger_id=request.form.get('trigger_id'),
        dialog=json.dumps(dialog)
    )    
    assert response["ok"]

    return ""

@app.route('/interactive', methods=['POST'])
def dialog_submit():
    """handle dialog submission"""
    payload_json = request.form["payload"]    
    payload = json.loads(payload_json)
    print(payload)
    return ""

@app.route('/options_load', methods=['POST'])
def dialog_options_load():    
    """provide filtered list of options based on input for dialog"""
    payload_json = request.form["payload"]    
    payload = json.loads(payload_json)    

    # example list of all options
    cities = {
        "Berlin": 1,
        "Copenhagen": 2,        
        "Lisabon": 3,
        "London": 4,
        "Madrid": 5,
        "Oslo": 6,
        "Paris": 7,
        "Rom": 8,
        "Stockholm": 9
    }

    # find matching options
    # will match if user input string is in name
    options = list()
    for name, value in cities.items():
        if payload["value"] in name:
            options.append({
                "label": name,
                "value": value
            })

    # build response structure
    response = {
        "options": options
    }

    return json.jsonify(response)

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

推荐阅读