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;
|
package org.telegram.telegrambots.starter;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.telegram.telegrambots.meta.TelegramBotsApi;
|
import org.telegram.telegrambots.meta.TelegramBotsApi;
|
||||||
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
|
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.LongPollingBot;
|
||||||
import org.telegram.telegrambots.meta.generics.WebhookBot;
|
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.
|
* 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 {
|
public void afterPropertiesSet() throws Exception {
|
||||||
try {
|
try {
|
||||||
for (LongPollingBot bot : longPollingBots) {
|
for (LongPollingBot bot : longPollingBots) {
|
||||||
telegramBotsApi.registerBot(bot);
|
BotSession session = telegramBotsApi.registerBot(bot);
|
||||||
|
handleAfterRegistrationHook(bot, session);
|
||||||
}
|
}
|
||||||
for (WebhookBot bot : webHookBots) {
|
for (WebhookBot bot : webHookBots) {
|
||||||
telegramBotsApi.registerBot(bot);
|
telegramBotsApi.registerBot(bot);
|
||||||
@ -42,4 +50,47 @@ public class TelegramBotInitializer implements InitializingBean {
|
|||||||
throw new RuntimeException(e);
|
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