slackapi / bolt-js

A framework to build Slack apps using JavaScript
https://tools.slack.dev/bolt-js/
MIT License
2.75k stars 393 forks source link

Downloading file-content when user upload a file/s in bot conversation. #2069

Closed Sudip-byte closed 8 months ago

Sudip-byte commented 8 months ago

I am using Bolt-JS SDK for my bot development.

I have a requirement, where user is prompted to upload a file based on which further communication will continue.

Now i want to read contents of that respective file. I need the knowledge on how to handle the file upload event or under which event shall I check in Bolt SDK in JavaScript.

Flow example goes like:

User: Hi Bot: Hello User. Good Day

User: I want to upload a file. Bot: Sure. Please upload the excel file.

User: Uploads file. ----> (I need to handle this event) Bot: Thank You.

Please suggest me a code solution or reference. I need something file_shared event or something similar. (Since I want to read the file contents) Thanks in advance.

zimeg commented 8 months ago

Hey @Sudip-byte! 👋 Downloading file contents can be a bit tricky but if your app has the right setup, should be possible with just the message event and the addition of a files:read scope using the url_private_download in a message.

This snippet can be used for retrieving contents from files shared to a channel:

app.message(async ({ context, event }) => {
    if (!event.files) {
        return;
    }
    const downloads = await Promise.all(event.files.map(async (file) => {
        const download = await fetch(file.url_private_download, {
            headers: {
                'Authorization': `Bearer ${context.botToken}`
            },
        });
        return download.text();
    }));
    console.log(downloads);
});

Including the bot token in this request is pretty important since files are restricted to a team by default. Hopefully this is helpful, but let me know if this doesn't seem to work for you!

Sudip-byte commented 8 months ago

Thanks @zimeg for your suggestion. Actually my requirement is a bit different.

I think this works well for text (.txt) files. My requirement here is that a excel (.xlsx) will be uploaded in the slack bot conversation. Then I need to extract the contents of file either in binary or in base64 and send to a different server for uploading.

zimeg commented 8 months ago

I think you can change the download.text() to possibly download.arrayBuffer() or .blob() instead? A few other typed options for the body are listed here, but ArrayBuffer should represent binary pretty well.

Sudip-byte commented 8 months ago

@zimeg Thanks a lot for your support in helping me with the solution. I was able to achieve my requirement with the solution that you mentioned above.

In addition to your above suggestion, I did some additional exploration and was able to achieve the same using the file_shared event and axios.

Regards, Sudip Rana