如何在Telegraf.js中实现仅管理员可见的内联按钮?
Telegraf.js 商城机器人管理员按钮条件渲染修复
问题场景
开发Telegram商城机器人时,需要实现:
- 普通用户启动机器人,显示4个内联按钮:📚 Products、🛒 Cart、🪪 Account、ℹ️ Info
- 当用户ID在配置文件的管理员列表中时,额外显示「Admin Panel」按钮
尝试直接在Context.reply的参数对象中嵌入条件判断展开按钮,出现语法错误。
错误尝试代码
// 错误写法,无法在对象字面量中直接嵌入条件展开 Context.reply("Welcome user", { parse_mode: 'HTML', ...Markup.inlineKeyboard([ Markup.button.callback("📚 Products", "products"), Markup.button.callback("🛒 Cart", "products"), ]), ...Markup.inlineKeyboard([ Markup.button.callback("🪪 Account", "account"), Markup.button.callback("ℹ️ Info", "info"), ]), // 这里的条件写法会导致语法错误 if (Config.administrators.includes(Context.from.id)) { ...Markup.inlineKeyboard([ Markup.button.callback("Admin Panel", "admin") ]), } })
修复方案
不能直接在对象字面量中嵌入条件判断的展开操作,正确做法是提前构建完整的按钮行数组,再生成内联键盘:
const Config = require("./config"); const { writeFileSync } = require('fs'); const { Markup } = require('telegraf'); client.start(async (Context) => { if (Config.bans.includes(Context.chat.id)) return; let user = Config.users.find(usr => usr.id === Context.from.id); if (!user) { Config.users.push({ id: Context.from.id, balance: 0, cart: [] }); writeFileSync("config/index.json", JSON.stringify(Config)); } // 构建按钮行数组 const buttonRows = [ // 第一行按钮 [ Markup.button.callback("📚 Products", "products"), Markup.button.callback("🛒 Cart", "cart") // 修复原代码callback值错误 ], // 第二行按钮 [ Markup.button.callback("🪪 Account", "account"), Markup.button.callback("ℹ️ Info", "info") ] ]; // 判断是否为管理员,添加第三行按钮 if (Config.administrators.includes(Context.from.id)) { buttonRows.push([ Markup.button.callback("Admin Panel", "admin") ]); } // 生成内联键盘并发送消息 Context.reply("Welcome user", { parse_mode: 'HTML', ...Markup.inlineKeyboard(buttonRows) }); })
关键说明
- 先初始化普通用户的按钮行数组,再通过条件判断向数组中追加管理员专属按钮行,避免在对象字面量中嵌入非法语法
- 修复了原代码中「🛒 Cart」按钮的callback值错误(原代码写的是"products",应改为"cart")
- 统一通过
Markup.inlineKeyboard(buttonRows)生成完整的内联键盘配置,确保语法正确
内容的提问来源于stack exchange,提问作者Giacca
相关产品推荐
相关产品推荐

