Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What sort of Stream is fileUploadV2 looking for? #2131

Open
cssinate opened this issue Dec 20, 2024 · 3 comments
Open

What sort of Stream is fileUploadV2 looking for? #2131

cssinate opened this issue Dec 20, 2024 · 3 comments
Labels
pkg:web-api applies to `@slack/web-api` question M-T: User needs support to use the project

Comments

@cssinate
Copy link

(Filling out the following with as much detail as you can provide will help us answer your question sooner.)

@slack/bolt version

4.1.1

Your App and Receiver Configuration

export const app = new App({
    token: SLACK_TOKEN, 
    signingSecret: SLACK_SIGNING_SECRET,
    socketMode: true,
    appToken: SLACK_SOCKET_TOKEN,
    logLevel: LogLevel.DEBUG
});

Node.js runtime version

20.13.1

Steps to reproduce:

I'm trying to create a bot to help run a hackathon; all of the pitching, team management, swag forms, and demo submissions, etc. I want teams to be able to upload a video into their private team channel, and when voting opens, the bot posts all of the videos in a public channel simultaneously. I'm having trouble doing that. Here's a minimal test with an MP4 file I uploaded.

  const fileInfo = await app.client.files.info({
    file: 'FXXXXXXXXXX',
    token: process.env.SLACK_BOT_TOKEN
  })
  const filePath = fileInfo.file!.url_private as string;
  const readableStream = await fetch(filePath).then(r => {
    if (!r.body) {
      throw new Error('Response body is null');
    }
    return Readable.from(r.body as any);
  });

  await app.client.filesUploadV2({
    channel_id: 'DXXXXXXXXXX',
    initial_comment: 'This is a test',
    file: readableStream,
    filename: fileInfo.file!.name as string,
  })

The file says it can accept a Stream, but when it posts this in the DM, it's a 56KB Binary file presented to the user. Visiting the filePath in a browser shows the MP4 as expected.

I fully recognize this could be a lack of understanding on my part with Readable Streams. I apologize if that's the sole issue at play.

Expected result:

I expect the readableStream passed into file to be given back in the same file format and size as the input file.

Actual result:

image
The file came back as a binary file.

Requirements

For general questions/issues about Slack API platform or its server-side, could you submit questions at https://my.slack.com/help/requests/new instead. 🙇

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

@zimeg zimeg added question M-T: User needs support to use the project and removed untriaged labels Dec 21, 2024
@zimeg zimeg transferred this issue from slackapi/bolt-js Jan 3, 2025
@zimeg zimeg added the pkg:web-api applies to `@slack/web-api` label Jan 3, 2025
@zimeg
Copy link
Member

zimeg commented Jan 3, 2025

Hey @cssinate 👋 Thanks for sharing this setup and question! 🎁

I'm moving this issue to the slackapi/node-slack-sdk since this is related to file uploads using @slack/web-api

The file says it can accept a Stream, but when it posts this in the DM, it's a 56KB Binary file presented to the user. Visiting the filePath in a browser shows the MP4 as expected.

A blob of binary data can sometimes be caused by unexpected data mixing with an unknown filetype and misleading file extension - meaning this confusion is super fair!

I believe the upload and readable stream are working as expected, but the data downloaded from url_private might be a page requesting authorization. To unlock this file download, a token will have to be included in the fetch call:

const readableStream = await fetch(fileInfo.file.url_private, {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SLACK_TOKEN}`,
  },
}).then((r) => {
  if (!r.body) {
    throw new Error('Response body is null');
  }
  return Readable.from(r.body);
});

This seems to download (then upload) a file uploaded by a user as long as the bot has been added to that channel and includes the files:read and files:write scopes!

I apologize for the delay in this response, but I hope this change downloads the files as expected. Please let me know if something else seems strange though 🙏

@cssinate
Copy link
Author

cssinate commented Jan 3, 2025

Thanks so much! This worked.

I have a quick follow-up request for confirmation... It seems that, even if a file is public across the workspace, a bot can't just re-share/forward that file to a DM. Is that accurate? The only way to send files in DMs is to always use the upload method and create new copies of the same file?

@seratch
Copy link
Member

seratch commented Jan 6, 2025

If you include the file's URL in a DM message, you can share the file again without uploading it again. If the file is visible to the recipient, Slack's UI should display the file preview.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:web-api applies to `@slack/web-api` question M-T: User needs support to use the project
Projects
None yet
Development

No branches or pull requests

3 participants