Add annotation to allow bot to get botSession
A method annotated with @AfterBotRegistration will be invoked after the bot is registered. Optionally the method can have a parameter of type BotSession to get passed the BotSession the bot was created with.
This commit is contained in:
parent
27e0751b7e
commit
ad195d8d59
@ -0,0 +1,20 @@
|
||||
package org.telegram.telegrambots.starter;
|
||||
|
||||
import org.telegram.telegrambots.meta.TelegramBotsApi;
|
||||
import org.telegram.telegrambots.meta.generics.BotSession;
|
||||
import org.telegram.telegrambots.meta.generics.LongPollingBot;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicated that the Method of a Class extending {@link LongPollingBot} will be called after the bot was registered
|
||||
* If the Method has a single Parameter of type {@link BotSession}, the method get passed the bot session the bot was registered with
|
||||
* <br><br>
|
||||
* <p>The bot session passed is the ones returned by {@link TelegramBotsApi#registerBot(LongPollingBot)}</p>
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AfterBotRegistration {}
|
@ -1,13 +1,20 @@
|
||||
package org.telegram.telegrambots.starter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.telegram.telegrambots.meta.TelegramBotsApi;
|
||||
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
|
||||
import org.telegram.telegrambots.meta.generics.BotSession;
|
||||
import org.telegram.telegrambots.meta.generics.LongPollingBot;
|
||||
import org.telegram.telegrambots.meta.generics.WebhookBot;
|
||||
import org.telegram.telegrambots.meta.logging.BotLogger;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Receives all beand which are #LongPollingBot and #WebhookBot and register them in #TelegramBotsApi.
|
||||
@ -33,7 +40,8 @@ public class TelegramBotInitializer implements InitializingBean {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
try {
|
||||
for (LongPollingBot bot : longPollingBots) {
|
||||
telegramBotsApi.registerBot(bot);
|
||||
BotSession session = telegramBotsApi.registerBot(bot);
|
||||
handleAfterRegistrationHook(bot, session);
|
||||
}
|
||||
for (WebhookBot bot : webHookBots) {
|
||||
telegramBotsApi.registerBot(bot);
|
||||
@ -42,4 +50,47 @@ public class TelegramBotInitializer implements InitializingBean {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAnnotatedMethod(Object bot, Method method, BotSession session) throws InvocationTargetException, IllegalAccessException {
|
||||
if (method.getParameterCount() > 1) {
|
||||
BotLogger.warn(this.getClass().getSimpleName(),
|
||||
format("Method %s of Type %s has too many parameters",
|
||||
method.getName(),
|
||||
method.getDeclaringClass().getCanonicalName()
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (method.getParameterCount() == 0) {
|
||||
method.invoke(bot);
|
||||
return;
|
||||
}
|
||||
if (method.getParameterTypes()[0].equals(BotSession.class)) {
|
||||
method.invoke(bot, session);
|
||||
return;
|
||||
}
|
||||
BotLogger.warn(this.getClass().getSimpleName(),
|
||||
format("Method %s of Type %s has invalid parameter type",
|
||||
method.getName(),
|
||||
method.getDeclaringClass().getCanonicalName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void handleAfterRegistrationHook(Object bot, BotSession botSession) {
|
||||
for (Method m : bot.getClass().getMethods()) {
|
||||
Stream.of(m.getAnnotations()).forEach(annotation -> System.out.println(annotation.annotationType().getName()));
|
||||
if (m.getAnnotation(AfterBotRegistration.class) != null) {
|
||||
try {
|
||||
handleAnnotatedMethod(bot, m, botSession);
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
BotLogger.error(this.getClass().getSimpleName(),
|
||||
format("Couldn't invoke Method %s of Type %s",
|
||||
m.getName(), m.getDeclaringClass().getCanonicalName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
package org.telegram.telegrambots.starter;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
|
||||
import org.telegram.telegrambots.meta.TelegramBotsApi;
|
||||
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
|
||||
import org.telegram.telegrambots.meta.generics.BotSession;
|
||||
import org.telegram.telegrambots.meta.generics.LongPollingBot;
|
||||
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class TestTelegramBotStarterRegistrationHooks {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(MockTelegramBotsApi.class, TelegramBotStarterConfiguration.class));
|
||||
|
||||
// Terrible workaround for mockito loosing annotations on methods
|
||||
private static boolean hookCalled = false;
|
||||
private static boolean hookCalledWithSession = false;
|
||||
private static final DefaultBotSession someBotSession = new DefaultBotSession();
|
||||
|
||||
private static final TelegramBotsApi mockTelegramBotsApi = mock(TelegramBotsApi.class);
|
||||
|
||||
@Test
|
||||
public void longPollingBotWithAnnotatedMethodshouldBeCalled() throws TelegramApiRequestException {
|
||||
|
||||
when(mockTelegramBotsApi.registerBot(any(LongPollingBot.class))).thenReturn(someBotSession);
|
||||
|
||||
this.contextRunner.withUserConfiguration(LongPollingBotConfig.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(AnnotatedLongPollingBot.class);
|
||||
|
||||
final LongPollingBot bot = context.getBean(LongPollingBot.class);
|
||||
final TelegramBotsApi telegramBotsApi = context.getBean(TelegramBotsApi.class);
|
||||
|
||||
assertThat(hookCalled).isTrue();
|
||||
assertThat(hookCalledWithSession).isTrue();
|
||||
verify(telegramBotsApi, times(1)).registerBot(bot);
|
||||
verifyNoMoreInteractions(telegramBotsApi);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class MockTelegramBotsApi{
|
||||
|
||||
@Bean
|
||||
public TelegramBotsApi telegramBotsApi() {
|
||||
return mockTelegramBotsApi;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class LongPollingBotConfig{
|
||||
@Bean
|
||||
public LongPollingBot longPollingBot() { return new AnnotatedLongPollingBot(); }
|
||||
}
|
||||
|
||||
static class AnnotatedLongPollingBot extends TelegramLongPollingBot {
|
||||
|
||||
@Override
|
||||
public void onUpdateReceived(final Update update) {}
|
||||
|
||||
@Override
|
||||
public String getBotUsername() { return null; }
|
||||
|
||||
@Override
|
||||
public String getBotToken() { return null; }
|
||||
|
||||
@AfterBotRegistration
|
||||
public void afterBotHook() {
|
||||
hookCalled = true;
|
||||
}
|
||||
|
||||
@AfterBotRegistration
|
||||
public void afterBotHookWithSession(BotSession session) {
|
||||
hookCalledWithSession = session.equals(someBotSession);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user