使用 NodeJS 的 Slack API (files.upload)

Posted

技术标签:

【中文标题】使用 NodeJS 的 Slack API (files.upload)【英文标题】:Slack API (files.upload) using NodeJS 【发布时间】:2016-06-28 19:12:23 【问题描述】:

已编辑

我正在尝试构建通过 Slack 提供的 files.upload() API,但我很难理解正确的格式。目前,我可以使用 API 上传文本文件,但我终生无法弄清楚如何上传图片。

这是我的问题:我的开发服务器上有一个图像,我们称之为 image.png。我想使用 files.upload() API 将该图像发布到#general Slack 频道。下面是我成功生成图像的代码,但目前只是发送文本:

        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);
          ;
        );

当我运行代码时,出现以下错误之一:

“invalid_array_arg”,其中 Slack 详细说明为:“该方法传递了一个 php 样式的数组参数(例如,名称类似于 foo[7])。这些对于 Slack API 永远无效。 "

我不完全确定这个错误是怎么回事,因为我没有使用 PHP,也没有使用任何我可以识别的类似 PHP 的东西。

我尝试了几种不同的方法来包含文件路径,无论是使用“fs”模块,将其存储在变量中,还是仅引用它的绝对路径(甚至是相对路径)。我有点迷茫,只是在寻找一些指导。

我了解此特定 API 使用 multipart/form-data 但我没有表单。这个应用程序严格来说是一个 NodeJS 应用程序。没有框架(如 Express)与主节点脚本协同工作。

非常感谢任何和所有帮助。再次,只是寻找一些关于我错过或做错了什么的见解/指导。

提前致谢!

【问题讨论】:

您能告诉我们bot.api 是什么吗?我只是根据变量名猜测,但也许你使用的是botkit? 如果它确实是 botkit,我认为 file: fs.createReadStream("path/to/image/file") 可能会成功。 (Botkit 使用request,它通过form-data 处理multipart/form-data)。 我正在使用botkit!我会试试看,谢谢你的建议! 当我这样做时,我不断收到错误消息“invalid_array_arg”。它与我生成图像的方式有什么关系吗? (见下文):canvas.toBuffer(function(err, buf) if (err) throw err; fs.writeFile(__dirname + "/image.png", buf); ); 你能用你当前的代码和你看到的错误的详细信息更新这个问题吗? 【参考方案1】:

看来您必须在此处脱离 Botkit 的 API,因为 Botkit 似乎不支持发送 multipart/form-data

试一试,直接使用request(Botkit 本身已经在使用):

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));
);

【讨论】:

对您的帮助我感激不尽。您建议的答案完美无缺。非常感谢,我真的很感激! 是否可以直接发送给用户而不是频道?我看到文档只谈论发送到频道 仅供参考...我刚刚得到了原始请求(使用 bot.api.files.upload)来工作。 Botkit v0.4.1 中似乎有一个修复程序。详情见github.com/howdyai/botkit/commit/… @dimirc 是的,用用户的ID作为频道,会直接在Slackbot频道上传给他【参考方案2】:

我建议您使用nodejslack。 它使用由 Bluebird 提供支持的 Promises 模式。 在其文档中有一个上传文件的示例代码,这里是:

    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;
    );

【讨论】:

以上是关于使用 NodeJS 的 Slack API (files.upload)的主要内容,如果未能解决你的问题,请参考以下文章

通过Slack API发送命令

在 Django 2.0 中使用 Slack RTM API

Slack RTM API 连接到多个服务器

如何从服务器使用 Slack API 进行身份验证

zapier 无法发送挑战值以启用 slack 事件 api

slack events api通过一条消息多次触发