node服务发送文本消息或图片

# 示例


An image

# 实现思路

微信网页版?被禁止登录了!钉钉群机器人?需要用户资格!短信?可以展示的内容太少,而且需要 💰

最后退而求其次,选择了 telegram,可以实现通过电报机器人发送消息给电报群,也可以私发消息给用户

  • 需要注意的是,telegram 的使用是需要梯子的,所以需要服务器上我先配置了一个代理服务,这里我使用的是 v2ray ,而且只对 6009 端口的 http 请求进行了代理

  • 生成一个代理实例

/** 代理相关 */
export const agentPort = isProd ? '6009' : '1087';
export const proxyUrl = `http://127.0.0.1:${agentPort}`; // V2Ray 本地代理地址和端口
export const agent = new HttpsProxyAgent(proxyUrl);
  • 写一个发送 telegram 消息的方法,这个方法我为了避免代理生效导致 fetch 一直请求,所以设置了一个 race,超时就停止发送
/** 发送文本信息 */
export const sendMessage = async (
  message,
  parseMode = 'HTML',
  chatId = '需要接受消息的电报群id或者用户id',
  token = '发送消息的当前bot对应的token',
) => {
  const timeoutPromise = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), telegramSendMessageTimeOut),
  );

  try {
    const fetch = await loadFetch();

    const fetchPromise = fetch(
      `https://api.telegram.org/bot${token}/sendMessage`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          chat_id: chatId,
          text: message,
          parse_mode: parseMode,
        }),
        agent,
      },
    ).then(async (response) => {
      const { ok: success } = await response.json();
      if (success) {
        log('消息发送成功');
        return true;
      }
      return false;
    });

    return await Promise.race([fetchPromise, timeoutPromise]);
  } catch (error) {
    if (error.message === 'Timeout') {
      log('消息发送失败: 超时');
    } else {
      log('消息发送失败:', error);
    }
    return false;
  }
};
  • 同理,发送图片也是可以的
/** 发送图片 */
export const sendPhoto = async (
  filePath,
  caption = '',
  chatId = '需要接受消息的电报群id或者用户id',
  token = '发送消息的当前bot对应的token',
) => {
  const timeoutPromise = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), telegramSendMessageTimeOut),
  );

  try {
    const fetch = await loadFetch();

    const fetchPromise = fetch(
      `https://api.telegram.org/bot${token}/sendPhoto?chat_id=${chatId}&photo=${filePath}&caption=${caption}`,
      {
        method: 'GET',
        agent,
      },
    ).then(async (response) => {
      const { ok: success } = await response.json();
      if (success) {
        log('photo发送成功');
        return true;
      }
      return false;
    });

    return await Promise.race([fetchPromise, timeoutPromise]);
  } catch (error) {
    if (error.message === 'Timeout') {
      log('photo发送失败: 超时');
    } else {
      log('photo发送失败:', error);
    }
    return false;
  }
};