Zabbix 企业微信内部应用发送告警

Zabbix 企业微信内部应用发送告警

发表于 2022/04/10 更新于 2022/04/10 602 字 3 分钟
AI 摘要 由 AI 自动生成

|

我有一个 Zabbix 是收 HomeLab 告警的,之前注册了一个企业微信拉了个群通过 Bot 去发告警,但是因为工作也是使用企业微信,基本上我都在我的主企业里,企业微信有个特性是不提醒其他企业的具体消息,搞得我上周漏掉了服务器硬盘挂了告警,本来是周四就告警预故障了,结果周六才看到。好在网上能买到备件,周日到货完成了更换,才没有出现两块硬盘接连“寄”掉的事情发生。

从这件事情之后,我就想如何换一种告警渠道,避免看不到告警的情况出现。最后发现可以在企业微信中添加内部应用,结合微信企业号去推送告警。

添加企业微信应用

应用管理创建一个应用,并获取到 Secret 和 AgentId。这里的 Secret 对应后面的 Corpsecret。 20220409221403

微信添加微信插件(原企业号)

之前以为企业号=企业微信,最近再翻管理后台发现企业号变成了微信插件。我们可以在我的企业->微信插件中获得二维码并关注。

20220409220634

增加报警媒介类型

增加一种报警媒介,类型是 WebHook,参数如下填写:

参数参数说明
Agentid应用的 ID
Corpid企业 ID术语说明-corpid
Corpsecret应用的凭证密钥术语说明-secret
Subject告警主题{ALERT.SUBJECT}
Message告警内容{ALERT.MESSAGE}
To告警接收人{ALERT.SENDTO}

20220409214306

脚本如下:

var weworkApp = {
  touser: null,
  message: null,
  corpid: null,
  corpsecret: null,
  agentid: null,
  proxy: null,
  msgtype: "text",

  // 获取企业微信 AccessToken
  getAccessToken: function () {
    var url =
        "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" +
        weworkApp.corpid +
        "&corpsecret=" +
        weworkApp.corpsecret,
      request = new CurlHttpRequest();

    // 设置代理
    if (weworkApp.proxy) {
      request.setProxy(weworkApp.proxy);
    }
    request.AddHeader("Content-Type: application/json");
    response = request.Get(url);
    try {
      response = JSON.parse(response);
      return response.access_token;
    } catch (error) {
      response = null;
    }
    if (request.Status() !== 200 || response.errcode !== 0) {
      if (typeof response.errmsg === "string") {
        throw response.errmsg;
      } else {
        throw "Unknown error. Check debug log for more information.";
      }
    }
  },

  // 发消息
  sendMessage: function (access_token) {
    var params = {
        touser: weworkApp.touser,
        agentid: weworkApp.agentid,
        msgtype: weworkApp.msgtype,
        text: {
          content: weworkApp.message,
        },
        enable_duplicate_check: 1,
        duplicate_check_interval: 20,
      },
      data,
      response,
      request = new CurlHttpRequest(),
      url =
        "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" +
        access_token;

    // 设置代理
    if (weworkApp.proxy) {
      request.setProxy(weworkApp.proxy);
    }

    request.AddHeader("Content-Type: application/json");
    data = JSON.stringify(params);

    // 在日志中不展示 AccessToken
    Zabbix.Log(
      4,
      "[weworkApp Webhook] URL: " +
        url.replace(weworkApp.access_token, "<ACCESS_TOKEN>")
    );
    Zabbix.Log(4, "[weworkApp Webhook] params: " + data);
    response = request.Post(url, data);
    Zabbix.Log(4, "[weworkApp Webhook] HTTP code: " + request.Status());

    try {
      response = JSON.parse(response);
    } catch (error) {
      response = null;
    }

    if (request.Status() !== 200 || response.errcode !== 0) {
      if (typeof response.errmsg === "string") {
        throw response.errmsg;
      } else {
        throw "Unknown error. Check debug log for more information.";
      }
    }
  },
};

// Main
try {
  var params = JSON.parse(value);
  if (params.HTTPProxy) {
    weworkApp.proxy = params.HTTPProxy;
  }
  weworkApp.agentid = params.Agentid;
  weworkApp.corpid = params.Corpid;
  weworkApp.corpsecret = params.Corpsecret;
  weworkApp.touser = params.To;
  var access_token = weworkApp.getAccessToken();
  weworkApp.message = params.Subject + "\n" + params.Message;
  weworkApp.sendMessage(access_token);
  return "OK";
} catch (error) {
  Zabbix.Log(4, "[weworkApp Webhook] notification failed: " + error);
  throw "Sending failed: " + error + ".";
}

当时测试了推送 makedown,但是发现微工作台(原企业号)不支持展示 markdown 消息。

在添加完脚本后还应添加对应的模板消息,并将告警媒介关联到某个动作上。

我们通过用户设置页的告警媒介,关联上 WeworkApp 这个媒介和接收告警的用户。

20220409234248

告警测试

搞点事情,触发一下告警。完美~

20220409215510

扩展阅读

作者: 小谈谈
声明: 本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。