
本文详解 telegram bot 使用 parse_mode: "html" 发送动态生成的 html 字符串时,因数组未正确拼接导致“message text is empty”错误的根本原因与解决方案,包含安全拼接、空数据防御及格式优化实践。
本文详解 telegram bot 使用 parse_mode: "html" 发送动态生成的 html 字符串时,因数组未正确拼接导致“message text is empty”错误的根本原因与解决方案,包含安全拼接、空数据防御及格式优化实践。
在使用 node-telegram-bot-api 发送 HTML 格式消息时,一个常见误区是直接将 Array.map() 返回的数组传入 bot.sendMessage() —— 这会导致实际传递的是 JavaScript 数组(如 ["1. 65a1b2c3...", "2. 65a1b2d4..."]),而非拼接后的字符串。Telegram API 严格校验 text 字段:若传入数组或空字符串,会立即抛出 400 Bad Request: message text is empty 错误,正如你遇到的日志所示。
根本问题在于:
inviters.map(...) 返回的是数组,而 bot.sendMessage() 的 text 参数必须是字符串。即使启用了 parse_mode: "HTML",Telegram 也不会自动调用 .toString();它只解析字符串内容中的 HTML 标签。
✅ 正确做法是使用 .join() 显式拼接:
User.find({ Inviter: helpers.getUserID(query) })
.then(inviters => {
console.log('Found users:', inviters);
// ✅ 安全拼接:空数组时返回提示语,避免空消息
if (inviters.length === 0) {
return bot.sendMessage(chatID, '⚠️ 暂无关联用户', { parse_mode: 'HTML' });
}
// ✅ 生成带序号的 HTML 列表项,并用 <br> 换行(Telegram HTML 支持有限,<br> 是换行首选)
const htmlList = inviters.map((user, index) =>
`${index + 1}. <code>${user._id}</code>`
).join('<br>');
// ✅ 组装完整消息(支持加标题、强调等)
const fullMessage = `? 共找到 ${inviters.length} 位用户:<br><br>${htmlList}`;
return bot.sendMessage(chatID, fullMessage, { parse_mode: 'HTML' });
})
.catch(err => {
console.error('Failed to send user list:', err);
bot.sendMessage(chatID, '❌ 获取用户列表失败,请稍后重试。', { parse_mode: 'HTML' });
});? 关键注意事项:
立即学习“前端免费学习笔记(深入)”;
-
换行必须用
:Telegram 的 HTML 模式不支持、
或 \n,仅
可生效;- 特殊字符需转义:若 user._id 或其他字段含 , &,建议用 escapeHtml() 函数处理(例如:user._id.replace(/&/g, '&').replace(/, '<').replace(/>/g, '>'));
- 避免纯空格/空白字符串:.join('
') 在空数组时返回空字符串,务必前置长度判断;标签提升可读性:对 _id 等长字符串使用可防止折行错乱,且视觉更清晰;- 不要依赖模板字面量隐式转换:像 `${html}` 对数组会调用默认 toString()(逗号分隔),这既不符合 HTML 语义,也易被误认为格式缺陷。
? 进阶建议:
若用户量较大(>50),考虑分页或发送为 .txt 文件附件,避免单消息超限(Telegram 文本消息上限为 4096 字符);同时建议添加加载状态(如 bot.sendChatAction(chatID, 'typing'))提升用户体验。通过规范拼接、主动防御空数据、合理使用 Telegram 支持的 HTML 子集,即可稳定输出结构化、易读的用户列表消息。



















