Reputation: 259
EDITED
I'm trying to structure the files.upload() API provided via Slack but am having a hard time understanding the correct format. At the moment, I am able to use the API to upload a text file but cannot for the life of me figure out how to upload an image.
Here's my issue: I have an image on my development server, let's call it image.png. I want to use the files.upload() API to post that image into a #general Slack channel. Below is the code I have that is successfully generating the image, but currently is just sending the text:
var myBarChart = new Chart(ctx).Bar(barChartData, barChartOptions);
var myBarChartDataURL = leaderboardBarChart.toBase64Image();
canvas.toBuffer(function(err, buf) {
if (err) throw err;
fs.writeFile(__dirname + "/leaderboard.png", buf);
});
bot.api.files.upload({
token: process.env.token,
title: "Image",
filename: "image.png",
filetype: "auto",
//content: "Posted with files.upload API",
file: fs.createReadStream("path/to/image_file.png"),
channels: filtered[0].id
}, function(err, response) {
if (err) {
console.log("Error (files.upload) " + err);
} else {
console.log("Success (files.upload) " + response);
};
});
When I run the code I get one of the following error:
"invalid_array_arg" which Slack details as: "The method was passed a PHP-style array argument (e.g. with a name like foo[7]). These are never valid with the Slack API."
I'm not entirely sure what to make of this error as I'm not using PHP nor anything that I can identify that would be PHP-like.
I've experimented with several different approaches for including the file path, whether using the 'fs' module, storing it in a variable, or just referencing it's absolute path (and even a relative path). I'm a bit lost and am just looking for some guidance.
I understand that this particular API uses multipart/form-data but I don't have a form. This app is strictly a NodeJS app. There is no framework (like Express) working in tandem with the main node script.
Any and all help is really appreciated. Again, just looking for some insight/guidance on what I'm missing or doing wrong.
Thanks in advance!
Upvotes: 11
Views: 11422
Reputation: 192
I recommend you using the nodejslack. It uses the Promises pattern, powered by Bluebird . There is a sample code for uploading file in its documentations, here it is:
var Slack = require('nodejslack');
var fs = require('fs');
var SLACK_TOKEN = process.env.SLACK_TOKEN || 'YOUR_GENERATED_SLACK_TOKEN';
var slack = new Slack(SLACK_TOKEN);
var form = {
file: fs.createReadStream('test.csv'), // Optional, via multipart/form-data. If omitting this parameter, you MUST submit content
// content: 'Your text here', // Optional, File contents. If omitting this parameter, you must provide a `file`
filename: 'test.csv', // Required
fileType: 'post', // Optional, See more file types in https://api.slack.com/types/file#file_types
title: 'Title of your file!', // Optional
initial_comment: 'First comment about this file.', // Optional
channels: 'general' //Optional, If you want to put more than one channel, separate using comma, example: 'general,random'
};
slack.fileUpload(form)
.then(function(response){
// Slack sends a json with a boolean var ok.
// Error example : data = { ok: false, error: 'user_not_found' }
// Error example : data = { ok: true, file: 'user_not_found' }
if(!response || !response.ok){
return Promise.reject(new Error('Something wrong happened during the upload.'));
}
console.log('Uploaded Successfully:',response);
return Promise.resolve(response);
})
.catch(function(err){
return err;
});
Upvotes: 1
Reputation: 60153
It looks like you'll have to go outside of Botkit's API here, since Botkit doesn't seem to support sending multipart/form-data
.
Give this a try, using request
directly (already in use by Botkit itself):
var request = require('request');
...
request.post({
url: 'https://slack.com/api/files.upload',
formData: {
token: bot.config.token,
title: "Image",
filename: "image.png",
filetype: "auto",
channels: filtered[0].id,
file: fs.createReadStream('test.png'),
},
}, function (err, response) {
console.log(JSON.parse(response.body));
});
Upvotes: 18