Bagaimana cara mengunggah gambar ke Slack menggunakan node.js di Windows?

Saya mencoba mengunggah gambar melalui Slack menggunakan node.js dan paket permintaan, tetapi tidak memiliki banyak keberuntungan. Entah saya menerima kesalahan invalid_array_arg atau no_file_data dari API.

Ini permintaan saya:

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

Saya telah melihat beberapa posting yang relevan:

Satu-satunya hal yang berhasil adalah menggunakan perintah curl secara langsung, tetapi menggunakan cygwin (CommandPrompt gagal: curl: (1) Protocol https not supported or disabled in libcurl). Masalah memanggil curl dari node (menggunakan child_process) tetapi gagal secara diam-diam di Command Prompt dan masih mengembalikan no_file_data menggunakan cygwin (melewati jalur absolut ke 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

Saya menggunakan node v6.9.1 di Windows.

Apa yang saya lewatkan? Bagaimana cara mengunggah gambar ke slack melalui node.js di Windows?


person George Profenza    schedule 06.02.2018    source sumber
comment
Saya tahu ini bukan jawaban untuk pertanyaan Anda, mungkin Anda harus mempertimbangkan untuk menggunakan node-slack-sdk /, dalam hal ini Anda tidak perlu mengimplementasikan sendiri fitur ini. dokumentasi pengunggahan file   -  person Peter    schedule 07.02.2018
comment
@Peter secara mengejutkan mendapatkan kesalahan yang sama dengan node-slack-sdk:error: Response not OK: no_file_data Error: no_file_data   -  person George Profenza    schedule 07.02.2018
comment
@GeorgeProfenza caranya adalah files.upload.   -  person Erik Kalkoken    schedule 07.02.2018
comment
mengapa solusi dari pertanyaan tertaut #2 Anda tidak berhasil? (stackoverflow.com/questions/38084459/) sudahkah Anda mencoba mereproduksi dengan sintaks yang sama?   -  person Erik Kalkoken    schedule 07.02.2018
comment
Kemungkinan duplikat Slack API (files.upload) menggunakan NodeJS   -  person Erik Kalkoken    schedule 07.02.2018
comment
apa yang fs.createReadStream(filepath).stat() katakan?   -  person Peter    schedule 07.02.2018
comment
lagipula ini juga terlihat relevan.   -  person Peter    schedule 07.02.2018
comment
@Peter console.log(fs.createReadStream(filename).stat()); ^ TypeError: fs.createReadStream(...).stat is not a function   -  person George Profenza    schedule 07.02.2018
comment
@ErikKalkoken Saya telah menyebutkan dalam pertanyaan saya, saya sudah memeriksa pertanyaan yang Anda tandai sebagai duplikat. Saya akui mereka sangat mirip, tetapi solusinya tidak berhasil dalam kasus saya. Meskipun error pada akhirnya sama, namun sumber errornya mungkin berbeda.   -  person George Profenza    schedule 07.02.2018
comment
Bagaimana kalau mencoba contoh skrip ini? gist.github.com/tanaikech/40c9284e91d209356395b43022ffc5cc Di lingkungan saya, skrip Anda juga mengalami kesalahan yang sama . Jadi saya membuat ini. Jika ini tidak berguna bagi Anda, saya minta maaf.   -  person Tanaike    schedule 07.02.2018
comment
@Tanaike, tajuk multibagian eksplisit pertama berfungsi dengan baik! Anda juga harus memposting ini sebagai jawaban: ini sangat berguna! Terima kasih banyak   -  person George Profenza    schedule 08.02.2018
comment
Terimakasih atas balasan anda. Saya senang ini bermanfaat bagi Anda. Saya memposting skrip ini. Mohon konfirmasinya.   -  person Tanaike    schedule 09.02.2018
comment
Jika Anda mempunyai masalah dengan contoh skrip saya, tolong beri tahu saya. Saya ingin belajar dari permasalahan tersebut.   -  person Tanaike    schedule 11.02.2018
comment
@Tanaike Saya harap saya bisa memberi Anda lebih dari satu suara. Kedua solusi tersebut berhasil! Sementara itu, saya telah menjalankan lebih banyak tes dan menemukan masalahnya: Saya mencoba mengunggah gambar sebelum gambar tersebut sepenuhnya ditulis ke disk. Setelah saya memastikan file telah ditulis sepenuhnya ke disk, metode kedua juga berfungsi. Yang menarik adalah metode pertama Anda, membuat header multibagian secara manual, tetap berfungsi bahkan ketika gambar tidak sepenuhnya ditulis ke disk: metode ini hanya menampilkan piksel abu-abu untuk data yang hilang.   -  person George Profenza    schedule 16.02.2018
comment
Terima kasih atas informasi tambahan Anda. Saya senang masalah Anda terpecahkan. Dan saya juga bisa belajar dari pertanyaan Anda. Terima kasih kembali.   -  person Tanaike    schedule 17.02.2018
comment
Hai @GeorgeProfenza, saya mengalami kesalahan yang sama dan saya bertanya-tanya bagaimana Anda memastikan bahwa gambar Anda sepenuhnya ditulis ke disk. Anda bilang saya mencoba mengunggah gambar sebelum sepenuhnya ditulis ke disk. Setelah saya memastikan file sepenuhnya ditulis ke disk, metode tersebut berfungsi. Saya mencoba mengirim PDF dan bukan gambar, tetapi saya mendapatkan kesalahan yang sama dan saya merasa alasannya sama   -  person Carol Gonzalez    schedule 17.09.2019
comment
@CarolGonzalez Dalam kasus saya, saya mengunduh beberapa gambar, menggunakan sihir grafis untuk membuat montase, lalu mengunggah hasilnya, jadi dalam kasus saya memulai proses pengunggahan dari acara 'close' gm. Dalam kasus Anda, mungkin pendengar tersedia ketika file pdf selesai ditulis ke disk. Sebagai bukti konsep, Anda dapat mencoba hacky setTimeout hingga 10 detik atau lebih (jika PDF tidak besar) untuk mengisolasi masalah dan mengonfirmasi bahwa itu adalah masalah yang sama. Jika itu masalahnya, idealnya Anda akan menghapus penundaan peretasan dan menggunakan acara yang benar. Maaf atas keterlambatan pengembalian.   -  person George Profenza    schedule 19.09.2019


Jawaban (2)


Kesalahan Slack API invalid_array_arg berarti ada masalah dengan format argumen yang diteruskan ke Slack. (lihat di sini)

Saat menggunakan properti file untuk files.upload, Slack mengecualikan data sebagai multipart/form-data, bukan sebagai application/x-www-form-urlencoded. Jadi, alih-alih form, Anda perlu menggunakan formData di objek permintaan Anda. Saya juga menghapus bagian yang salah di header.

Ini bekerja:

      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);
    });
