slackapi / java-slack-sdk

Slack Developer Kit (including Bolt for Java) for any JVM language
https://slack.dev/java-slack-sdk/
MIT License
568 stars 210 forks source link

files.upload v2 method does not upload multiple files with full metadata #1314

Closed oppokui closed 1 month ago

oppokui commented 1 month ago

I am in Bolt SDK 1.37.

I want to use client API to upload file like .png and .zip. I can manually upload files in Slack app, so suppose I can do it as well in client API. I find uploading .png file to a channel is simple and works well, but uploading a .zip file won't work. Firstly, I need to send the link to channel message, Secondly, I can't download the zip file (never complete). It sounds the file doesn't upload successfully. I use permal link, not sure it is ok. Any suggestion?

Slack website has many detailed explanations about the upload process, but never have a complete example code.

Screenshot from 2024-05-24 22-54-40

Here is my code:

package com.vitria.app.slack;

import com.google.gson.Gson;
import com.slack.api.Slack;
import com.slack.api.methods.MethodsClient;
import com.slack.api.methods.SlackApiException;
import com.slack.api.methods.request.chat.ChatPostMessageRequest;
import com.slack.api.methods.request.files.FilesUploadV2Request;
import com.slack.api.methods.response.chat.ChatPostMessageResponse;
import com.slack.api.methods.response.files.FilesUploadV2Response;
import com.slack.api.model.File;

import java.io.IOException;
import java.util.*;

public class UploadFile {

    public static void main(String[] args) throws Exception {

        String boltToken = System.getenv("SLACK_BOT_TOKEN");
        String channelID = "C072TGJAAA2";
        String name = "VIAOpsGenAI.zip";
        //String name = "chart-tmp-1716527653272.png";

        Map file = new HashMap();
        file.put("uuid", UUID.randomUUID().toString());
        file.put("name", name);
        file.put("desc", name);
        upload(boltToken, file, channelID);
    }

    public static void upload(String boltToken, Map fileMeta, String channelId) throws Exception {
        System.out.println("upload file to slack " + new Gson().toJson(fileMeta, Map.class));

        List<FilesUploadV2Request.UploadFile> uploadFiles = new ArrayList<>();
        String filename = (String) fileMeta.get("name");
        java.io.File file = new java.io.File(System.getProperty("java.io.tmpdir") + java.io.File.separator + filename);
        String desc = (String) fileMeta.get("desc");
        FilesUploadV2Request.UploadFile uploadFile = new FilesUploadV2Request.UploadFile();
        uploadFile.setFile(file);
        uploadFile.setFilename(filename);
        uploadFile.setTitle(filename);
        uploadFile.setAltTxt(desc);
        uploadFiles.add(uploadFile);
        MethodsClient methods = Slack.getInstance().methods(boltToken);

        FilesUploadV2Request request = FilesUploadV2Request.builder().uploadFiles(uploadFiles)
                .token(boltToken).channel(channelId).build();
        FilesUploadV2Response response = methods.filesUploadV2(request);

        if(response.isOk()) {
            Map result = new HashMap();
            List<File> files = response.getFiles();
            for(int i=0; i<files.size(); i++) {
                File slackFile = files.get(i);
                if(filename.endsWith(".zip")) {
                    String fileURL = slackFile.getPermalink();
                    sendToSlack(methods, channelId, fileURL);
                }
            }
        } else {
            throw new Exception("Fail to upload file, require " + response.getError() + "," + response.getNeeded());
        }
    }

    private static void sendToSlack(MethodsClient methods,
                                    String channelId, String fileURL) throws SlackApiException, IOException {

        ChatPostMessageRequest.ChatPostMessageRequestBuilder builder = ChatPostMessageRequest.builder()
                .channel(channelId).text(fileURL);
        ChatPostMessageRequest request = builder.build();
        ChatPostMessageResponse resp = methods.chatPostMessage(request);
        if(resp.isOk()) {
            System.out.println("Send response to " + channelId);
        } else {
            System.err.println("Fail to send response to " + channelId + ": " + resp.getError() + ", need: " + resp.getNeeded());
        }
    }
}
oppokui commented 1 month ago

@seratch do you know anything I am missing in the .zip upload process?

seratch commented 1 month ago

Hi @oppokui, thanks for asking the question. The following code works for me without any issues:

FilesUploadV2Response response = Slack.getInstance().methods(botToken).filesUploadV2(r -> r
  .file(new java.io.File("./test.zip"))
  .title("test.zip")
  .filename("test.zip")
  .channel(channelId)
  .initialComment("Here you are :wave:")
);

If your uploaded file is invalid, it could be caused by file access issue or data corruption. I hope you'll figure the cause out soon.

oppokui commented 1 month ago

Thanks, @seratch

Is it a bug of uploading multi files?

The following code doesn't work for .zip file (but works for .png file):

        FilesUploadV2Request.UploadFile uploadFile = new FilesUploadV2Request.UploadFile();
        uploadFile.setFile(file);
        uploadFile.setFilename(filename);
        uploadFile.setTitle(filename);
        uploadFile.setAltTxt(desc);
        uploadFiles.add(uploadFile);

        FilesUploadV2Request request = FilesUploadV2Request.builder().uploadFiles(uploadFiles)
                .token(boltToken).channel(channelId).build();

If I change to upload one file as you show in the example code, it works for .zip:

FilesUploadV2Request request = FilesUploadV2Request.builder().file(file).filename(filename)
                .title(filename)
                .token(boltToken).channel(channelId).build();
seratch commented 1 month ago

Ah I see. Since it’s Saturday for me, I will check the issue early next week. Thanks for reporting the issue and we’re sorry about the inconvenience.

oppokui commented 1 month ago

@seratch , no problem. Happy weekend!