[ ] telegram Spring |
? ? - ? .
: spring mvc telegram api.
- :
@BotController
public class SimpleOkayController {
@BotRequestMapping(value = "/ok")
public SendMessage ok(Update update) {
return new SendMessage()
.setChatId(update.getMessage().getChatId())
.setText("okay bro, okay!");
}
}
@BotController
public class StartController {
@Autowired
private Filter shopMenu;
@Autowired
private PayTokenService payTokenService;
@Autowired
private ItemService itemService;
@BotRequestMapping("/shop")
public SendMessage generateInitMenu(Update update) {
return new SendMessage()
.setChatId(update.getMessage().getChatId().toString())
.setText(" !")
.setReplyMarkup(shopMenu.getSubMenu(0L, 4L, 1L)); // <--
}
@BotRequestMapping(value = "/buyItem", method = BotRequestMethod.EDIT)
public List bayItem(Update update) {
....................
Item item = itemService.findById(id); // <--
return Arrays.asList(new EditMessageText()
.setChatId(update.getMessage().getChatId())
.setMessageId(update.getMessage().getMessageId())
.setText(" , "),
new SendInvoice()
.setChatId(Integer.parseInt(update.getMessage().getChatId().toString()))
.setDescription(item.getDescription())
.setTitle(item.getName())
.setProviderToken(payTokenService.getPayToken())
........................
.setPrices(item.getPrice())
);
}
}
:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface BotController {
String[] value() default {};
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface BotRequestMapping {
String[] value() default {};
BotRequestMethod[] method() default {BotRequestMethod.MSG};
}
HashMap
public class BotApiMethodContainer {
private static final Logger LOGGER = Logger.getLogger(BotApiMethodContainer.class);
private Map controllerMap;
public static BotApiMethodContainer getInstanse() {
return Holder.INST;
}
public void addBotController(String path, BotApiMethodController controller) {
if(controllerMap.containsKey(path)) throw new BotApiMethodContainerException("path " + path + " already add");
LOGGER.trace("add telegram bot controller for path: " + path);
controllerMap.put(path, controller);
}
public BotApiMethodController getBotApiMethodController(String path) {
return controllerMap.get(path);
}
private BotApiMethodContainer() {
controllerMap = new HashMap<>();
}
private static class Holder{
final static BotApiMethodContainer INST = new BotApiMethodContainer();
}
}
( @BotController @BotRequestMapping)
public abstract class BotApiMethodController {
private static final Logger LOGGER = Logger.getLogger(BotApiMethodController.class);
private Object bean;
private Method method;
private Process processUpdate;
public BotApiMethodController(Object bean, Method method) {
this.bean = bean;
this.method = method;
processUpdate = typeListReturnDetect() ? this::processList : this::processSingle;
}
public abstract boolean successUpdatePredicate(Update update);
public List process(Update update) {
if(!successUpdatePredicate(update)) return null;
try {
return processUpdate.accept(update);
} catch (IllegalAccessException | InvocationTargetException e) {
LOGGER.error("bad invoke method", e);
}
return null;
}
boolean typeListReturnDetect() {
return List.class.equals(method.getReturnType());
}
private List processSingle(Update update) throws InvocationTargetException, IllegalAccessException {
BotApiMethod botApiMethod = (BotApiMethod) method.invoke(bean, update);
return botApiMethod != null ? Collections.singletonList(botApiMethod) : new ArrayList<>(0);
}
private List processList(Update update) throws InvocationTargetException, IllegalAccessException {
List botApiMethods = (List) method.invoke(bean, update);
return botApiMethods != null ? botApiMethods : new ArrayList<>(0);
}
private interface Process{
List accept(Update update) throws InvocationTargetException, IllegalAccessException;
}
}
: Spring , ?
BeanPostProcessor. . scope , !
@Component
public class TelegramUpdateHandlerBeanPostProcessor implements BeanPostProcessor, Ordered {
private static final Logger LOGGER = Logger.getLogger(TelegramUpdateHandlerBeanPostProcessor.class);
private BotApiMethodContainer container = BotApiMethodContainer.getInstanse();
private Map botControllerMap = new HashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Class