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

Telegram Bot Java自定义计算器键盘 实现完整数字输入后发送消息问询

解决Telegram Bot数字键盘输入完整数字后再发送的问题

嘿,我懂你的困扰——现在每次点数字按钮都会直接发一条单独的消息,想输入1000却连发四条消息,完全不是想要的效果对吧?其实核心思路就是给每个用户维护一个临时的输入缓冲区,把点击的数字先存起来,等用户确认发送的时候再一次性提交。下面是具体的实现方案,适配你用的Java Telegram Bot API:

一、核心思路拆解

  1. 用户输入隔离:每个用户的输入是独立的,用一个Map来存储每个用户ID对应的当前输入字符串。
  2. 键盘扩展:在原有数字键盘基础上添加「发送」和「清空」按钮,让用户能主动触发提交或重置操作。
  3. 按钮点击逻辑重写:数字按钮不再直接发送消息,而是追加到缓冲区;功能按钮负责提交或清空缓冲区内容。

二、完整代码实现

1. 定义全局输入缓冲区

首先需要一个线程安全的Map来存储用户的临时输入,避免多用户操作时出现冲突:

// 用ConcurrentHashMap保证线程安全,key是用户的ChatId,value是当前输入的数字字符串
private Map<Long, String> userInputBuffer = new ConcurrentHashMap<>();

2. 重构键盘布局

给数字键盘添加功能按钮行,方便用户操作:

ReplyKeyboardMarkup keyBoardMarkup = new ReplyKeyboardMarkup();
keyBoardMarkup.setResizeKeyboard(true); // 让键盘自适应屏幕大小
List<KeyboardRow> keyboard = new ArrayList<>();

// 第一行:1、2、3
KeyboardRow row1 = new KeyboardRow();
row1.add("1");
row1.add("2");
row1.add("3");
keyboard.add(row1);

// 第二行:4、5、6
KeyboardRow row2 = new KeyboardRow();
row2.add("4");
row2.add("5");
row2.add("6");
keyboard.add(row2);

// 第三行:7、8、9
KeyboardRow row3 = new KeyboardRow();
row3.add("7");
row3.add("8");
row3.add("9");
keyboard.add(row3);

// 第四行:0、清空、发送
KeyboardRow row4 = new KeyboardRow();
row4.add("0");
row4.add("清空");
row4.add("发送");
keyboard.add(row4);

keyBoardMarkup.setKeyboard(keyboard);

3. 处理按钮点击逻辑

在消息处理方法里,判断用户点击的是数字还是功能按钮,执行对应的操作:

@Override
public void onUpdateReceived(Update update) {
    if (update.hasMessage() && update.getMessage().hasText()) {
        Long userId = update.getMessage().getChatId();
        String inputText = update.getMessage().getText();

        // 处理数字按钮点击
        if (inputText.matches("[0-9]")) {
            // 从缓冲区取出当前输入,没有则为空字符串
            String currentInput = userInputBuffer.getOrDefault(userId, "");
            // 追加新数字
            currentInput += inputText;
            userInputBuffer.put(userId, currentInput);
            // 给用户反馈当前输入状态
            sendReplyMessage(userId, "当前输入:" + currentInput, keyBoardMarkup);
        } 
        // 处理清空按钮
        else if (inputText.equals("清空")) {
            userInputBuffer.remove(userId);
            sendReplyMessage(userId, "已清空输入,请重新输入~", keyBoardMarkup);
        } 
        // 处理发送按钮
        else if (inputText.equals("发送")) {
            String fullNumber = userInputBuffer.getOrDefault(userId, "");
            if (fullNumber.isEmpty()) {
                sendReplyMessage(userId, "还没输入数字哦,请先点击数字按钮~", keyBoardMarkup);
            } else {
                // 这里可以把完整数字发送到目标聊天,或者做后续处理
                sendReplyMessage(userId, "你输入的完整数字是:*" + fullNumber + "*", keyBoardMarkup);
                // 发送完成后清空缓冲区
                userInputBuffer.remove(userId);
            }
        } 
        // 处理其他非键盘输入
        else {
            sendReplyMessage(userId, "请使用下方的数字键盘输入哦", keyBoardMarkup);
        }
    }
}

// 封装发送消息的工具方法,避免重复代码
private void sendReplyMessage(Long chatId, String text, ReplyKeyboardMarkup keyboard) {
    SendMessage message = new SendMessage();
    message.setChatId(chatId.toString());
    message.setText(text);
    message.setParseMode(ParseMode.MARKDOWN); // 支持Markdown格式强调
    message.setReplyMarkup(keyboard);
    try {
        execute(message);
    } catch (TelegramApiException e) {
        e.printStackTrace();
    }
}

三、额外优化建议

  • 增加删除按钮:可以在键盘里加一个「删除」按钮,实现删除最后一位数字的功能,提升用户体验。
  • 输入超时清理:如果用户长时间不操作,可以定时清理缓冲区里的无效输入,避免内存浪费。
  • 分布式场景适配:如果你的Bot是多实例部署,ConcurrentHashMap就不够用了,建议用Redis等分布式存储来保存用户输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:31:23