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

如何用Telegram Bot API获取机器人加入的聊天列表(Node.js+Axios)

如何通过Telegram Bot API获取机器人已加入的所有聊天名称列表

我正在使用Node.js和Axios开发Telegram机器人,通过Telegram Bot API进行交互。我需要获取机器人已加入的所有聊天名称列表,目前已能调用getUpdates和getChat方法获取更新及聊天信息,现有代码如下:

const axios = require('axios');

const botToken = process.env.BOT_TOKEN;
const apiUrl = `https://api.telegram.org/bot${'botToken'}`; // 此处存在错误,应改为${botToken}

const getUpdates = async () => {
  try {
    const response = await axios.get(`${apiUrl}/getUpdates`);
    return response.data;
  } catch (err) {
    console.error(err);
    throw err
  }
};
const getChat = async (chatId) => {
  try {
    const response = await axios.get(`${apiUrl}/getChat`, {
        params: {
            chat_id: chatId,
        },
    });
    return response.data;
  } catch (err) {
    console.error(err);
    throw err
  }
}

module.exports = {getUpdates, getChat}

请问:

  1. 如何通过getUpdates方法获取机器人已加入的所有聊天列表?
  2. 如何提取这些聊天的名称?
  3. 最佳实现方式是什么?
  4. 获取该信息存在哪些潜在问题或限制?

先修正现有代码的明显错误

你的apiUrl定义存在语法问题,模板字符串里的${'botToken'}是字符串字面量,无法注入环境变量中的令牌,应修改为:

const apiUrl = `https://api.telegram.org/bot${botToken}`;

1. 通过getUpdates获取聊天列表的方法

getUpdates返回机器人收到的最近更新记录,每条更新的message、callback_query等字段中都会包含chat对象(或嵌套在message.chat中)。具体步骤:

  • 遍历所有更新条目,提取其中的chat.id
  • 对提取到的chat.id去重,避免重复处理同一个聊天
  • 用去重后的chat.id列表调用getChat获取完整聊天信息

示例实现:

const getAllChatsFromUpdates = async () => {
  const updates = await getUpdates();
  if (!updates.ok || !updates.result.length) {
    return [];
  }

  // 提取所有唯一的chat_id,兼容不同类型的更新字段
  const uniqueChatIds = [...new Set(updates.result.map(item => {
    return item.message?.chat?.id || item.callback_query?.message?.chat?.id || '';
  }).filter(id => id))];

  // 批量并行获取聊天信息
  const chatPromises = uniqueChatIds.map(chatId => getChat(chatId));
  const chatResults = await Promise.all(chatPromises);

  // 筛选成功返回的聊天数据
  return chatResults.filter(res => res.ok).map(res => res.result);
};

2. 提取不同类型聊天的名称

Telegram聊天分为私人聊天、群组/超级群组、频道三类,不同类型的名称字段不同:

  • 私人聊天:使用first_name,若存在last_name则拼接为完整名称
  • 群组/超级群组/频道:直接使用title字段

提取名称的工具函数:

const getChatDisplayName = (chat) => {
  switch (chat.type) {
    case 'private':
      return `${chat.first_name}${chat.last_name ? ` ${chat.last_name}` : ''}`;
    case 'group':
    case 'supergroup':
    case 'channel':
      return chat.title;
    default:
      return '未知聊天';
  }
};

// 使用示例
const chats = await getAllChatsFromUpdates();
const chatNames = chats.map(chat => getChatDisplayName(chat));
console.log('所有聊天名称:', chatNames);

3. 最佳实现方式

  • 强制去重:必须对chat_id去重,避免重复调用getChat浪费API配额
  • 处理更新偏移量:调用getUpdates时传入offset参数,标记已处理的更新,避免重复获取旧数据
  • 改用Webhook:长期运行的机器人优先使用Webhook,实时接收更新,避免轮询遗漏新聊天
  • 缓存聊天信息:定期更新聊天列表,无需每次都调用API,减少请求次数
  • 容错处理:对getChat的失败请求做降级处理(比如跳过无效chat_id)

优化后的带偏移量的getUpdates:

const getUpdatesWithOffset = async (offset = 0) => {
  try {
    const response = await axios.get(`${apiUrl}/getUpdates`, {
      params: { offset, limit: 100 } // limit最大值为100,符合API限制
    });
    return response.data;
  } catch (err) {
    console.error(err);
    throw err;
  }
};

4. 潜在问题与限制

  • 更新历史限制:getUpdates最多返回最近100条更新,若机器人加入的聊天长期无消息(如静音群组),不会出现在更新结果中,导致无法获取
  • 权限限制:若机器人被加入群组但无消息读取权限,或私人聊天用户未给机器人发过消息,这类聊天不会出现在更新中
  • API速率限制:Telegram Bot API有调用频率限制(如getChat最多每秒30次),批量请求需控制速率,避免被限流
  • 已退出聊天残留:机器人被踢出聊天后,getUpdates不会主动移除该聊天记录,需通过getChat返回的404错误检测并清理
  • 更新丢失风险:轮询getUpdates间隔过长时,可能漏掉超过24小时保留期限的更新(Telegram服务器仅保留最近24小时的更新)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 15:07:26