Reputation: 15795
I've been searching a lot and I haven't found an answer to what I'm looking for.
I'm trying to upload a file from /tmp
to slack using python requests but I keep getting {"ok":false,"error":"no_file_data"}
returned.
file={'file':('/tmp/myfile.pdf', open('/tmp/myfile.pdf', 'rb'), 'pdf')}
payload={
"filename":"myfile.pdf",
"token":token,
"channels":['#random'],
"media":file
}
r=requests.post("https://slack.com/api/files.upload", params=payload)
Mostly trying to follow the advice posted here
Upvotes: 11
Views: 36034
Reputation: 1836
Writing this post, to potentially save you all the time I've wasted. I did try to create a new file and upload it to Slack, without actually creating a file (just having it's content). Because of various and not on point errors from the Slack API I wasted few hours to find out that in the end, I had good code from the beginning and simply missed a bot in the channel.
This code can be used also to open an existing file, get it's content, modify and upload it to Slack.
from io import StringIO # this library will allow us to
# get a csv content, without actually creating a file.
sio = StringIO()
df.to_csv(sio) # save dataframe to CSV
csv_content = sio.getvalue()
filename = 'some_data.csv'
token=os.environ.get("SLACK_BOT_TOKEN")
url = "https://slack.com/api/files.upload"
request_data = {
'channels': 'C123456', # somehow required if you want to share the file
# it will still be uploaded to the Slack servers and you will get the link back
'content': csv_content, # required
'filename': filename, # required
'filetype': 'csv', # helpful :)
'initial_comment': comment, # optional
'text': 'File uploaded', # optional
'title': filename, # optional
#'token': token, # Don't bother - it won't work. Send a header instead (example below).
}
headers = {
'Authorization': f"Bearer {token}",
}
response = requests.post(
url, data=request_data, headers=headers
)
I just had a worst experience (probably of this year) with Slack's file.upload documentation. I think that might be useful for you in the future.
Things that were not working in the docs:
token
- it cannot be a param of the post request, it must be a header. This was said in one of github bug reports by actual Slack employee.channel_not_found
- I did provide an existing, correct channel ID and got this message. This is somehow OK, because of security reasons (obfuscation), but why there is this error message then: not_in_channel
- Authenticated user is not in the channel.
After adding bot to the channel everything worked.content
param (that's why I am sharing my code with you.The main issue is they do not version their API, change it and do not update docs, so many statements in the docs are false/outdated.
Upvotes: 5
Reputation: 1057
Base on the Slack API file.upload documentation What you need to have are:
- Token : Authentication token bearing required scopes.
- Channel ID : Channel to upload the file
- File : File to upload
Here is the sample code. I am using WebClient method in @slack/web-api package to upload it in slack channel.
import { createReadStream } from 'fs';
import { WebClient } from '@slack/web-api';
const token = 'token'
const channelId = 'channelID'
const web = new WebClient(token);
const uploadFileToSlack = async () => {
await web.files.upload({
filename: 'fileName',
file: createReadStream('path/file'),
channels: channelId,
});
}
Upvotes: 0
Reputation: 543
Sending files through http requires a bit more extra work than sending other data. You have to set content type and fetch the file and all that, so you can't just include it in the payload
parameter in requests.
You have to give your file information to the files
parameter of the .post
method so that it can add all the file transfer information to the request.
my_file = {
'file' : ('/tmp/myfile.pdf', open('/tmp/myfile.pdf', 'rb'), 'pdf')
}
payload={
"filename":"myfile.pdf",
"token":token,
"channels":['#random'],
}
r = requests.post("https://slack.com/api/files.upload", params=payload, files=my_file)
Upvotes: 31