slackapi / bolt-python

A framework to build Slack apps using Python
https://tools.slack.dev/bolt-python/
MIT License
1.06k stars 245 forks source link

How to post a snippet in a bot's direct message? #934

Closed samkit-jain closed 1 year ago

samkit-jain commented 1 year ago

I have created an app on the Slack platform using this SDK and am stuck with an issue in which I am unable to upload a file on my bot's "Messages" view with the user.

Reproducible in:

pip freeze | grep slack
python --version
sw_vers && uname -v # or `ver`

The slack_bolt version

slack-bolt==1.18.0 slack-sdk==3.21.3

Python runtime version

Python 3.10.6

OS info

Ubuntu 22.04.2 LTS

Steps to reproduce:

The code you can use to reproduce is

def ack_generic(ack):
    """Generic ack to respond within 3 seconds."""
    ack()

def run_action(body, client):
    main_user = body["user"]["id"]
    msg = "Hi"

    # This works and sends a message that is visible in the "Messages" section of the app.
    client.chat_postMessage(channel=main_user, text=msg)

    # This works but by only providing the DM ID that starts with D. I copied it from the URL of the Slack website.
    res = client.files_upload_v2(
        channel="D000000000000",
        content='{"key": "value"}',
        filename="policy.json",
        snippet_type="json",
        initial_comment=msg,
        title=msg,
    )

    # This gives a successful response but the message is nowhere to be found on the "Messages" tab.
    res = client.files_upload(
        channel=main_user,
        content='{"key": "value"}',
        filename="policy.json",
        filetype="json",
        initial_comment=msg,
        title=msg,
    )

    # This does not work and fails with the error:
    # The server responded with: {'ok': False, 'error': 'invalid_arguments', 'response_metadata': {'messages': ['[ERROR] input must match regex pattern: ^[CGD][A-Z0-9]{8,}$ [json-pointer:/channel_id]']}}
    res = client.files_upload_v2(
        channel=main_user,
        content='{"key": "value"}',
        filename="policy.json",
        snippet_type="json",
        initial_comment=msg,
        title=msg,
    )

app.action("my-action")(ack=ack_generic, lazy=[run_action])
  1. Why is files_upload not resulting in the message being shown on the app's direct message tab even though passing main_user as the channel for posting a message is working and it is even giving a successful response?
  2. How can I get the DM ID (starting with D) for my app so that files_upload_v2 can work?

Expected result:

I expected the snippet to be shared.

Actual result:

Snippet wasn't shared.

seratch commented 1 year ago

Hi @samkit-jain, thanks for writing in.

Why is files_upload not resulting in the message being shown on the app's direct message tab even though passing main_user as the channel for posting a message is working and it is even giving a successful response?

I understand this could be confusing, but the argument key for legacy files.upload method needs to be channels, not channel. That being said, we no longer recommend using this legacy one. Please consider using only the v2 method.

How can I get the DM ID (starting with D) for my app so that files_upload_v2 can work?

You can perform conversations.open API call to get the ID. while it's not yet open, the API starts a new DM and returns its ID. If the DM is already open, the API just returns the ID.

I hope this was helpful to you.

samkit-jain commented 1 year ago

Hi @seratch Appreciate the quick and helpful response. Thanks, I am using the conversations.open API now. Could you please also tell me why files_upload_v2 does not work with the user ID? All the examples on the https://slack.dev/bolt-python/concepts#basic use the user value for the channel attribute and it works great and it not working with the v2 confused me.

I am also closing the issue now as the core issue has been answered.

seratch commented 1 year ago

Only a small number of long-lived APIs such as chat.postMessage can accept both a channel ID and a user ID for channel parameter. After a while, Slack's platfom decided not to add the same support for newer APIs to avoid extra overhead to look up the channel ID associated with a passed user ID. I hear you that this could be confusing but now we generally recommend always passing a channel ID.

Thanks again for asking the question. I hope you'll enjoy deploping with Slack's platform!