使用gram-js调用Telegram API时如何解决STATS_MIGRATE_4错误?
解决gram-js调用GetBroadcastStats时的STATS_MIGRATE_4错误
核心方案:临时切换数据中心调用
Telegram部分频道的统计数据存储在特定数据中心,当客户端默认数据中心(DC)与目标频道的stats_dc不一致时,就会触发303迁移错误。gram-js提供withDc方法可临时切换DC完成调用,无需修改客户端默认配置。
步骤1:获取目标频道的stats_dc(可选,也可从错误中提取)
通过channels.getFullChannel获取频道完整信息,提取统计数据所在的DC编号:
const fullChannel = await client.invoke( new Api.channels.GetFullChannel({ channel: channelId // 传入频道ID/用户名/Peer对象 }) ); const statsDc = fullChannel.fullChat.stats_dc;
步骤2:临时切换DC调用GetBroadcastStats
使用withDc方法切换到目标DC执行统计查询:
const stats = await client.withDc(statsDc, async (dcClient) => { return dcClient.invoke( new Api.stats.GetBroadcastStats({ channel: channelId, dark: true }) ); });
优化方案:自动捕获错误并重试
封装函数自动捕获303错误,提取目标DC后重试,省去手动获取stats_dc的步骤:
async function fetchBroadcastStats(client, channelId) { try { return await client.invoke( new Api.stats.GetBroadcastStats({ channel: channelId, dark: true }) ); } catch (err) { // 判断是否为STATS_MIGRATE类型错误 if (err.code === 303 && err.errorMessage.match(/STATS_MIGRATE_\d+/)) { const targetDc = Number(err.errorMessage.split('_')[1]); // 切换到目标DC重试 return client.withDc(targetDc, async (dcClient) => { return dcClient.invoke( new Api.stats.GetBroadcastStats({ channel: channelId, dark: true }) ); }); } // 非迁移错误直接抛出 throw err; } } // 使用示例 const channelStats = await fetchBroadcastStats(client, 'your_channel_id');
关键说明
withDc方法会临时创建连接到指定DC的客户端实例,调用完成后自动销毁该连接,不改变原客户端的默认DC配置。- 官方API凭证(API ID/哈希)默认支持全DC访问,无需额外配置。
- 若频道为私有,需确保客户端已加入频道或拥有查看统计数据的权限。
内容的提问来源于stack exchange,提问作者Igor Subotin
相关产品推荐
相关产品推荐

