如何用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>
你的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(); }
重写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
相关产品推荐
相关产品推荐

