CompletableFuture support
This commit is contained in:
parent
447c9d3f92
commit
fb5626de7a
@ -6,6 +6,7 @@
|
||||
5. Locations now use Double instead of Float to avoid rounding.
|
||||
6. When registering a Webhook Bot, a SetWebhook object must be provided.
|
||||
7. When using Webhook with Spring, extends class SpringWebhookBot instead of WebhookBot
|
||||
8. New Async methods returning CompletableFutures.
|
||||
|
||||
### <a id="4.9.2"></a>4.9.2 ###
|
||||
1. Bug fixing: #792, #801, #804, #810, #812, #813, #820 and #814
|
||||
|
@ -66,14 +66,4 @@ public class PassportElementErrorTranslationFiles implements PassportElementErro
|
||||
throw new TelegramApiValidationException("Type parameter can't be empty", this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PassportElementErrorTranslationFiles{" +
|
||||
"source='" + source + '\'' +
|
||||
", type='" + type + '\'' +
|
||||
", fileHashes=" + fileHashes +
|
||||
", message='" + message + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import org.telegram.telegrambots.meta.updateshandlers.SentCallback;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* @author Ruben Bermudez
|
||||
@ -49,6 +50,13 @@ public abstract class AbsSender {
|
||||
sendApiMethodAsync(method, callback);
|
||||
}
|
||||
|
||||
public <T extends Serializable, Method extends BotApiMethod<T>> CompletableFuture<T> executeAsync(Method method) throws TelegramApiException {
|
||||
if (method == null) {
|
||||
throw new TelegramApiException("Parameter method can not be null");
|
||||
}
|
||||
return sendApiMethodAsync(method);
|
||||
}
|
||||
|
||||
public <T extends Serializable, Method extends BotApiMethod<T>> T execute(Method method) throws TelegramApiException {
|
||||
if (method == null) {
|
||||
throw new TelegramApiException("Parameter method can not be null");
|
||||
@ -70,6 +78,15 @@ public abstract class AbsSender {
|
||||
|
||||
// Send Requests Async
|
||||
|
||||
|
||||
public final CompletableFuture<User> getMeAsync() {
|
||||
return sendApiMethodAsync(new GetMe());
|
||||
}
|
||||
|
||||
public final CompletableFuture<WebhookInfo> getWebhookInfoAsync() {
|
||||
return sendApiMethodAsync(new GetWebhookInfo());
|
||||
}
|
||||
|
||||
public final void getMeAsync(SentCallback<User> sentCallback) throws TelegramApiException {
|
||||
if (sentCallback == null) {
|
||||
throw new TelegramApiException("Parameter sentCallback can not be null");
|
||||
@ -175,9 +192,94 @@ public abstract class AbsSender {
|
||||
*/
|
||||
public abstract Message execute(SendAnimation sendAnimation) throws TelegramApiException;
|
||||
|
||||
|
||||
// Specific Send Requests Async
|
||||
|
||||
public abstract CompletableFuture<Message> executeAsync(SendDocument sendDocument);
|
||||
|
||||
public abstract CompletableFuture<Message> executeAsync(SendPhoto sendPhoto);
|
||||
|
||||
public abstract CompletableFuture<Message> executeAsync(SendVideo sendVideo);
|
||||
|
||||
public abstract CompletableFuture<Message> executeAsync(SendVideoNote sendVideoNote);
|
||||
|
||||
public abstract CompletableFuture<Message> executeAsync(SendSticker sendSticker);
|
||||
|
||||
/**
|
||||
* Sends a file using Send Audio method (https://core.telegram.org/bots/api#sendaudio)
|
||||
* @param sendAudio Information to send
|
||||
* @return If success, the sent Message is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Message> executeAsync(SendAudio sendAudio);
|
||||
|
||||
/**
|
||||
* Sends a voice note using Send Voice method (https://core.telegram.org/bots/api#sendvoice)
|
||||
* For this to work, your audio must be in an .ogg file encoded with OPUS
|
||||
* @param sendVoice Information to send
|
||||
* @return If success, the sent Message is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Message> executeAsync(SendVoice sendVoice);
|
||||
|
||||
/**
|
||||
* Send a media group (https://core.telegram.org/bots/api#sendMediaGroup)
|
||||
* @return If success, list of generated messages
|
||||
*/
|
||||
public abstract CompletableFuture<List<Message>> executeAsync(SendMediaGroup sendMediaGroup);
|
||||
|
||||
/**
|
||||
* Set chat profile photo (https://core.telegram.org/bots/api#setChatPhoto)
|
||||
* @param setChatPhoto Information to set the photo
|
||||
* @return If success, true is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Boolean> executeAsync(SetChatPhoto setChatPhoto);
|
||||
|
||||
/**
|
||||
* Adds a new sticker to a set (https://core.telegram.org/bots/api#addStickerToSet)
|
||||
* @param addStickerToSet Information of the sticker to set
|
||||
* @return If success, true is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Boolean> executeAsync(AddStickerToSet addStickerToSet);
|
||||
|
||||
/**
|
||||
* Set sticker set thumb (https://core.telegram.org/bots/api#setStickerSetThumb)
|
||||
* @param setStickerSetThumb Information of the sticker to set
|
||||
* @return If success, true is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Boolean> executeAsync(SetStickerSetThumb setStickerSetThumb);
|
||||
|
||||
/**
|
||||
* Creates a new sticker set (https://core.telegram.org/bots/api#createNewStickerSet)
|
||||
* @param createNewStickerSet Information of the sticker set to create
|
||||
* @return If success, true is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Boolean> executeAsync(CreateNewStickerSet createNewStickerSet);
|
||||
|
||||
/**
|
||||
* Upload a new file as sticker (https://core.telegram.org/bots/api#uploadStickerFile)
|
||||
* @param uploadStickerFile Information of the file to upload as sticker
|
||||
* @return If success, true is returned
|
||||
*/
|
||||
public abstract CompletableFuture<File> executeAsync(UploadStickerFile uploadStickerFile);
|
||||
|
||||
/**
|
||||
* Edit media in a message
|
||||
* @param editMessageMedia Information of the new media
|
||||
* @return If the edited message is not an inline message, the edited Message is returned, otherwise True is returned
|
||||
*/
|
||||
public abstract CompletableFuture<Serializable> executeAsync(EditMessageMedia editMessageMedia);
|
||||
|
||||
/**
|
||||
* Send animation
|
||||
* @param sendAnimation Information of the animation
|
||||
* @return Sent message
|
||||
*/
|
||||
public abstract CompletableFuture<Message> executeAsync(SendAnimation sendAnimation);
|
||||
|
||||
// Simplified methods
|
||||
|
||||
protected abstract <T extends Serializable, Method extends BotApiMethod<T>, Callback extends SentCallback<T>> void sendApiMethodAsync(Method method, Callback callback);
|
||||
|
||||
protected abstract <T extends Serializable, Method extends BotApiMethod<T>> CompletableFuture<T> sendApiMethodAsync(Method method);
|
||||
|
||||
protected abstract <T extends Serializable, Method extends BotApiMethod<T>> T sendApiMethod(Method method) throws TelegramApiException;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.telegram.telegrambots.bots;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
@ -50,6 +51,7 @@ import java.io.Serializable;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@ -61,6 +63,7 @@ import static org.telegram.telegrambots.Constants.SOCKET_TIMEOUT;
|
||||
* Implementation of all the methods needed to interact with Telegram Servers
|
||||
*/
|
||||
@SuppressWarnings({"unused"})
|
||||
@Slf4j
|
||||
public abstract class DefaultAbsSender extends AbsSender {
|
||||
private static final ContentType TEXT_PLAIN_CONTENT_TYPE = ContentType.create("text/plain", StandardCharsets.UTF_8);
|
||||
|
||||
@ -92,22 +95,6 @@ public abstract class DefaultAbsSender extends AbsSender {
|
||||
}
|
||||
}
|
||||
|
||||
private void configureHttpContext() {
|
||||
|
||||
if (options.getProxyType() != DefaultBotOptions.ProxyType.NO_PROXY) {
|
||||
InetSocketAddress socksaddr = new InetSocketAddress(options.getProxyHost(), options.getProxyPort());
|
||||
options.getHttpContext().setAttribute("socketAddress", socksaddr);
|
||||
}
|
||||
|
||||
if (options.getProxyType() == DefaultBotOptions.ProxyType.SOCKS4) {
|
||||
options.getHttpContext().setAttribute("socksVersion", 4);
|
||||
}
|
||||
if (options.getProxyType() == DefaultBotOptions.ProxyType.SOCKS5) {
|
||||
options.getHttpContext().setAttribute("socksVersion", 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token of the bot to be able to perform Telegram Api Requests
|
||||
* @return Token of the bot
|
||||
@ -118,6 +105,10 @@ public abstract class DefaultAbsSender extends AbsSender {
|
||||
return options;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return options.getBaseUrl() + getBotToken() + "/";
|
||||
}
|
||||
|
||||
// Send Requests
|
||||
|
||||
public final java.io.File downloadFile(String filePath) throws TelegramApiException {
|
||||
@ -776,6 +767,204 @@ public abstract class DefaultAbsSender extends AbsSender {
|
||||
}
|
||||
}
|
||||
|
||||
// Async Methods
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendDocument sendDocument) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendDocument));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendPhoto sendPhoto) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendPhoto));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendVideo sendVideo) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendVideo));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendVideoNote sendVideoNote) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendVideoNote));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendSticker sendSticker) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendSticker));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendAudio sendAudio) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendAudio));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendVoice sendVoice) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendVoice));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Message>> executeAsync(SendMediaGroup sendMediaGroup) {
|
||||
CompletableFuture<List<Message>> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendMediaGroup));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> executeAsync(SetChatPhoto setChatPhoto) {
|
||||
CompletableFuture<Boolean> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(setChatPhoto));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> executeAsync(AddStickerToSet addStickerToSet) {
|
||||
CompletableFuture<Boolean> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(addStickerToSet));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> executeAsync(SetStickerSetThumb setStickerSetThumb) {
|
||||
CompletableFuture<Boolean> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(setStickerSetThumb));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> executeAsync(CreateNewStickerSet createNewStickerSet) {
|
||||
CompletableFuture<Boolean> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(createNewStickerSet));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<File> executeAsync(UploadStickerFile uploadStickerFile) {
|
||||
CompletableFuture<File> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(uploadStickerFile));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Serializable> executeAsync(EditMessageMedia editMessageMedia) {
|
||||
CompletableFuture<Serializable> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(editMessageMedia));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> executeAsync(SendAnimation sendAnimation) {
|
||||
CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
completableFuture.complete(execute(sendAnimation));
|
||||
} catch (TelegramApiException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
|
||||
// Simplified methods
|
||||
|
||||
@Override
|
||||
@ -799,6 +988,20 @@ public abstract class DefaultAbsSender extends AbsSender {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends Serializable, Method extends BotApiMethod<T>> CompletableFuture<T> sendApiMethodAsync(Method method) {
|
||||
CompletableFuture<T> completableFuture = new CompletableFuture<>();
|
||||
exe.submit(() -> {
|
||||
try {
|
||||
String responseContent = sendMethodRequest(method);
|
||||
completableFuture.complete(method.deserializeResponse(responseContent));
|
||||
} catch (IOException | TelegramApiValidationException | TelegramApiRequestException e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final <T extends Serializable, Method extends BotApiMethod<T>> T sendApiMethod(Method method) throws TelegramApiException {
|
||||
try {
|
||||
@ -809,6 +1012,24 @@ public abstract class DefaultAbsSender extends AbsSender {
|
||||
}
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
private void configureHttpContext() {
|
||||
|
||||
if (options.getProxyType() != DefaultBotOptions.ProxyType.NO_PROXY) {
|
||||
InetSocketAddress socksaddr = new InetSocketAddress(options.getProxyHost(), options.getProxyPort());
|
||||
options.getHttpContext().setAttribute("socketAddress", socksaddr);
|
||||
}
|
||||
|
||||
if (options.getProxyType() == DefaultBotOptions.ProxyType.SOCKS4) {
|
||||
options.getHttpContext().setAttribute("socksVersion", 4);
|
||||
}
|
||||
if (options.getProxyType() == DefaultBotOptions.ProxyType.SOCKS5) {
|
||||
options.getHttpContext().setAttribute("socksVersion", 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private <T extends Serializable, Method extends BotApiMethod<T>> String sendMethodRequest(Method method) throws TelegramApiValidationException, IOException {
|
||||
method.validate();
|
||||
String url = getBaseUrl() + method.getMethod();
|
||||
@ -888,10 +1109,6 @@ public abstract class DefaultAbsSender extends AbsSender {
|
||||
}
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return options.getBaseUrl() + getBotToken() + "/";
|
||||
}
|
||||
|
||||
private void assertParamNotNull(Object param, String paramName) throws TelegramApiException {
|
||||
if (param == null) {
|
||||
throw new TelegramApiException("Parameter " + paramName + " can not be null");
|
||||
|
Loading…
Reference in New Issue
Block a user