Telegraf.js技术求助:单条消息实现及群发消息故障排查
问题1:如何在Telegraf.js中实现Telegram机器人发送单条消息
有两种常见实现方式:
- 回复当前触发的消息:直接使用
ctx.reply(),自动回复发起交互的用户:// 示例:触发/hello命令时回复 bot.command('hello', (ctx) => { ctx.reply('你好!这是一条单条回复消息'); }); - 主动给指定用户发消息:已知目标用户
chatId时,用ctx.telegram.sendMessage()或bot.telegram.sendMessage():// 示例:主动发送给指定chatId的用户 const targetChatId = 123456789; bot.telegram.sendMessage(targetChatId, '这是主动发送的单条消息');
问题2:群发消息失败的排查与解决
针对你提供的代码,以下是常见问题及修复方案:
1. 触发Telegram API速率限制
Telegram对机器人消息发送频率有严格限制(短时间内最多30条/秒),同步循环发送会快速触发限流,导致后续消息失败。
修复:添加发送间隔,避免触发限流:
for (const row of rows) { console.log(`Sending to chatId: ${row.chatId}`); try { await ctx.telegram.sendMessage(row.chatId, 'Your advertising message is here'); await new Promise(resolve => setTimeout(resolve, 1000)); // 每发一条等待1秒 } catch (userError) { console.error(`Failed to send to ${row.chatId}:`, userError); } }
2. ChatId无效或用户已取关
数据库中的chatId可能格式错误,或是用户已取消关注机器人,导致无法发送。
修复:
- 在循环内单独捕获每个用户的发送错误,记录无效ID并清理:
for (const row of rows) { console.log(`Sending to chatId: ${row.chatId}`); try { await ctx.telegram.sendMessage(row.chatId, 'Your advertising message is here'); await new Promise(resolve => setTimeout(resolve, 1000)); } catch (userError) { console.error(`Failed to send to ${row.chatId}:`, userError.description); // 可选:删除数据库中无效的chatId // await conn.query('DELETE FROM users WHERE chatId = ?', [row.chatId]); } } - 确保数据库中
chatId存储为数字类型(Telegram的chatId是整数,不要存成字符串)。
3. 全局错误捕获中断流程
当前代码的try-catch包裹整个循环,单个用户发送失败会直接终止整个群发,且无法定位具体失败用户。
修复:将try-catch移到循环内部,保证群发不被单个错误中断,同时统计发送结果:
bot.command('sendAd', async (ctx) => { let successCount = 0; let failCount = 0; try { const conn = await db.getConnection(); const [rows] = await conn.query('SELECT * FROM users'); console.log(`共获取${rows.length}个用户`); // 确认数据库返回数据 conn.release(); for (const row of rows) { console.log(`Sending to chatId: ${row.chatId}`); try { await ctx.telegram.sendMessage(row.chatId, 'Your advertising message is here'); await new Promise(resolve => setTimeout(resolve, 1000)); successCount++; } catch (userError) { console.error(`Failed to send to ${row.chatId}:`, userError); failCount++; } } ctx.reply(`广告发送完成:成功${successCount}条,失败${failCount}条`); } catch (error) { console.error('群发初始化出错:', error); ctx.reply('初始化群发时出现错误,请查看日志'); } });
4. 数据库连接或数据异常
确认数据库连接池配置正确,且SELECT * FROM users能返回有效数据。可添加日志验证取出的用户数量:
const [rows] = await conn.query('SELECT * FROM users'); console.log(`共取出${rows.length}个用户`);
内容的提问来源于stack exchange,提问作者Vadim Yanyushkin
相关产品推荐
相关产品推荐

