I'm trying to upload an image via Slack using node.js and the request package, but not having much luck. Either I receive invalid_array_arg
or no_file_data
errors from the API.
Here is my request:
var options = { method: 'POST',
url: 'https://slack.com/api/files.upload',
headers:
{ 'cache-control': 'no-cache',
'content-type': 'application/x-www-form-urlencoded' },
form:
{ token: SLACK_TOKEN,
channels: SLACK_CHANNEL,
file: fs.createReadStream(filepath)
} };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
I had a look at a few relevant posts:
The only thing that worked was using the curl command directly, but using cygwin (CommandPrompt failed: curl: (1) Protocol https not supported or disabled in libcurl
). The issue calling curl from node (using child_process
) but that silently fails in Command Prompt and still returns no_file_data
using cygwin (passing an absolute path to the file):
stdout: {"ok":false,"error":"no_file_data"}
stderr: % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 469 100 35 100 434 359 4461 --:--:-- --:--:-- --:--:-- 6112
I'm using node v6.9.1 on Windows.
What am I missing ? How can I upload an image to slack via node.js on Windows ?
The Slack API error invalid_array_arg
means that there is a problem with the format of the arguments passed to Slack. (see here)
When using the file
property for files.upload
, Slack excepts the data as multipart/form-data
, not as application/x-www-form-urlencoded
. So instead of form
, you need to use formData
in your request object. I also removed the incorrect part in the header.
This works:
var fs = require('fs');
var request = require('request');
var SLACK_TOKEN = "xoxp-xxx";
var SLACK_CHANNEL = "general";
var filepath = "file.txt";
var options = { method: 'POST',
url: 'https://slack.com/api/files.upload',
headers:
{ 'cache-control': 'no-cache' },
formData:
{ token: SLACK_TOKEN,
channels: SLACK_CHANNEL,
file: fs.createReadStream(filepath)
} };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});