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

tmi.js开发Twitch机器人如何正确获取礼物订阅数量实现条件回复

问题背景

基于tmi.js为Twitch平台开发聊天机器人,实现礼物订阅响应功能时遇到如下问题:

  • 现有代码在用户单次赠送1个订阅时运行正常,但用户一次性赠送多个订阅(例如10个)时,机器人会对应发送10条单份赠礼感谢消息,交互体验差
  • 目标是获取用户本次赠送的订阅总数量,添加条件判断逻辑,当赠送数量大于1时发送适配批量赠礼场景的专属消息
  • 前期尝试通过const senderCount = userstate["msg-param-sender-count"]获取赠礼数量,返回结果为false;改用const senderCount = ~~userstate["msg-param-sender-count"]取值时仅返回0

现有功能代码如下:

client.on('subgift', (channel, username, streakMonths, recipient, methods, userstate) => {
  subGiftHandler(channel, username, streakMonths, recipient, methods, userstate)
})

function subGiftHandler(channel, username, streakMonths, recipient, methods, userstate) {
  client.say(channel,
    `Thank you @${username} for gifting a sub to ${recipient}.`
  )
}
解决方案

问题核心原因有两点:

  • subgift事件会为每一份被赠送的订阅单独触发一次,用户一次赠送10个订阅就会连续触发10次事件,直接在事件回调里发消息必然会重复发送10条
  • 你读取的msg-param-sender-count字段是该用户历史累计给当前频道赠送的订阅总数量,不是本次批量赠送的数量,且该字段仅在用户累计赠礼数达到平台阈值时才会返回,未返回时自然会拿到false。

按以下步骤修复即可:

  1. 先升级本地tmi.js到最新版本,1.8.5以前的版本没有正确解析Twitch返回的批量赠礼专属字段msg-param-mass-gift-count,执行npm install tmi.js@latest完成升级
  2. 增加短时间窗口的缓存做事件聚合,避免同一次批量赠礼触发多次消息发送;当msg-param-mass-gift-count字段存在且值大于1时,判定为批量赠礼场景,等待窗口期结束后统一发送批量感谢消息,单份赠礼走原有逻辑即可。

修复后的完整代码:

// 暂存批量赠礼数据的缓存
const giftBatchCache = new Map()
// 批量聚合等待时长,单位毫秒,Twitch同一次批量赠礼的事件间隔通常在1s以内,设3s足够覆盖
const BATCH_WAIT_TIME = 3000

client.on('subgift', (channel, username, streakMonths, recipient, methods, userstate) => {
  subGiftHandler(channel, username, streakMonths, recipient, methods, userstate)
})

function subGiftHandler(channel, username, streakMonths, recipient, methods, userstate) {
  // 优先读取批量赠礼总数字段,不存在则默认为单份赠礼
  const giftTotal = Number(userstate["msg-param-mass-gift-count"]) || 1
  const cacheKey = `${channel}:${username}`

  // 批量赠礼场景走聚合逻辑
  if (giftTotal > 1) {
    // 缓存中已有同批次记录则直接追加收件人,不触发消息发送
    if (giftBatchCache.has(cacheKey)) {
      const currentBatch = giftBatchCache.get(cacheKey)
      currentBatch.recipients.push(recipient)
      return
    }
    // 无记录则新建批次缓存
    giftBatchCache.set(cacheKey, {
      total: giftTotal,
      recipients: [recipient],
      channel: channel
    })
    // 等待窗口期结束后发送统一感谢消息
    setTimeout(() => {
      const batch = giftBatchCache.get(cacheKey)
      client.say(channel, `@${username} 一次性赠送了${batch.total}个订阅!欢迎所有新加入频道的订阅用户🎉`)
      // 发送完成后清除对应缓存
      giftBatchCache.delete(cacheKey)
    }, BATCH_WAIT_TIME)
    return
  }

  // 单份赠礼沿用原有感谢逻辑
  client.say(channel, `Thank you @${username} for gifting a sub to ${recipient}.`)
}

注意事项:

  • 3秒的聚合窗口可以根据实际使用场景调整,不要设置过长避免消息发送延迟过高
  • 如果需要在批量感谢消息里@所有获赠用户,直接读取缓存里的recipients数组拼接即可
  • 若要统计用户历史累计赠礼数,再去读取msg-param-sender-count字段,注意做非空判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 04:15:55