Skip to content

Commit 599fe13

Browse files
authored
Add ability to ignore old updates (#50)
1 parent 72988dc commit 599fe13

File tree

4 files changed

+86
-11
lines changed

4 files changed

+86
-11
lines changed

jtelegrambotapi-core/src/main/java/com/jtelegram/api/update/PollingUpdateProvider.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ public class PollingUpdateProvider implements UpdateProvider {
2323
private int sleepInterval = 50;
2424
@Builder.Default
2525
private int timeout = 10;
26+
/**
27+
* The max age (in seconds) that an update can be.
28+
*
29+
* If the data is available and the update is older
30+
* than maxUpdateAge seconds, then it is silently ignored.
31+
*
32+
* By default, this feature is disabled.
33+
*
34+
* @see com.jtelegram.api.update.Update.TimeSensitiveUpdate
35+
*/
36+
@Builder.Default
37+
private long maxUpdateAge = -1;
2638
@Singular
2739
private List<UpdateType> allowedUpdates;
2840
@Builder.Default

jtelegrambotapi-core/src/main/java/com/jtelegram/api/update/PollingUpdateRunnable.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import okhttp3.Response;
99

1010
import java.io.IOException;
11+
import java.util.concurrent.TimeUnit;
1112
import java.net.SocketTimeoutException;
1213
import java.util.Objects;
1314
import java.util.stream.Stream;
@@ -57,18 +58,43 @@ public void run() {
5758
public void handleUpdates(Update[] updates) {
5859
for (Update update : updates) {
5960
if (update != null) {
60-
handleUpdate(bot, UpdateType.from(update.getClass()), update);
61+
handleUpdate(bot, owner.getMaxUpdateAge(), UpdateType.from(update.getClass()), update);
6162
}
6263
}
6364

6465
offset = Stream.of(updates).filter(Objects::nonNull).mapToInt(Update::getUpdateId).max().orElse(offset - 1) + 1;
6566
}
6667

68+
// legacy method for mismatched core + webhooks
6769
public static <T extends Update> void handleUpdate(TelegramBot bot, UpdateType<T> type, Update update) {
70+
handleUpdate(bot, -1L, type, update);
71+
}
72+
73+
public static <T extends Update> void handleUpdate(TelegramBot bot, long maxAge, UpdateType<T> type, Update update) {
6874
if (type != null) {
6975
Class<T> clazz = type.getUpdateClass();
7076

77+
if (isTooOld(update, maxAge)) {
78+
return;
79+
}
80+
7181
bot.getEventRegistry().dispatch(type.getEventFunction().apply(bot, clazz.cast(update)));
7282
}
7383
}
84+
85+
private static boolean isTooOld(Update update, long maxDistance) {
86+
if (maxDistance <= 0) {
87+
return false;
88+
}
89+
90+
if (!(update instanceof Update.TimeSensitiveUpdate)) {
91+
return false;
92+
}
93+
94+
long eventTime = ((Update.TimeSensitiveUpdate) update).getEventTime();
95+
long currentUnixTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
96+
long timeDistance = Math.max(0, currentUnixTime - eventTime);
97+
98+
return timeDistance >= maxDistance;
99+
}
74100
}

jtelegrambotapi-core/src/main/java/com/jtelegram/api/update/Update.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,27 @@
2121
public class Update {
2222
private int updateId;
2323

24+
public static abstract class TimeSensitiveUpdate extends Update {
25+
/**
26+
* @return The relevant unix time when the update
27+
* should be compared to.
28+
*/
29+
public abstract long getEventTime();
30+
31+
protected long getDateFromMessage(Message message) {
32+
return message.getForwardSignature() != null ? message.getForwardDate() : message.getDate();
33+
}
34+
}
35+
2436
@Getter
2537
@ToString(callSuper = true)
26-
public static class ChannelPostUpdate extends Update {
38+
public static class ChannelPostUpdate extends TimeSensitiveUpdate {
2739
private Message channelPost;
40+
41+
@Override
42+
public long getEventTime() {
43+
return getDateFromMessage(channelPost);
44+
}
2845
}
2946

3047
@Getter
@@ -35,14 +52,24 @@ public static class ChosenInlineResultUpdate extends Update {
3552

3653
@Getter
3754
@ToString(callSuper = true)
38-
public static class EditedChannelPostUpdate extends Update {
55+
public static class EditedChannelPostUpdate extends TimeSensitiveUpdate {
3956
private Message editedChannelPost;
57+
58+
@Override
59+
public long getEventTime() {
60+
return editedChannelPost.getEditDate();
61+
}
4062
}
4163

4264
@Getter
4365
@ToString(callSuper = true)
44-
public static class EditedMessageUpdate extends Update {
66+
public static class EditedMessageUpdate extends TimeSensitiveUpdate {
4567
private Message editedMessage;
68+
69+
@Override
70+
public long getEventTime() {
71+
return editedMessage.getEditDate();
72+
}
4673
}
4774

4875
@Getter
@@ -59,8 +86,13 @@ public static class CallbackQueryUpdate extends Update {
5986

6087
@Getter
6188
@ToString(callSuper = true)
62-
public static class MessageUpdate extends Update {
89+
public static class MessageUpdate extends TimeSensitiveUpdate {
6390
private Message message;
91+
92+
@Override
93+
public long getEventTime() {
94+
return getDateFromMessage(message);
95+
}
6496
}
6597

6698
@Getter

jtelegrambotapi-webhooks/src/main/java/com/jtelegram/api/webhooks/WebhookUpdateProvider.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
import com.jtelegram.api.message.input.file.LocalInputFile;
88
import com.jtelegram.api.requests.webhooks.DeleteWebhook;
99
import com.jtelegram.api.requests.webhooks.SetWebhook;
10-
import com.jtelegram.api.update.PollingUpdateRunnable;
11-
import com.jtelegram.api.update.Update;
12-
import com.jtelegram.api.update.UpdateProvider;
13-
import com.jtelegram.api.update.UpdateType;
10+
import com.jtelegram.api.update.*;
1411
import io.vertx.core.AsyncResult;
1512
import io.vertx.core.Vertx;
1613
import io.vertx.core.http.HttpServer;
@@ -43,14 +40,18 @@ public class WebhookUpdateProvider implements UpdateProvider {
4340
private List<UpdateType> updateTypes;
4441
private Integer maxConnections;
4542
private Integer retryAfter;
43+
/**
44+
* @see PollingUpdateProvider#getMaxUpdateAge()
45+
*/
46+
private long maxUpdateAge = -1;
4647
private Consumer<TelegramException> errorHandler = ErrorLogger.builder()
4748
.identifier("Webhook Update Provider")
4849
.build();
4950

5051
@Builder
5152
public WebhookUpdateProvider(HttpServerOptions serverOptions, File selfSignedCertificate,
5253
List<UpdateType> updateTypes, Integer maxConnections, Integer retryAfter,
53-
Consumer<TelegramException> errorHandler) throws InterruptedException, FailBindingException {
54+
Long maxUpdateAge, Consumer<TelegramException> errorHandler) throws InterruptedException, FailBindingException {
5455
if (!serverOptions.isSsl()) {
5556
throw new IllegalArgumentException("Http Server must be SSL!");
5657
}
@@ -63,6 +64,10 @@ public WebhookUpdateProvider(HttpServerOptions serverOptions, File selfSignedCer
6364
this.errorHandler = errorHandler;
6465
}
6566

67+
if (maxUpdateAge != null) {
68+
this.maxUpdateAge = maxUpdateAge;
69+
}
70+
6671
this.updateTypes = updateTypes;
6772
this.maxConnections = maxConnections;
6873
this.retryAfter = retryAfter;
@@ -80,7 +85,7 @@ public WebhookUpdateProvider(HttpServerOptions serverOptions, File selfSignedCer
8085
Update update = TelegramBotRegistry.GSON.fromJson(buffer.toString(), Update.class);
8186

8287
if (update != null) {
83-
PollingUpdateRunnable.handleUpdate(bot, UpdateType.from(update.getClass()), update);
88+
PollingUpdateRunnable.handleUpdate(bot, maxUpdateAge, UpdateType.from(update.getClass()), update);
8489
}
8590
} catch (TelegramException ex) {
8691
this.errorHandler.accept(ex);

0 commit comments

Comments
 (0)