skip to Main Content

I use Spring Boot 3.1, Telegram Bots Spring Boot Starter 6.7.0 and WebHook bot

I need to use class RestTemplate for call method /sendDocument in telegram API. I have read documentation telegram https://core.telegram.org/bots/api#senddocument and https://core.telegram.org/bots/api#sending-files, in my situation i need to send new binary pdf file.

I use next code:

public void sendNewPdfReport(Long chatId) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

    File file = null;
    try {
        file = ResourceUtils.getFile("classpath:reports/report.pdf");
    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    }
    InputFile inputFile = new InputFile(file);

    body.add("chat_id", chatId);
    body.add("document", inputFile);

    HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
    restTemplate.postForEntity("https://api.telegram.org/bot<myToken>/sendDocument", requestEntity, String.class);
}

When i call this code i get an error:

API Telegram: 400 Bad Request: "{"ok":false,"error_code":400,"description":"Bad Request: invalid file HTTP URL specified: Unsupported URL protocol"}"

2023-07-23 18:22:58,936 ERROR [http-nio-8088-exec-1] o.a.j.l.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "org.telegram.telegrambots.meta.api.objects.Message.getChatId()" because the return value of "org.telegram.telegrambots.meta.api.objects.Update.getMessage()" is null] with root cause

I don’t understand what the problem is. I fill in the fields as indicated in the documentation.

I rewrote the code without using RestTemplate:

public void sendNewPdfReport2Work(Long chatId) {
    String uri = "https://api.telegram.org/bot<myToken>/sendDocument";
    HttpPost httppost = new HttpPost(uri);
    InputFile inputFile = new InputFile(new File("report.pdf"));

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("chat_id", chatId.toString());
    builder.addBinaryBody(inputFile.getMediaName(), inputFile.getNewMediaFile(),
    ContentType.APPLICATION_OCTET_STREAM, inputFile.getMediaName());
    builder.addTextBody("document", inputFile.getAttachName());
    org.apache.http.HttpEntity multipart = builder.build();

    httppost.setEntity(multipart);
    CloseableHttpClient httpClient = HttpClients.createDefault();
    try {
        httpClient.execute(httppost);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

AND IT IS WORK! BUT … I need the code to work when using RestTemplate. I conclude that the problem is in the use of RestTemplate.

Help plz, How do I correctly use and configure RestTemplate to send binary files in /sendDocument telegram API

ok, I try with WebClient:

public void sendNewPdfReportWebClient(Long chatId) {
    WebClient webClient = WebClient.create(tgBotConfig.getTelegramApiUrl() + tgBotConfig.getBotToken());

    MultipartBodyBuilder builder = new MultipartBodyBuilder();
    builder.part("chat_id", chatId);
    try {
        builder.part("document", new InputFile(ResourceUtils.getFile("classpath:reports/report.pdf")));
    } catch (FileNotFoundException e) {
        throw new RuntimeException(e);
    }

    webClient.post()
            .uri(String.join("/sendDocument"))
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData(builder.build()))
            .exchangeToMono(response -> {
                if (response.statusCode().equals(HttpStatus.OK)) {
                    return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode());
                } else {
                    throw new ServiceException("Error uploading file");
                }
            })
            .block();
}

I have the next error:

Error uploading file
2023-07-24 23:33:55,572 ERROR [http-nio-8088-exec-5] o.a.j.l.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "org.telegram.telegrambots.meta.api.objects.Message.getText()" because "message" is null] with root cause
java.lang.NullPointerException: Cannot invoke "org.telegram.telegrambots.meta.api.objects.Message.getText()" because "message" is null

2

Answers


  1. Don’t use ResetTemplate with spring boot 3.x. WebClient
    is the recommended for spring boot 3.

    Login or Signup to reply.
  2. try with LinkedMultiValueMap like this.

    public void sendNewPdfReportWebClient(Long chatId) {
        WebClient webClient = WebClient.create(tgBotConfig.getTelegramApiUrl() + tgBotConfig.getBotToken());
    
        //** Create a MultiValueMap to hold the parts of the multipart form data
        MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    
        parts.add("chat_id", chatId);
        try {
            parts.add("document", new InputFile(ResourceUtils.getFile("classpath:reports/report.pdf")));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    
        webClient.post()
                .uri(String.join("/sendDocument"))
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(parts))
                .exchangeToMono(response -> {
                    if (response.statusCode().equals(HttpStatus.OK)) {
                        return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode());
                    } else {
                        throw new ServiceException("Error uploading file");
                    }
                })
                .block();
    }
    
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search