Inject bot instance into the reply update consumer

Also added deprecated methods to still allow the old behaviour, discarding the bot reference in that case.

The condition could have a bot instance injected as well, which would require rewriting the Flag register though.
This commit is contained in:
Chase22 2020-11-24 17:02:44 +01:00
parent 415d31eaec
commit e7cb0e6ced
8 changed files with 95 additions and 30 deletions

View File

@ -625,7 +625,7 @@ public abstract class BaseAbilityBot extends DefaultAbsSender implements Ability
return replies.stream()
.filter(reply -> runSilently(() -> reply.isOkFor(update), reply.name()))
.map(reply -> runSilently(() -> {
reply.actOn(update);
reply.actOn(this, update);
updateReplyStats(reply);
return false;
}, reply.name()))
@ -651,4 +651,4 @@ public abstract class BaseAbilityBot extends DefaultAbsSender implements Ability
return ability.flags().stream()
.reduce(true, flagAnd, Boolean::logicalAnd);
}
}
}

View File

@ -254,7 +254,7 @@ public final class DefaultAbilities implements AbilityExtension {
.input(0)
.action(ctx -> bot.silent.forceReply(
getLocalizedMessage(ABILITY_RECOVER_MESSAGE, ctx.user().getLanguageCode()), ctx.chatId()))
.reply(update -> {
.reply((bot, update) -> {
String replyToMsg = update.getMessage().getReplyToMessage().getText();
String recoverMessage = getLocalizedMessage(ABILITY_RECOVER_MESSAGE, AbilityUtils.getUser(update).getLanguageCode());
if (!replyToMsg.equals(recoverMessage))

View File

@ -4,10 +4,12 @@ import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.telegram.abilitybots.api.bot.BaseAbilityBot;
import org.telegram.telegrambots.meta.api.objects.Update;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
@ -208,12 +210,22 @@ public final class Ability {
return this;
}
/**
* @deprecated Please use {@link #reply(BiConsumer, Predicate[])}
*/
@Deprecated
@SafeVarargs
public final AbilityBuilder reply(Consumer<Update> action, Predicate<Update>... conditions) {
replies.add(Reply.of(action, conditions));
return this;
}
@SafeVarargs
public final AbilityBuilder reply(BiConsumer<BaseAbilityBot, Update> action, Predicate<Update>... conditions) {
replies.add(Reply.of(action, conditions));
return this;
}
public final AbilityBuilder reply(Reply reply) {
replies.add(reply);
return this;

View File

@ -2,10 +2,12 @@ package org.telegram.abilitybots.api.objects;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import org.telegram.abilitybots.api.bot.BaseAbilityBot;
import org.telegram.telegrambots.meta.api.objects.Update;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Predicate;
@ -22,18 +24,41 @@ import static com.google.common.collect.Lists.newArrayList;
*/
public class Reply {
public final List<Predicate<Update>> conditions;
public final Consumer<Update> action;
public final BiConsumer<BaseAbilityBot, Update> action;
private boolean statsEnabled;
private String name;
Reply(List<Predicate<Update>> conditions, Consumer<Update> action) {
Reply(List<Predicate<Update>> conditions, BiConsumer<BaseAbilityBot, Update> action) {
this.conditions = ImmutableList.<Predicate<Update>>builder()
.addAll(conditions)
.build();
.addAll(conditions)
.build();
this.action = action;
statsEnabled = false;
}
Reply(List<Predicate<Update>> conditions, BiConsumer<BaseAbilityBot, Update> action, String name) {
this(conditions, action);
if (Objects.nonNull(name)) {
enableStats(name);
}
}
/**
* @deprecated Please use {@link #Reply(List, BiConsumer)}
*/
@Deprecated
Reply(List<Predicate<Update>> conditions, Consumer<Update> action) {
this.conditions = ImmutableList.<Predicate<Update>>builder()
.addAll(conditions)
.build();
this.action = ((baseAbilityBot, update) -> action.accept(update));
statsEnabled = false;
}
/**
* @deprecated Please use {@link #Reply(List, BiConsumer, String)}
*/
@Deprecated
Reply(List<Predicate<Update>> conditions, Consumer<Update> action, String name) {
this(conditions, action);
if (Objects.nonNull(name)) {
@ -41,10 +66,27 @@ public class Reply {
}
}
public static Reply of(BiConsumer<BaseAbilityBot, Update> action, List<Predicate<Update>> conditions) {
return new Reply(conditions, action);
}
@SafeVarargs
public static Reply of(BiConsumer<BaseAbilityBot, Update> action, Predicate<Update>... conditions) {
return Reply.of(action, newArrayList(conditions));
}
/**
* @deprecated Please use {@link #of(BiConsumer, List)}
*/
@Deprecated
public static Reply of(Consumer<Update> action, List<Predicate<Update>> conditions) {
return new Reply(conditions, action);
}
/**
* @deprecated Please use {@link #of(BiConsumer, Predicate[])}
*/
@Deprecated
@SafeVarargs
public static Reply of(Consumer<Update> action, Predicate<Update>... conditions) {
return Reply.of(action, newArrayList(conditions));
@ -56,15 +98,15 @@ public class Reply {
return conditions.stream().reduce(true, stateAnd, Boolean::logicalAnd);
}
public void actOn(Update update) {
action.accept(update);
public void actOn(BaseAbilityBot bot, Update update) {
action.accept(bot, update);
}
public List<Predicate<Update>> conditions() {
return conditions;
}
public Consumer<Update> action() {
public BiConsumer<BaseAbilityBot, Update> action() {
return action;
}

View File

@ -1,6 +1,7 @@
package org.telegram.abilitybots.api.objects;
import org.jetbrains.annotations.NotNull;
import org.telegram.abilitybots.api.bot.BaseAbilityBot;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.util.AbilityUtils;
import org.telegram.telegrambots.meta.api.objects.Update;
@ -10,6 +11,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
@ -20,7 +22,7 @@ public class ReplyFlow extends Reply {
private final Set<Reply> nextReplies;
private ReplyFlow(List<Predicate<Update>> conditions, Consumer<Update> action, Set<Reply> nextReplies, String name) {
private ReplyFlow(List<Predicate<Update>> conditions, BiConsumer<BaseAbilityBot, Update> action, Set<Reply> nextReplies, String name) {
super(conditions, action, name);
this.nextReplies = nextReplies;
}
@ -48,7 +50,7 @@ public class ReplyFlow extends Reply {
private final DBContext db;
private final int id;
private List<Predicate<Update>> conds;
private Consumer<Update> action;
private BiConsumer<BaseAbilityBot, Update> action;
private Set<Reply> nextReplies;
private String name;
@ -63,7 +65,16 @@ public class ReplyFlow extends Reply {
this(db, replyCounter.getAndIncrement());
}
/**
* @deprecated Please use {@link #action(BiConsumer)}
*/
@Deprecated
public ReplyFlowBuilder action(Consumer<Update> action) {
this.action = (bot, update) -> action.accept(update);
return this;
}
public ReplyFlowBuilder action(BiConsumer<BaseAbilityBot, Update> action) {
this.action = action;
return this;
}
@ -80,7 +91,7 @@ public class ReplyFlow extends Reply {
public ReplyFlowBuilder next(Reply nextReply) {
List<Predicate<Update>> statefulConditions = toStateful(nextReply.conditions());
Consumer<Update> statefulAction = nextReply.action().andThen(upd -> {
BiConsumer<BaseAbilityBot, Update> statefulAction = nextReply.action().andThen((unused, upd) -> {
Long chatId = AbilityUtils.getChatId(upd);
db.<Long, Integer>getMap(STATES).remove(chatId);
});
@ -100,16 +111,16 @@ public class ReplyFlow extends Reply {
public ReplyFlow build() {
if (action == null)
action = upd -> {};
action = (bot, upd) -> {};
Consumer<Update> statefulAction;
BiConsumer<BaseAbilityBot, Update> statefulAction;
if (nextReplies.size() > 0) {
statefulAction = action.andThen(upd -> {
statefulAction = action.andThen((bot, upd) -> {
Long chatId = AbilityUtils.getChatId(upd);
db.<Long, Integer>getMap(STATES).put(chatId, id);
});
} else {
statefulAction = action.andThen(upd -> {
statefulAction = action.andThen((bot, upd) -> {
Long chatId = AbilityUtils.getChatId(upd);
db.<Long, Integer>getMap(STATES).remove(chatId);
});

View File

@ -210,7 +210,7 @@ public class AbilityBotTest {
// Support for null parameter matching since due to mocking API changes
when(sender.downloadFile(ArgumentMatchers.<File>isNull())).thenReturn(backupFile);
defaultAbs.recoverDB().replies().get(0).actOn(update);
defaultAbs.recoverDB().replies().get(0).actOn(bot, update);
verify(silent, times(1)).send(RECOVER_SUCCESS, GROUP_ID);
assertEquals(db.getSet(TEST), newHashSet(TEST), "Bot recovered but the DB is still not in sync");

View File

@ -43,8 +43,8 @@ public class DefaultBot extends AbilityBot {
return getDefaultBuilder()
.name(DEFAULT)
.info("dis iz default command")
.reply(Reply.of(upd -> silent.send("reply", upd.getMessage().getChatId()), MESSAGE, update -> update.getMessage().getText().equals("must reply")).enableStats("mustreply"))
.reply(upd -> silent.send("reply", upd.getCallbackQuery().getMessage().getChatId()), CALLBACK_QUERY)
.reply(Reply.of((bot, upd) -> silent.send("reply", upd.getMessage().getChatId()), MESSAGE, update -> update.getMessage().getText().equals("must reply")).enableStats("mustreply"))
.reply((bot, upd) -> silent.send("reply", upd.getCallbackQuery().getMessage().getChatId()), CALLBACK_QUERY)
.build();
}
@ -75,11 +75,11 @@ public class DefaultBot extends AbilityBot {
public Reply channelPostReply() {
return Reply.of(
upd -> silent.send("test channel post", upd.getChannelPost().getChatId()), Flag.CHANNEL_POST
(bot, upd) -> silent.send("test channel post", upd.getChannelPost().getChatId()), Flag.CHANNEL_POST
);
}
public Ability testAbility() {
return getDefaultBuilder().build();
}
}
}

View File

@ -163,19 +163,19 @@ public class ReplyFlowTest {
}
public ReplyFlow directionFlow() {
Reply saidLeft = Reply.of(upd -> silent.send("Sir, I have gone left.", getChatId(upd)),
Reply saidLeft = Reply.of((bot, upd) -> silent.send("Sir, I have gone left.", getChatId(upd)),
hasMessageWith("go left or else"));
ReplyFlow leftflow = ReplyFlow.builder(db, 2)
.action(upd -> silent.send("I don't know how to go left.", getChatId(upd)))
.action((bot, upd) -> silent.send("I don't know how to go left.", getChatId(upd)))
.onlyIf(hasMessageWith("left"))
.next(saidLeft).build();
Reply saidRight = Reply.of(upd -> silent.send("Sir, I have gone right.", getChatId(upd)),
Reply saidRight = Reply.of((bot, upd) -> silent.send("Sir, I have gone right.", getChatId(upd)),
hasMessageWith("right"));
return ReplyFlow.builder(db, 1)
.action(upd -> silent.send("Command me to go left or right!", getChatId(upd)))
.action((bot, upd) -> silent.send("Command me to go left or right!", getChatId(upd)))
.onlyIf(hasMessageWith("wake up"))
.next(leftflow)
.next(saidRight)
@ -184,10 +184,10 @@ public class ReplyFlowTest {
public Reply errantReply() {
return Reply.of(
upd -> {
(bot, upd) -> {
throw new RuntimeException("Throwing an exception inside the update consumer");
},
upd -> {
(upd) -> {
throw new RuntimeException("Throwing an exception inside the reply conditions (flags)");
});
}
@ -195,7 +195,7 @@ public class ReplyFlowTest {
public Ability replyFlowsWithAbility() {
Reply replyWithVk = ReplyFlow.builder(db, 2)
.enableStats("SECOND")
.action(upd -> {
.action((bot, upd) -> {
silent.send("Second reply", upd.getMessage().getChatId());
})
.onlyIf(hasMessageWith("two"))
@ -203,7 +203,7 @@ public class ReplyFlowTest {
Reply replyWithNickname = ReplyFlow.builder(db, 1)
.enableStats("FIRST")
.action(upd -> {
.action((bot, upd) -> {
silent.send("First reply", upd.getMessage().getChatId());
})
.onlyIf(hasMessageWith("one"))