python-3.xflaskslack-apislack-dialog

How can users upload images to a Slack app?


To provide context i have a Slack bot that allows users to create ads, i am able to use a dialog to fetch the listing title, description and price. What am looking for is a way to allow users to also add images.

The file.upload seems to allow the bot to upload files but what i want is lo be able to allow users to select the files locally and upload them, the bot will then be able to capture this and respond accordingly.

This is what i have so far

@app.route('/new', methods=['POST'])
def new_listing():

    # Get payload
    api_url = 'https://slack.com/api/dialog.open'

    trigger_id = request.form.get('trigger_id')

    dialog = {
        "callback_id": "marketplace",
        "title": "Create a new listing",
        "submit_label": "Create",
        "notify_on_cancel": True,
        "state": "Item",
        "elements": [
            {
                "type": "text",
                "label": "Listing Title",
                "name": "listing_title"
            },
            {
                "type": "text",
                "label": "Listing description",
                "name": "listing_description"
            },
            {
                "type": "text",
                "label": "Listing Price",
                "name": "listing_price"
            }
        ]
    }


    api_data = {
        "token": oauth_token,
        "trigger_id": trigger_id,
        "dialog": json.dumps(dialog)
    }

    res = requests.post(api_url, data=api_data)
    print(res.content)

    return make_response()

@app.route('/message_actions', methods=['POST'])
def message_actions():
    user_id = request.form['user']['id']

    submission = request.form['submission']
    title = submission['listing_title']
    description = submission['listing_description']
    price = submission['listing_price']

    # Add the listing to the database

    return make_response()

Solution

  • There is no straight forward approach, since the Slack API (currently) does not offer a filer picker.

    However, here are 3 workarounds to address this requirement:

    A - Image URLs

    Instead of uploading images to Slack directly, users only provide the URL of image hosted on the Internet (e.g. uploading to imgur.com). The image URL can be queried with a simple plain-text input field in your dialog.

    If you can expect your users to be tech savvy enough to handle image URLs and uploads to imgur.com (or other image hosters) I think think approach works pretty well.

    B - External web page

    You redirect users to an external web page of your app that has a file picker. That file picker allows uploading images from the user local machine to your app.

    This approach also works well. However users need to switch to a browser (and back to Slack again), so it can break the input flow a bit. It also is a lot more effort to implement, e.g. you need to maintain context between Slack and your web page in a secure way, which can be a challenge.

    C - Manual upload to Slack

    Users upload images manual to Slack, e.g. in the app channel. You app detects every image upload and asks them to which item of your app to attach it to.

    This approach allows you to stay within the Slack eco-system, but might be confusing for users and ensuring correct linking between user uploads and your items might be a challenge.

    P.S.: I had the same requirement with one of my Slack apps (Rafflebot) and went with approach A.