com.annimon.tgbotsmodule.commands.CommandRegistry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tgbots-module Show documentation
Show all versions of tgbots-module Show documentation
Simple Java telegram bots runner built on top of the Telegram Bots library
The newest version!
package com.annimon.tgbotsmodule.commands;
import com.annimon.tgbotsmodule.analytics.UpdateHandler;
import com.annimon.tgbotsmodule.commands.authority.Authority;
import com.annimon.tgbotsmodule.commands.context.CallbackQueryContext;
import com.annimon.tgbotsmodule.commands.context.InlineQueryContext;
import com.annimon.tgbotsmodule.commands.context.MessageContext;
import com.annimon.tgbotsmodule.commands.context.RegexMessageContext;
import com.annimon.tgbotsmodule.services.CommonAbsSender;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.telegram.telegrambots.meta.api.objects.Update;
@SuppressWarnings("RedundantIfStatement")
public class CommandRegistry> implements UpdateHandler {
private final String botUsername;
private final Map> textCommands;
private final List regexCommands;
private final Map> callbackCommands;
private final Map> inlineCommands;
private final Authority authority;
private String callbackCommandSplitPattern;
public CommandRegistry(@NotNull String botUsername, @NotNull Authority authority) {
this.authority = authority;
this.botUsername = "@" + botUsername.toLowerCase(Locale.ENGLISH);
textCommands = new HashMap<>();
regexCommands = new ArrayList<>();
callbackCommands = new HashMap<>();
inlineCommands = new HashMap<>();
callbackCommandSplitPattern = ":";
}
public CommandRegistry register(@NotNull TextCommand command) {
Objects.requireNonNull(command);
Stream.concat(Stream.of(command.command()), command.aliases().stream())
.map(this::stringToCommand)
.forEach(key -> addCommand(textCommands, key, command));
return this;
}
public CommandRegistry register(@NotNull RegexCommand command) {
Objects.requireNonNull(command);
regexCommands.add(command);
return this;
}
public CommandRegistry register(@NotNull CallbackQueryCommand command) {
Objects.requireNonNull(command);
addCommand(callbackCommands, command.command(), command);
return this;
}
public CommandRegistry register(@NotNull InlineQueryCommand command) {
Objects.requireNonNull(command);
addCommand(inlineCommands, command.command(), command);
return this;
}
public CommandRegistry registerBundle(@NotNull CommandBundle bundle) {
Objects.requireNonNull(bundle);
bundle.register(this);
return this;
}
/**
* Splits {@code callback.data} by whitespace ({@code "cmd:args"})
* @return this
*/
public CommandRegistry splitCallbackCommandByColon() {
return splitCallbackCommandByPattern(":");
}
/**
* Splits {@code callback.data} by whitespace ({@code "cmd args"})
* @return this
*/
public CommandRegistry splitCallbackCommandByWhitespace() {
return splitCallbackCommandByPattern("\\s+");
}
/**
* Treats whole {@code callback.data} as command ({@code "cmd"})
* @return this
*/
public CommandRegistry doNotSplitCallbackCommands() {
return splitCallbackCommandByPattern("$");
}
public CommandRegistry splitCallbackCommandByPattern(@NotNull String pattern) {
this.callbackCommandSplitPattern = Objects.requireNonNull(pattern);
return this;
}
@Override
public boolean handleUpdate(@NotNull CommonAbsSender sender, @NotNull Update update) {
if (update.hasMessage()) {
// Text commands
if (update.getMessage().hasText()) {
if ((!textCommands.isEmpty()) && handleTextCommands(sender, update)) {
return true;
}
if ((!regexCommands.isEmpty()) && handleRegexCommands(sender, update)) {
return true;
}
}
} else if (update.hasCallbackQuery()) {
// Callback query commands
final var data = update.getCallbackQuery().getData();
if (data != null && !data.isEmpty()) {
if ((!callbackCommands.isEmpty()) && handleCallbackQueryCommands(sender, update)) {
return true;
}
}
} else if (update.hasInlineQuery()) {
// Inline query commands
if ((!inlineCommands.isEmpty()) && handleInlineQueryCommands(sender, update)) {
return true;
}
}
return false;
}
protected boolean handleTextCommands(@NotNull CommonAbsSender sender, @NotNull Update update) {
final var message = update.getMessage();
final var args = message.getText().split("\\s+", 2);
final var command = stringToCommand(args[0]);
final var commands = Stream.ofNullable(textCommands.get(command))
.flatMap(Collection::stream)
.filter(cmd -> authority.hasRights(sender, update, message.getFrom(), cmd.authority()))
.toList();
if (commands.isEmpty()) {
return false;
}
final var commandArguments = args.length >= 2 ? args[1] : "";
final var context = new MessageContext(sender, update, commandArguments);
for (TextCommand cmd : commands) {
cmd.accept(context);
}
return true;
}
protected boolean handleRegexCommands(@NotNull CommonAbsSender sender, @NotNull Update update) {
final var message = update.getMessage();
final var text = message.getText();
final long count = regexCommands.stream()
.map(cmd -> Map.entry(cmd, cmd.pattern().matcher(text)))
.filter(e -> e.getValue().matches())
.filter(e -> authority.hasRights(sender, update, message.getFrom(), e.getKey().authority()))
.peek(e -> {
final RegexCommand command = e.getKey();
final var matcher = e.getValue();
command.accept(new RegexMessageContext(sender, update, text, matcher));
})
.count();
return (count > 0);
}
protected boolean handleCallbackQueryCommands(@NotNull CommonAbsSender sender, @NotNull Update update) {
final var query = update.getCallbackQuery();
final var args = query.getData().split(callbackCommandSplitPattern, 2);
final var command = args[0];
final var commands = Stream.ofNullable(callbackCommands.get(command))
.flatMap(Collection::stream)
.filter(cmd -> authority.hasRights(sender, update, query.getFrom(), cmd.authority()))
.toList();
if (commands.isEmpty()) {
return false;
}
final var commandArguments = args.length >= 2 ? args[1] : "";
final var context = new CallbackQueryContext(sender, update, commandArguments);
for (CallbackQueryCommand cmd : commands) {
cmd.accept(context);
}
return true;
}
private boolean handleInlineQueryCommands(@NotNull CommonAbsSender sender, @NotNull Update update) {
final var inlineQuery = update.getInlineQuery();
final var query = inlineQuery.getQuery();
final var args = query.split("\\s+", 2);
final var command = args[0];
final var commands = Stream.ofNullable(inlineCommands.get(command))
.flatMap(Collection::stream)
.filter(cmd -> authority.hasRights(sender, update, inlineQuery.getFrom(), cmd.authority()))
.toList();
if (commands.isEmpty()) {
return false;
}
final var commandArguments = args.length >= 2 ? args[1] : "";
final var context = new InlineQueryContext(sender, update, commandArguments);
for (InlineQueryCommand cmd : commands) {
cmd.accept(context);
}
return true;
}
protected String stringToCommand(String str) {
return str.toLowerCase(Locale.ENGLISH).replace(botUsername, "");
}
private static void addCommand(Map> map, K key, V value) {
map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy