TelegramLongPollingBot构造函数及getBotToken()方法废弃导致Bot实例为Null的问题求助
TelegramLongPollingBot构造函数及getBotToken()方法废弃导致Bot实例为Null的问题求助
兄弟,我完全懂你这种看着官方文档和实际代码不匹配、还遇到废弃API导致Bot实例为null的崩溃感!我来一步步帮你搞定这个问题:
首先解决配置类的静态字段注入坑
你的GeneralBotConfig里用了静态字段加@Value,这是Spring注入的常见误区——Spring没法直接把值注入到静态字段里,因为Spring是针对实例对象进行依赖注入的。先把配置类改成实例字段:
import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @Data @PropertySource("application.properties") public class GeneralBotConfig { @Value("${bot.name}") private String botName; @Value("${bot.token}") private String botToken; }
替换废弃的TelegramLongPollingBot构造方式
现在TelegramLongPollingBot的无参构造已经被废弃,官方推荐使用带token和用户名的构造函数初始化。我们通过构造注入把配置类的参数传进来,同时修正getBotToken()的实现(虽然它标记废弃,但目前仍可正常使用,或者直接用构造传入的token返回即可):
import org.springframework.stereotype.Component; import org.telegram.telegrambots.bots.TelegramLongPollingBot; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; import org.telegram.telegrambots.meta.api.objects.Update; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; @Component public class DemoCountryBot extends TelegramLongPollingBot { private final String botName; private final String botToken; // 通过构造注入配置类参数 public DemoCountryBot(GeneralBotConfig botConfig) { // 使用非废弃的带参构造函数初始化 super(botConfig.getBotToken(), botConfig.getBotName()); this.botName = botConfig.getBotName(); this.botToken = botConfig.getBotToken(); } @Override public String getBotUsername() { return botName; } @Override public String getBotToken() { return botToken; } @Override public void onUpdateReceived(Update update) { if(update.hasMessage() && update.getMessage().hasText()) { String messageText = update.getMessage().getText(); Long chatId = update.getMessage().getChatId(); String userFirstName = update.getMessage().getChat().getFirstName(); switch(messageText) { case "/start": startCommandReceived(chatId, userFirstName); break; default: sendResponseMessage(chatId, "Sorry, command not recognized"); } } } private void startCommandReceived(long chatId, String userName) { // 把控制台输出改成发送消息给用户,不然用户看不到提示 sendResponseMessage(chatId, String.format("Hi, %s!\nI can give you basic information\nabout any country in the world.\nJust send me a country name in English (like Ukraine)", userName)); } private void sendResponseMessage(long chatId, String message) { // 推荐用Builder模式构建消息,比setter更简洁 SendMessage sendMessage = SendMessage.builder() .chatId(chatId) .text(message) .build(); try { execute(sendMessage); } catch (TelegramApiException e) { e.printStackTrace(); } } }
最后添加Bot注册配置类
Spring启动后不会自动注册Bot,必须手动把你的Bot实例注册到TelegramBotsApi里,否则会出现Bot实例无效、无法接收消息的情况:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.telegram.telegrambots.meta.TelegramBotsApi; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; @Configuration public class BotRegistrationConfig { @Bean public TelegramBotsApi telegramBotsApi(DemoCountryBot demoCountryBot) throws TelegramApiException { TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class); botsApi.registerBot(demoCountryBot); return botsApi; } }
额外小提醒
- 之前你的
startCommandReceived方法只是打印到控制台,用户在Telegram里看不到这个提示,我已经改成发送消息给用户了 - 遇到废弃API时,可以直接看IDE里的JavaDoc注释,里面会明确标注替代方案,比滞后的官方文档更靠谱
备注:内容来源于stack exchange,提问作者Alexei Krylov Nikiforov
相关产品推荐
相关产品推荐

