Spring Boot Telegram Bot CI构建失败:凭证为空问题求助
解决Spring Boot Telegram Bot CI构建凭证缺失问题
我正在开发一个集成简易Telegram Bot的Java Spring Boot项目。为了避免把Bot用户名、Bot Token这类敏感凭证推送到远程仓库,我把.env文件加入了.gitignore,但这导致Java CI构建失败,抛出异常:org.telegram.telegrambots.meta.exceptions.TelegramApiException: Bot token and username can't be empty
我试过设置模拟凭证值,结果又出现404 Not found错误。以下是我的Bot代码和配置代码,求可行的解决办法:
Bot代码
import application.carsharingapp.exception.NotificationSendingException; import application.carsharingapp.service.notification.NotificationService; import io.github.cdimascio.dotenv.Dotenv; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; 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; @RequiredArgsConstructor @Service public class TelegramNotificationService extends TelegramLongPollingBot implements NotificationService { private static final Dotenv DOTENV = Dotenv.configure().ignoreIfMissing().load(); private static final String BOT_USERNAME = DOTENV.get("BOT_USERNAME"); private static final String BOT_TOKEN = DOTENV.get("BOT_TOKEN"); private static final String TARGET_CHAT_ID = DOTENV.get("TARGET_CHAT_ID"); @Override public void sendNotification(String message) { SendMessage sendMessage = new SendMessage(); sendMessage.setText(message); sendMessage.setChatId(TARGET_CHAT_ID); try { execute(sendMessage); } catch (TelegramApiException e) { throw new NotificationSendingException("Can't send notification " + "to chat: " + sendMessage.getChatId(), e); } } @Override public void onUpdateReceived(Update update) { } @Override public String getBotUsername() { return BOT_USERNAME; } @Override public String getBotToken() { return BOT_TOKEN; } }
Bot配置代码
import application.carsharingapp.service.notification.impl.TelegramNotificationService; 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 TelegramBotConfig { @Bean public TelegramBotsApi telegramBotsApi(TelegramNotificationService telegramNotificationService) throws TelegramApiException { TelegramBotsApi api = new TelegramBotsApi(DefaultBotSession.class); api.registerBot(telegramNotificationService); return api; } }
可行解决方案
1. 用Spring Profiles区分环境配置
给不同环境(开发、CI、生产)单独配置凭证:
- 在
src/main/resources下新建application-ci.properties,填入格式合法的模拟值:
bot.username=mock_ci_bot bot.token=mock_token:abc123 bot.chat-id=mock_chat_123
- 改造代码,用Spring的
@Value注入替代Dotenv直接读取:
@RequiredArgsConstructor @Service public class TelegramNotificationService extends TelegramLongPollingBot implements NotificationService { @Value("${bot.username}") private String botUsername; @Value("${bot.token}") private String botToken; @Value("${bot.chat-id}") private String targetChatId; // 原有方法不变,getBotUsername()返回botUsername,getBotToken()返回botToken }
- CI构建时激活
ciprofile,Spring会自动加载对应配置,避免空值异常。
2. CI环境跳过Bot注册
如果CI阶段不需要实际运行Bot功能,直接跳过注册:
修改配置类,用@Profile注解限制Bean仅在非CI环境创建:
@Configuration public class TelegramBotConfig { @Bean @Profile("!ci") public TelegramBotsApi telegramBotsApi(TelegramNotificationService telegramNotificationService) throws TelegramApiException { TelegramBotsApi api = new TelegramBotsApi(DefaultBotSession.class); api.registerBot(telegramNotificationService); return api; } }
CI构建时激活ci profile,这个Bean就不会被初始化,自然不会触发凭证校验。
3. CI平台直接注入环境变量
主流CI平台(GitHub Actions、GitLab CI等)都支持设置环境变量,你可以在CI配置里添加BOT_USERNAME、BOT_TOKEN、TARGET_CHAT_ID,用模拟值或者专门的测试Bot凭证,这样Dotenv能读取到这些变量,不会为空。
4. 规避模拟凭证的404问题
如果必须保留模拟凭证且要避免发送时的404,在发送方法里判断环境,CI环境直接跳过发送:
@Value("${spring.profiles.active}") private String activeProfile; @Override public void sendNotification(String message) { if ("ci".equals(activeProfile)) { // CI环境下仅记录日志,不实际发送 return; } // 原有发送逻辑不变 }
内容的提问来源于stack exchange,提问作者Yaroslav Radevych-Vynnytskyi
相关产品推荐
相关产品推荐

