开发TikTok开播通知Discord Bot时反复出现两类错误的解决求助
Hey 👋,看你说做TikTok开播通知的Discord Bot时老是被两类错误来回困扰,还怀疑和TypeScript严格模式有关,作为刚接触Discord Bot的新手确实容易踩这类坑,我来帮你梳理下可能的问题点和解决方向:
首先,你的代码目前是用CommonJS语法写的,但如果是在TypeScript严格模式项目下,确实会触发不少类型相关的报错,再加上代码里有一些潜在的空值访问问题,就会出现“改完一个错又冒出来另一个”的情况。下面是具体的分析和调整建议:
1. 先解决TypeScript严格模式下的类型缺失问题
严格模式下TS会强制要求变量有明确类型,你当前解析JSON后直接用json.title、json.owner.nickname这类属性,TS会认为它们是any类型,或者会报错“可能未定义”。建议先给TikTok返回的直播间数据定义类型接口:
// 定义TikTok直播间数据的类型接口 interface TikTokRoomInfo { title: string; owner: { nickname: string; }; cover: { url_list: string[]; }; game_tag: Array<{ show_name: string }>; user_count: string | number; share_url: string; // 可以根据实际返回数据补充其他字段 }
然后在解析JSON时断言类型,让TS知道这个对象的结构:
const json = JSON.parse(body) as TikTokRoomInfo;
2. 处理潜在的空值/未定义风险
TS严格模式会严格检查可能出现的undefined或空值访问,比如你代码里的json.game_tag[0].show_name,如果game_tag是空数组,直接访问索引0就会报错。要给这类可能为空的地方加判断:
// 处理游戏标签的空值情况 const gameName = json.game_tag.length > 0 ? json.game_tag[0].show_name : '未设置游戏'; // 处理封面图的空值情况 const coverUrl = json.cover.url_list.length > 0 ? json.cover.url_list[0] : '';
3. 统一模块导入方式(针对TS项目)
Discord.js v14+更推荐使用ES模块(import语法),如果你的项目是TS项目,建议把所有require改成import,同时在package.json里添加"type": "module",或者在TS配置文件tsconfig.json里把module设置为CommonJS,避免混合模块语法导致的报错。
4. 给Webhook参数补充类型断言
从webhook-config.json导入的webhookId和webhookToken,TS严格模式下会认为它们是any类型,建议添加类型断言明确类型:
const webhookClient = new WebhookClient({ id: webhookId as string, token: webhookToken as string });
5. 优化错误捕获逻辑
现在你的catch只打印错误消息,建议打印完整的错误对象,这样能看到更详细的报错堆栈,方便精准定位问题:
catch (error) { console.error('解析直播间信息或发送通知时出错:', error); }
另外还有个逻辑小问题:你当前的代码只请求一次直播间信息,这样只能检测一次状态。应该做成定时轮询(比如每5分钟请求一次),记录上次的直播状态,只有当从“未开播”变成“开播”时才发送通知,避免重复刷屏。比如可以加个状态变量:
// 记录上次的直播状态 let wasLive = false; // 每5分钟轮询一次直播间状态 setInterval(() => { http.get(url_roominfo, res => { let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => { try { const json = JSON.parse(body) as TikTokRoomInfo; // 根据返回数据判断当前是否在直播(需要你确认TikTok返回的直播状态字段) const isLive = /* 比如 json.is_live 或者根据user_count等字段判断 */; if (isLive && !wasLive) { // 只有第一次检测到开播时才发送通知 webhookClient.send({ content: '@everyone ' + json.owner.nickname + ' is live now', components: [row], embeds: [embed], }); wasLive = true; } else if (!isLive && wasLive) { // 直播结束时重置状态 wasLive = false; } } catch (error) { console.error(error); } }); }).on('error', error => console.error(error.message)); }, 5 * 60 * 1000); // 5分钟间隔,单位毫秒
如果能把具体的错误信息贴出来(比如类型错误提示、运行时报错内容),能更精准地帮你定位问题哦!
备注:内容来源于stack exchange,提问作者user28169474

