You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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构建时激活ci profile,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 16:24:50