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
Don’t use
ResetTemplate
withspring boot 3.x
.WebClient
is the recommended for spring boot 3.
try with
LinkedMultiValueMap
like this.