person Erik Kalkoken    schedule 07.02.2018
comment
Terima kasih atas jawaban Anda. Saya sudah mencoba menggunakan formData seperti yang Anda sarankan di atas, sayangnya saya mendapatkan kesalahan yang sama. Saya akan menjalankan beberapa tes lagi. Mungkin data yang saya upload belum siap? - person George Profenza; 08.02.2018
comment
@GeorgeProfenza Kode ini telah diuji dan berfungsi. Saya telah menambahkan inisialisasi hanya untuk memastikan. Sudahkah Anda mencoba kode persis ini? Dan tolong beri tahu saya kesalahan apa yang sebenarnya Anda dapatkan dari API. - person Erik Kalkoken; 08.02.2018
comment
Mohon maaf atas keterlambatannya. Saya melakukan beberapa tes lebih lanjut dan menemukan sumber masalahnya: bukan permintaan itu sendiri, tetapi data dan hasil createReadStream. Saya tidak menunggu gambar yang saya unggah sepenuhnya ditulis ke disk sebelum diunggah. Itu sudah diperbaiki sekarang dan kode Anda serta kode Tanaike berfungsi. Hal yang menarik tentang pendekatan multipart manualnya adalah pendekatan ini berfungsi bahkan ketika jpeg tidak sepenuhnya ditulis ke disk (menampilkan jpeg pada dimensi yang benar dengan sebagian kecil piksel abu-abu) - person George Profenza; 16.02.2018

Dalam contoh skrip ini, seharusnya mengunggah file biner (file zip). Saat Anda menggunakan ini, harap modifikasi sesuai lingkungan Anda. Saat file diunggah ke Slack, multipart/form-data digunakan. Di lingkungan saya, ada situasi dimana file tidak dapat diunggah oleh beberapa perpustakaan. Jadi saya membuat ini. Jika ini bermanfaat bagi lingkungan Anda, saya senang.

Pengguna dapat mengunggah file biner dengan mengonversi array byte sebagai berikut.

  • Pada awalnya, ia membangun data formulir.
  • Menambahkan file zip yang dikonversi ke array byte dan batas menggunakan Buffer.concat().
  • Ini digunakan sebagai isi permintaan.

Contoh skripnya adalah sebagai berikut.

Contoh skrip:

var fs = require('fs');
var request = require('request');
var upfile = 'sample.zip';
fs.readFile(upfile, function(err, content){
    if(err){
        console.error(err);
    }
    var metadata = {
        token: "### access token ###",
        channels: "sample",
        filename: "samplefilename",
        title: "sampletitle",
    };
    var url = "https://slack.com/api/files.upload";
    var boundary = "xxxxxxxxxx";
    var data = "";
    for(var i in metadata) {
        if ({}.hasOwnProperty.call(metadata, i)) {
            data += "--" + boundary + "\r\n";
            data += "Content-Disposition: form-data; name=\"" + i + "\"; \r\n\r\n" + metadata[i] + "\r\n";
        }
    };
    data += "--" + boundary + "\r\n";
    data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + upfile + "\"\r\n";
    data += "Content-Type:application/octet-stream\r\n\r\n";
    var payload = Buffer.concat([
            Buffer.from(data, "utf8"),
            new Buffer(content, 'binary'),
            Buffer.from("\r\n--" + boundary + "\r\n", "utf8"),
    ]);
    var options = {
        method: 'post',
        url: url,
        headers: {"Content-Type": "multipart/form-data; boundary=" + boundary},
        body: payload,
    };
    request(options, function(error, response, body) {
        console.log(body);
    });
});
person Tanaike    schedule 08.02.2018