如何解决nodejs-slackbot - 下载的文件已损坏
我使用 @slack/bolt
创建了一个带有 nodejs 的 slackbot。
每当我用 slackapp 标记并发送 textMessage 或 textMessage+Fileattachment 时,我都能够从 slack 接收我的 nodejs 服务器中的事件。请在下面找到nodejs源代码和事件对象的输出。
问题是,当我在 slack 中上传文件时,我的 nodejs slack-bot
会收到该事件。 (显示在下面的屏幕截图中+在下面附加的输出中查看事件对象的详细信息)
- nodejs slack-bot 从事件对象中检索到上传文件的链接
- 我可以使用网络浏览器(例如谷歌浏览器)中的链接查看上传的文件。
- 当我使用链接通过 nodejs 代码下载文件时,文件被下载,但下载的文件已损坏
我不确定如何使用 nodejs slack-bot 下载有效文件。我曾尝试更改一些参数和设置,但没有成功。到目前为止,文档对我没有帮助
请帮帮我
Nodejs 源代码
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);
}
});
})();
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] } ],ts: '1613713934.000900',channel: 'C01NXCJ2EN5',event_ts: '1613713934.000900'
}
使用事件对象中可用的 url 下载文件的脚本
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 ");
})
解决方法
- 问题是由于传递给文件下载 api 的令牌类型所致
-
BOT_TOKEN
是必须传递给文件下载 api 的适当令牌 - 一旦我将
BOT_TOKEN
传递给文件下载 api,问题就得到解决
下面是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;
};
以下是nodejs-slackbot集成的示例逻辑
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,"success");
}
catch(err){
sendMessageToSlack(event,"failed");
}
})
})();
如果您遇到与此主题相关的任何问题,请随时与我联系
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。