使用 nodejs 给企业微信发消息

2,489 阅读1分钟

企业微信现在有了群机器人的功能,我们可以和前端工程化相结合,比如把CI/CD信息发送到群里,最常用的是进行eslint的检查,把相关错误发到群里。

发送请求我们直接使用node-fetch这个库, 发送一个markdown格式的消息:


const eslintResult = `3 problems (2 errors, 1 warnings)`;
const data = JSON.stringify({
  msgtype: 'markdown',
  markdown: {
    content: `
### <font color="warning">Lint</font>
>**eslint:** <font color="red">${eslintResult}</font>
`,
  },
});

fetch(groupWebHook, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: data,
});

如果有eslint错误,如何通知具体错误信息呢?可以发送文件,首先要把文件上传到企业微信:

/**
 * 上传文件到企业微信
 * @param {string} filename 要上传的文件名
 * @return Promise<response>
 *
 * response:
 * ```
 * {
 *   errcode: 0,
 *   errmsg: 'ok',
 *   type: 'file',
 *   media_id: '3SHV09itHK5VuTLP8aroW5eihvXyCjQd9XsSh8XixqNc',
 *   created_at: '1590139537'
 * }
 * ```
 */
function uploadFileToEnterpriseWeChat(filename) {
  const url = `https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=${groupWebHookKey}&type=file`;
  const readStream = fs.createReadStream(filename);
  // 如果要修改文件名, 直接修改readStream.path
  // https://www.yinxiang.com/everhub/note/a3f1fe4f-d5bb-449b-98ea-848e77a68a60 参考这篇根据git分支名和hash命名
  // readStream.path = newPath;
  // 上传文件需要使用FormData
  // nodejs里使用FormData:https://github.com/form-data/form-data
  const formData = new FormData();
  formData.append('media', readStream);
  return fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'multipart/form-data',
    },
    body: formData,
  }).then(res => {
    return res.json();
  });
}

上传到企业微信主要是获取到media_id, 发送时需要用到。然后我们发送文件:

/**
 * 发送文件到企业微信群
 * @param {string} media_id 通过上传接口获取的`media_id`
 */
function sendFileToEnterpriseWeChatGroup(media_id) {
  const data = JSON.stringify({
    msgtype: 'file',
    file: {
      media_id,
    },
  });

  return fetch(groupWebHook, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: data,
  });
}

不出意外的话就会收到这样的消息:

获取eslint/typescript错误数和错误详情参考静态代码检查:获取eslint/typescript错误数和错误详情