i have created a slackbot with nodejs using @slack/bolt
.
i'm able to receive event in my nodejs server from slack whenever i tag with my slackapp and send textMessage or textMessage+Fileattachment. Please find the nodejs source code and output of the event object below.
The problem is, when i upload a file in slack, the event is received by my nodejs slack-bot
. (shown in below screenshot+view the event object details in the output attached below)
i'm not sure how to download the valid file using nodejs slack-bot. i have tried changing few parameters and settings but no success. The docs aren't helping me so far
Please help me out
Nodejs source code
const { App : BoltApp } = require('@slack/bolt');
const boltAppObj = new BoltApp({
token: constants.BOT_TOKEN,
appToken: constants.SLACK_APP_TOKEN,
socketMode: true,
scopes:["files:read","files:write"]
});
(async () => {
await boltAppObj.start();
console.log('⚡️ Bolt app started');
boltAppObj.event('app_mention', async ({ event, context, client, say }) => {
console.log("in app_mention")
console.log("event ",event)
try {
await say({"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `Thanks for the mention <@${event.user}>!`
}
}
]});
}
catch (error) {
console.error(error);
}
});
})();
Output
event {
type: 'app_mention',
text: '<@U01NJR8JNDQ> good morning have a nice day',
files: [
{
id: 'F01P0V0SC9X',
created: 1613713912,
timestamp: 1613713912,
name: 'hiddencloudvillage.png',
title: 'hiddencloudvillage.png',
mimetype: 'image/png',
filetype: 'png',
pretty_type: 'PNG',
user: 'U01NJPG7RGS',
editable: false,
size: 18207,
mode: 'hosted',
is_external: false,
external_type: '',
is_public: true,
public_url_shared: false,
display_as_bot: false,
username: '',
url_private: 'https://files.slack.com/files-pri/T01NC0NH1KQ-F01P0V0SC9X/hiddencloudvillage.png',
url_private_download: 'https://files.slack.com/files-pri/T01NC0NH1KQ-F01P0V0SC9X/download/hiddencloudvillage.png',
thumb_64: 'https://files.slack.com/files-tmb/T01NC0NH1KQ-F01P0V0SC9X-9f0babf31c/hiddencloudvillage_64.png',
thumb_80: 'https://files.slack.com/files-tmb/T01NC0NH1KQ-F01P0V0SC9X-9f0babf31c/hiddencloudvillage_80.png',
thumb_360: 'https://files.slack.com/files-tmb/T01NC0NH1KQ-F01P0V0SC9X-9f0babf31c/hiddencloudvillage_360.png',
thumb_360_w: 360,
thumb_360_h: 360,
thumb_480: 'https://files.slack.com/files-tmb/T01NC0NH1KQ-F01P0V0SC9X-9f0babf31c/hiddencloudvillage_480.png',
thumb_480_w: 480,
thumb_480_h: 480,
thumb_160: 'https://files.slack.com/files-tmb/T01NC0NH1KQ-F01P0V0SC9X-9f0babf31c/hiddencloudvillage_160.png',
original_w: 640,
original_h: 640,
thumb_tiny: 'AwAwADDToqtPfRRP5YDO/ooqP+0VU/vIZUHqRQBdoqCW7iiiV87g33Qveof7Q/6d5fyoAu0VS/tD/p3l/KpIL2OaTyyrI/YMOtAEb208U7y2zr85yysKRkvplKOYkU8HHNXqz9r3lzMplZEjOAq0AJLbtatbvGpkWPII7/Wp/t8X2fzcN97btxzmmf2ee1zN+dO+wR/Z/K3Nndu3d80AN/tFf+eEv5UwM95dROsTIkZyWYdafZvItxLbvIZAnIY9au0AFVprJJZPMVmjc9Sp61ZooApf2ef+fmb86P7PP/PzN+dXaKAIbe2S3UhMknqx6mpqKKAP/9k=',
permalink: 'https://pov-vtapbot.slack.com/files/U01NJPG7RGS/F01P0V0SC9X/hiddencloudvillage.png',
permalink_public: 'https://slack-files.com/T01NC0NH1KQ-F01P0V0SC9X-df55a3dc04',
is_starred: false,
has_rich_preview: false
}
],
upload: false,
blocks: [ { type: 'rich_text', block_id: 'ZecUF', elements: [Array] } ],
user: 'U01NJPG7RGS',
display_as_bot: false,
ts: '1613713934.000900',
channel: 'C01NXCJ2EN5',
event_ts: '1613713934.000900'
}
Script to download file using the url available in events object
const axios=require("axios");
const fs = require("fs")
const constants = require("./constants");
let url="https://files.slack.com/files-pri/T01NC0NH1KQ-F01N7CHRGF9/download/poc.xlsx";
const config = {
headers: { Authorization: `Bearer ${constants.SLACK_APP_TOKEN}` }
};
axios({
method: "GET",
url : url,
responseType: "stream",
headers : config.headers
}).then((result)=>{
console.log("result ")
result.data.pipe(fs.createWriteStream("./poc.xlsx"));
}).catch((err)=>{
console.log("err ");
})
BOT_TOKEN
is the appropriate token that has to be passed to the file download apiBOT_TOKEN
to the file download apiBelow is the logic to download the file that was uploaded in slack
const downloadFile= (url,filename)=>{
let fullFilePath = "";
const promise = new Promise((resolve,reject)=>{
const config = {
headers: { Authorization: `Bearer ${constants.BOT_TOKEN}` }
};
axios({
method: "GET",
url : url,
responseType: "stream",
headers : config.headers
}).then((result)=>{
const writeStream = fs.createWriteStream(fullFilePath);
result.data.on('data', (chunk) => {
writeStream.write(chunk);
});
result.data.on('end', function () {
writeStream.uncork();
writeStream.close();
writeStream.end();
console.log("completely ending the pipe");
});
writeStream.on('finish', () => {
resolve(fullFilePath);
});
// This is here incase any errors occur
writeStream.on('error', function (err) {
reject(err);
});
}).catch((err)=>{
reject(err);
});
});
return promise;
};
Below is the sample logic for nodejs-slackbot integration
const constants = require("./constants");
const { App : BoltApp } = require('@slack/bolt');
const utility = require("./utility");
const path = require("path");
const BOT_PORT = 3000;
const boltAppObj = new BoltApp({
token: constants.BOT_TOKEN,
signingSecret : constants.SLACK_SIGNING_SECRET,
});
const sendMessageToSlack= async (event,say,chatmessage)=>{
await say({
text: `Hey there <@${event.user}>! , ${chatmessage}`
});
}
(async () => {
await boltAppObj.start(BOT_PORT);
console.log('⚡️ Bolt app started');
boltAppObj.event('app_mention', async ({ event, context, client, say }) => {
const textMessage = event.text;
try{
const filePath = await utility.getLocalFilePath(event.files ? event.files : null);
sendMessageToSlack(event,say,"success");
}
catch(err){
sendMessageToSlack(event,say,"failed");
}
})
})();
Feel free to contact me if you are facing any issue related to this topic
Response to comment made by @ppp
Please verify if files:read
permission is present in the slackbot application which you have created on slack website