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

如何用Java实现Telegram@ShopBot式Inline Button触发UI的机器人?

嘿,很高兴你对开发类似ShopBot的Telegram机器人感兴趣!我来一步步帮你实现点击Inline Button触发表单UI的功能,假设你用的是Java生态里的java-telegram-bot-api库(这是最常用的Java Telegram Bot开发工具),以下是具体实现步骤:

1. 先搞定项目依赖(以Maven为例)

首先要在你的项目里引入Telegram Bot API的依赖,在pom.xml中添加:

<dependency>
    <groupId>org.telegram</groupId>
    <artifactId>telegrambots</artifactId>
    <version>6.9.7</version>
</dependency>
2. 创建并发送带Inline Button的消息

你的Bot类需要继承TelegramLongPollingBot,然后编写代码生成包含"Pay $142"按钮的消息并发送给用户:

// 构造"Pay $142"按钮
InlineKeyboardButton payButton = new InlineKeyboardButton();
payButton.setText("Pay $142");
// 设置唯一的回调标识,用来区分不同按钮,这里我们用"TRIGGER_PAY_FORM_142"
payButton.setCallbackData("TRIGGER_PAY_FORM_142");

// 将按钮组装成内联键盘
InlineKeyboardMarkup keyboardMarkup = new InlineKeyboardMarkup();
keyboardMarkup.setKeyboard(Collections.singletonList(Collections.singletonList(payButton)));

// 构造发送消息
SendMessage sendMessage = new SendMessage();
sendMessage.setChatId(chatId); // chatId是目标用户/群组的ID
sendMessage.setText("需要支付订单费用,请点击下方按钮:");
sendMessage.setReplyMarkup(keyboardMarkup);

// 发送消息
try {
    execute(sendMessage);
} catch (TelegramApiException e) {
    e.printStackTrace();
}
3. 处理Inline Button的点击回调

重写onUpdateReceived方法,监听用户的按钮点击事件,识别回调后触发表单显示:

@Override
public void onUpdateReceived(Update update) {
    // 检查是否是Inline Button的回调请求
    if (update.hasCallbackQuery()) {
        CallbackQuery callbackQuery = update.getCallbackQuery();
        String callbackData = callbackQuery.getData();
        long chatId = callbackQuery.getMessage().getChatId();
        int messageId = callbackQuery.getMessage().getMessageId();

        // 匹配我们设置的支付按钮回调标识
        if ("TRIGGER_PAY_FORM_142".equals(callbackData)) {
            // 触发显示支付表单的逻辑
            displayPaymentForm(chatId, messageId);
            
            // 回复回调,让用户看到按钮已被点击(避免一直显示加载状态)
            AnswerCallbackQuery answerCallback = new AnswerCallbackQuery();
            answerCallback.setCallbackQueryId(callbackQuery.getId());
            answerCallback.setText("正在加载支付表单...");
            try {
                execute(answerCallback);
            } catch (TelegramApiException e) {
                e.printStackTrace();
            }
        }
    }
}
4. 实现表单UI的展示

这里我们通过编辑原来的消息来替换成表单内容,也可以发送新消息。表单可以用内联按钮配合文本提示,引导用户填写信息:

private void displayPaymentForm(long chatId, int messageId) {
    // 编辑原有消息,替换为表单内容
    EditMessageText editMessage = new EditMessageText();
    editMessage.setChatId(chatId);
    editMessage.setMessageId(messageId);
    editMessage.setText("请完成以下支付信息填写:\n" +
            "*1. 持卡人姓名*\n" +
            "*2. 银行卡号*\n" +
            "*3. 有效期(格式:MM/YY)*");

    // 添加表单操作按钮:提交、取消
    InlineKeyboardButton submitBtn = new InlineKeyboardButton("提交信息");
    submitBtn.setCallbackData("SUBMIT_PAY_INFO");
    InlineKeyboardButton cancelBtn = new InlineKeyboardButton("取消支付");
    cancelBtn.setCallbackData("CANCEL_PAYMENT");

    InlineKeyboardMarkup formKeyboard = new InlineKeyboardMarkup();
    formKeyboard.setKeyboard(Arrays.asList(
            Collections.singletonList(submitBtn),
            Collections.singletonList(cancelBtn)
    ));
    editMessage.setReplyMarkup(formKeyboard);

    try {
        execute(editMessage);
    } catch (TelegramApiException e) {
        e.printStackTrace();
    }
}
5. 收集用户的表单输入(可选)

如果需要收集用户输入的文本信息,你可以维护一个用户状态映射,记录每个用户当前处于表单的哪个步骤,然后在onUpdateReceived中处理用户的普通消息:

// 用Map记录用户当前的表单状态,比如"WAITING_NAME"、"WAITING_CARD_NO"
private Map<Long, String> userFormStatus = new ConcurrentHashMap<>();

@Override
public void onUpdateReceived(Update update) {
    // 先处理回调,再处理普通消息
    if (update.hasCallbackQuery()) {
        // ... 之前的回调处理逻辑
        // 当用户点击"提交信息"按钮时,切换状态到等待姓名输入
        else if ("SUBMIT_PAY_INFO".equals(callbackData)) {
            userFormStatus.put(chatId, "WAITING_NAME");
            SendMessage prompt = new SendMessage(chatId, "请输入持卡人姓名:");
            execute(prompt);
        }
    } else if (update.hasMessage() && update.getMessage().hasText()) {
        long userId = update.getMessage().getFrom().getId();
        String currentStatus = userFormStatus.get(userId);
        String userInput = update.getMessage().getText();

        if ("WAITING_NAME".equals(currentStatus)) {
            // 保存姓名(可以存在数据库或内存中)
            // 切换状态到等待卡号输入
            userFormStatus.put(userId, "WAITING_CARD_NO");
            SendMessage prompt = new SendMessage(userId, "请输入银行卡号:");
            execute(prompt);
        } else if ("WAITING_CARD_NO".equals(currentStatus)) {
            // 保存卡号,切换到等待有效期
            userFormStatus.put(userId, "WAITING_EXPIRY");
            SendMessage prompt = new SendMessage(userId, "请输入有效期(格式:MM/YY):");
            execute(prompt);
        }
        // 完成所有步骤后,清除用户状态,处理支付逻辑
    }
}
最后补充几点
  • 记得在你的Bot类中实现getBotUsername()和getBotToken()方法,返回你在BotFather那里申请的机器人用户名和Token。
  • 生产环境中,建议用数据库存储用户的表单数据和状态,而不是内存中的Map。
  • 如果需要更复杂的表单,可以考虑用Telegram的ForceReply功能,强制用户回复消息。

内容的提问来源于stack exchange,提问作者lemmy njaria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:36:28