如何使用钉钉的自定义群机器人

386 阅读1分钟

为了简化发版部署流程,我借助sf-inner-service把公司运维网站的一部分能力实现在本地,并做了亿点点优化。

那么这个时候就来到了部署完之后通过钉钉机器人让测试审批的功能

接下来的代码时加了签的,markdown格式

前端工具类 UDing

import { message } from "antd";
import cryptoJS from "crypto-js";
import SBase from "../service/SBase";

/**
 * 文档地址 https://open.dingtalk.com/document/robots/custom-robot-access
 */

namespace UDing {
  export async function sendLink(
    webhook: string,
    secret: string,
    atMobiles: string[],
    markdown: object,
    isAtAll = false
  ) {
    const url = getSecretWebhook(webhook, secret);
    const rsp = await SBase.sendDingMsg(url, {
      msgtype: "markdown",
      markdown,
      at: {
        atMobiles,
        isAtAll,
      },
    });

    if (rsp.success) {
      message.success("发送钉钉消息成功");
    } else {
      message.error(rsp.message);
    }
  }
  export function getSecretWebhook(webhook: string, secret: string) {
    const timestamp = Date.now();
    let hash = cryptoJS
      .HmacSHA256(`${timestamp}\n${secret}`, secret)
      .toString();
    const base64 = Buffer.from(hash, "hex").toString("base64");

    return (
      webhook +
      "&timestamp=" +
      timestamp +
      "&sign=" +
      encodeURIComponent(base64)
    );
  }
}

export default UDing;

在markdown类型中,title是显示在左侧,text才是真正显示在群里面的内容,两者不会一起出现的

image.png

使用如下

        UDing.sendLink(iteratives.webhook, iteratives.secret, atPhoneList, {
          title: "您有项目需要审批",
          text: `
         \n ### ${atPhoneList
           .map((phone) => "@" + phone)
           .join(";")}  ${envName}环境 [去审批](${
            MDDevops.config.devopsAjaxPrefx + MDDevops.config.devopsDeployPath
          })\n\n
          \n 审批id:**${auditId}** \n 
          \n发起人:${MDDevops.developPerson.personName}
          \n更新内容:\n${values.content}\n`,
        });

后端node.js代码,sendDingMsg

(function () {
  return function (argData, argParams, external) {
    const axios = require("axios");

    axios.post(argParams.url, argParams.data, {}).then((rsp) => {
      const { errcode, errmsg } = rsp.data;
      if (errcode === 0) {
        external.response.end(
          JSON.stringify({
            success: true,
          })
        );
      } else {
        external.response.end(
          JSON.stringify({
            success: false,
            message: errmsg,
          })
        );
      }
    });
    return {
      async: true,
      response: {
        code: 200,
      },
    };
  };
})();

因为直接用浏览器发送是会跨域的