Open nobikin95 opened 4 weeks ago
Hi @nobikin95 - I noticed that the successful output has is_public: false
, and the channels array is empty. What was your output for the files.completeUploadExternal request? I just want to check here that you supplied the channel_id, otherwise the file will be private.
Hi @srajiang, output for the files.completeUploadExternal :
"ok": true,
"files": [
{
"id": "xxxxxxx",
"created": 1729847794,
"timestamp": 1729847794,
"name": "xxxxxxxxxxxxx.xxx",
"title": "xxxxxxxxxxx.xxx",
"mimetype": "",
"filetype": "",
"pretty_type": "",
"user": "xxxxxxxxx",
"user_team": "xxxxxxxxx",
"editable": false,
"size": 61652512,
"mode": "hosted",
"is_external": false,
"external_type": "",
"is_public": false,
"public_url_shared": false,
"display_as_bot": false,
"username": "",
"url_private": "https://files.slack.com/files-pri/XXXXXXXXXXXXX-XXXXXXXXXXX/xxxxxxxxxxxxxxxxx.xxx",
"url_private_download": "https://files.slack.com/files-pri/XXXXXXXXXXXXX-XXXXXXXXXXX/download/xxxxxxxxxxxxxxxxx.xxx",
"media_display_type": "unknown",
"permalink": "https://ikameglobal.slack.com/files/XXXXXXXXXXXXX/XXXXXXXXXXXXX/xxxxxxxxxxxxxxxxx.xxx",
"permalink_public": "https://slack-files.com/XXXXXXXXXXXXX-XXXXXXXXXXXXX-xxxxxxxxxx",
"comments_count": 0,
"is_starred": false,
"shares": {},
"channels": [],
"groups": [],
"ims": [],
"has_more_shares": false,
"has_rich_preview": false,
"file_access": "visible"
}
]
}
It seems like I'm having an issue with channel_id, here is the code I'm using:
#!/bin/bash
FILE_PATH=$1
CHANNEL_ID="XXXXXXXXXXX"
USER_TOKEN="xoxp-"
BOT_TOKEN="xoxb-"
# Check if the file exists
echo "Checking if file exists at: $FILE_PATH"
if [ ! -f "$FILE_PATH" ]; then
echo "Error: File $FILE_PATH does not exist!"
exit 1
fi
echo "File found at: $FILE_PATH"
# Get file size (use command compatible with macOS and Linux)
if [[ "$OSTYPE" == "darwin"* ]]; then
FILE_SIZE=$(stat -f%z "$FILE_PATH")
else
FILE_SIZE=$(stat -c%s "$FILE_PATH")
fi
# Step 1: Get upload URL using the files.getUploadURLExternal API
echo "Fetching upload URL from Slack API..."
UPLOAD_URL_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "filename=$(basename "$FILE_PATH")&length=$FILE_SIZE&channels=$CHANNEL_ID" \
https://slack.com/api/files.getUploadURLExternal)
# Log the response from the API
echo "Response from files.getUploadURLExternal: $UPLOAD_URL_RESPONSE"
# Extract upload URL and file_id from JSON response
UPLOAD_URL=$(echo "$UPLOAD_URL_RESPONSE" | grep -o '"upload_url":"[^"]*' | sed 's/"upload_url":"//g' | sed 's/\\//g')
FILE_ID=$(echo "$UPLOAD_URL_RESPONSE" | grep -o '"file_id":"[^"]*' | sed 's/"file_id":"//g')
# Check if the URL or file_id was not obtained
if [ -z "$UPLOAD_URL" ] || [ -z "$FILE_ID" ]; then
echo "Error: Failed to get upload URL or file_id"
exit 1
fi
echo "Upload URL: $UPLOAD_URL"
echo "File ID: $FILE_ID"
# Step 2: Upload the file to the obtained URL
echo "Uploading file to: $UPLOAD_URL"
UPLOAD_RESULT=$(curl -s -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary @"$FILE_PATH" \
"$UPLOAD_URL")
# Log the upload result
echo "Result of file upload: $UPLOAD_RESULT"
# Step 3: Complete the upload using the files.completeUploadExternal API
echo "Completing file upload with Slack API..."
COMPLETE_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "files=[{\"id\":\"$FILE_ID\"}]" \
--data-urlencode "channels=$CHANNEL_ID" \
https://slack.com/api/files.completeUploadExternal)
# Log the response from the files.completeUploadExternal API
echo "Response from files.completeUploadExternal: $COMPLETE_RESPONSE"
# Step 3.1: Share the public URL using the files.sharedPublicURL API
echo "Sharing file publicly using Slack API..."
SHARED_PUBLIC_URL_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "file=$FILE_ID" \
https://slack.com/api/files.sharedPublicURL)
# Log the response from the files.sharedPublicURL API
echo "Response from files.sharedPublicURL: $SHARED_PUBLIC_URL_RESPONSE"
# Extract URL from JSON response (use permalink instead of permalink_public)
PUBLIC_URL=$(echo "$SHARED_PUBLIC_URL_RESPONSE" | grep -o '"permalink_public":"[^"]*' | sed 's/"permalink_public":"//g' | sed 's/\\//g')
# Check if the URL was not obtained
if [ -z "$PUBLIC_URL" ]; then
echo "Error: Failed to get permalink URL"
exit 1
fi
echo "Public URL: $PUBLIC_URL"
# Step 4: Post a message to the channel with the uploaded file using chat.postMessage API
echo "Posting message to channel with uploaded file ..."
POST_MESSAGE_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
--data "$(cat <<EOF
{
"channel": "$CHANNEL_ID",
"text": "Build Success: <$PUBLIC_URL>",
"attachments": [
{
"title": "Click here to download",
"title_link": "$PUBLIC_URL",
"text": "The file is available for public download."
}
]
}
EOF
)" \
https://slack.com/api/chat.postMessage)
# Log the response from the chat.postMessage API
echo "Response from chat.postMessage: $POST_MESSAGE_RESPONSE"
The cause of your confusion may not be related to this, but the files.completeUploadExternal
API processes its tasks asynchronously. This means that if a subsequent operation attempts to download the uploaded file immediately, it might fail until the files.completeUploadExternal
operation completes. It appears that your code is trying to download the files right away. In most cases, this can fail regardless of whether the files are public or private.
One way to determine if the upload operation is finished is to check if the "shared" property is available in the file's metadata. You can verify this by polling the files.info
API with the uploaded file's ID.
I am trying to upload a file to a private Slack channel using the Slack API via the following Python script. However, once uploaded, the file cannot be downloaded by users in the channel. I am looking for help to understand why this is happening and how to resolve it.
Python runtime version
3.12.1
I used these step:
Actual result: