1

I'm currently working on a Python Slack bot and I've encountered an issue with sharing attachments across channels. My goal is to have any texts and attachments sent by a student in channel A automatically shared in another channel. However, the payload I receive when a student sends texts and attachments in channel A contains the fields url_private and public_permalink.

I have attempted to use the files.sharedPublicURL method by following the example provided in files.sharedPublic Test. My intention was to generate a public link and share it by providing the correct user token with the necessary scopes. In the files field, I supplied the file_id parameter. However, I am consistently encountering the following error:

{
    "ok": false,
    "error": "not_allowed"
}

Alternatively, if I directly use public_permalink in the block structure, I receive the following error:

{'ok': False, 'error': 'invalid_blocks', 'errors': ['downloading image failed [json-pointer:/blocks/1/image_url]'], 'response_metadata': {'messages': ['[ERROR] downloading image failed [json-pointer:/blocks/1/image_url]']}}

I would greatly appreciate any advice or help on this matter. Thank you in advance!

Dummy Cron
  • 143
  • 2
  • 11

1 Answers1

1

In docs for files.sharedPublicURL method there is description of an error you provided:

not_allowed

Public sharing has been disabled for this team. You may see this error if you are creating an external link from a free or trial workspace. You can either upgrade to a Paid Plan or use file.list to get a url_private_download link, download the file with an application, and re-upload it somewhere it can be shared with users who are not members of your workspace. Be sure to pass the Slack Bot token to the request on the headers file when calling url_private_download.

So, I suppose you getting this error because you use free plan, where the file sharing feature is unavailable, or you use paid plan and disabled this feature in settings.

Also, files.sharedPublicURL is only available for a user token with scope files:write.

So, in a paid workspace, with Workspace Settings -> Permissions -> Public File Sharing -> "Enable public file URL creation" turned on, an application with following user token scopes: files:write, files:read, chat:write will work:

import logging

from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

log = logging.getLogger(__name__)

PRIVATE_CHANNEL_ID = "C**"
PUBLIC_CHANNEL_ID = "C**"
USER_TOKEN = 'xoxp-**'
# BOT_TOKEN = 'xoxb-**')


if __name__ == "__main__":
    client = WebClient(token=USER_TOKEN)
    try:
        upload_result = client.files_upload_v2(channel=PRIVATE_CHANNEL_ID, file='test.txt')
        print(upload_result)

        public_url_result = client.files_sharedPublicURL(file=upload_result.get('file').get('id'))
        print(public_url_result)

        file_info_result = client.files_info(file=upload_result.get('file').get('id'))
        print(file_info_result)

        if file_info_result.get('file').get('public_url_shared'):
            file_public_url = file_info_result.get('file').get('permalink_public')
            # OR file_public_url = public_url_result.get('file').get('permalink_public')

            message_post_result = client.chat_postMessage(channel=PUBLIC_CHANNEL_ID, text=file_public_url)
            print(message_post_result)
    except SlackApiError as e:
        logging.exception(f"Error occurred: {e.response['error']}")

Ensure also you are calling client.files_upload/client.files_upload_v2 and files_sharedPublicURL with the same user token client, because if the file was uploaded with bot token but shared with user token, the error file_not_found will occur.

File upload into private channel works if bot or user is a member of this channel.

Also note, the permalink_public returns a link to a some sort of file web page, but not a direct link to a file, I suppose this is some sort of feature, and so this would not work in block as you described. Found an answer about this here https://stackoverflow.com/a/57254520/1308939 however not sure this will work.

Vadym Nekhai
  • 131
  • 5
  • So for freeplan I will have use url_private_download to access the files and share it across, right? – Dummy Cron Jul 06 '23 at 09:32
  • Potentially, yes, this could be vaild, if user has an access to a channel where the file is shared and they are authorized in Slack (i.e. logged in browser client), you could drop them a private and private direct links for a download. If they are not logged in or not a member of the channel where the file is shared, Slack could deny in downloading and viewing file content, and if the file shared in public channel only Slack login required. Please see https://api.slack.com/types/file#auth for details as how some fields works. Same for permalinks https://api.slack.com/types/file#permalinks – Vadym Nekhai Jul 06 '23 at 20:45