转载至:http://www.jianshu.com/p/09a5a21b6b47

1.背景

现实生产环境中,我们通常使用邮件和短信接受zabbix报警信息,但是邮件经常被工作人员搁置在角落中甚至被设置为垃圾邮件被过滤掉。公司的短信接口又太贵,复杂环境中使用短息报警会使运维成本增加很多。微信提供了很好的第三方接口,我们可以利用微信报警以求降低运维成本。

网上可以查到zabbix通过微信公众号和微信企业号两种方式实现报警,比较之后个人认为企业号更适合企业内的微信应用。

2.申请微信企业号

微信申请企业号

2.1.通讯录添加企业成员

我们要提前把成员信息添加进组织部门,必填项+手机号或者微信号,这样别人扫描二维码的时候才能成功关注企业号。

注意:这里有两个我们要用到信息,一个组织部门的ID,一个部门成员的账号(账号是自己手动指定的,不同于微信号,最好是字母加数字)

1240

部门ID

1240

部门成员账号

2.2.应用中心创建应用

我们要在这里创建应用,因为要通过应用发送消息给部门成员.

注意:这里要记住一个值,应用ID

1240

新建应用.jpg

1240

选择应用类型.jpg

1240

创建应用.jpg

1240

应用ID.jpg

2.3.给部门设置管理员

设置--->功能设置---->权限管理---->新建管理组
管理员必须事先已经关注了企业号

注意:管理组权限设置很重要,不设置后面会出问题!

1240

新建管理组.jpg

1240

管理组基本信息.jpg

1240

管理组权限.jpg

确定管理员可以读取通讯录,可以使用应用发消息。

     注意:我们需要管理员的CorpID和Secret

1240

CorpID和Secret.jpg

2.4微信企业号信息统计

我们要准备这些东西:

  • 一个微信企业号

  • 企业号已经被部门成员关注

  • 企业号里有一个可以发消息的应用

  • 一个授权管理员,可以使用该应用给成员发消息

我们要取到这些信息:

  • 成员账号

  • 组织部门ID

  • 应用ID

  • CropID

  • Secret

3. 微信接口调用测试

如何调用微信接口?

   调用微信接口需要一个调用接口的凭证:access_token
   通过 :CropID 、Secret  才能获取到access_token,但是获取到的token有效期为两分钟

微信企业号接口调试工具

1240

微信接口debug.jpg

4.调用微信接口的shell脚本

使用:

curl -s -G  url           获取 AccessToken

使用:

curl --data  url     传送凭证调用企业号接口

    zabbix会传递三个参数给脚本,$1是消息接收账号,$2报警标题,$3报警内容

4.1 shell脚本

#!/bin/bash###SCRIPT_NAME:weixin.sh######send message from weixin for zabbix monitor######wuhf######V1-2015-08-25###CropID='xxxxxx'Secret='xxxxxx'GURL="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$CropID&corpsecret=$Secret" Gtoken=$(/usr/bin/curl -s -G $GURL | awk -F\" '{print $4}')

PURL="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$Gtoken"

function body() {
        local int AppID=3                        企业号中的应用id
        local UserID=$1                          部门成员id,zabbix中定义的微信接收者
        local PartyID=1                          部门id,定义了范围,组内成员都可接收到消息
        local Msg=$(echo "$@" | cut -d" " -f3-)  过滤出zabbix传递的第三个参数
        printf '{\n'
        printf '\t"touser": "'"$UserID"\"",\n"
        printf '\t"toparty": "'"$PartyID"\"",\n"
        printf '\t"msgtype": "text",\n'
        printf '\t"agentid": "'" $AppID "\"",\n"
        printf '\t"text": {\n'
        printf '\t\t"content": "'"$Msg"\""\n"
        printf '\t},\n'
        printf '\t"safe":"0"\n'
        printf '}\n'
}
/usr/bin/curl --data-ascii "$(body $1 $2 $3)" $PURL

为什么要这样写脚本?
     因为微信企业号开放的端口有固定的格式限制
     企业号支持的格式:http://qydev.weixin.qq.com/wiki/index.php?title=消息类型及数据格式

1240

微信text消息格式

附python脚本:

#!/usr/bin/env python 
#coding: utf-8
import time
import urllib,urllib2
import json
import sys
'''
1 空
2 空
3 内容
'''
"""
touser否成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送
toparty否部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
totag否标签ID列表,多个接收者用‘|’分隔。当touser为@all时忽略本参数
msgtype是消息类型,此时固定为:text
agentid是企业应用的id,整型。可在应用的设置页面查看
content是消息内容
safe否表示是否是保密消息,0表示否,1表示是,默认0
"""
# baseurl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
# securl = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' % access_token
class WeChatMSG(object):
    def __init__(self,content):
        self.gettoken_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'     
        self.gettoken_content = {
                            'corpid' : 'xxxxxxx',
                            'corpsecret' : 'xxxxxxxxxx' ,         
                            }
        self.main_content = {
                            "toparty":"1",
                            "agentid":"3",
                            "msgtype": "text",
                            "text":{
                            "content":content,
                                    }
                            }
                           
    def get_access_token(self,string):
        token_result = json.loads(string.read())
        access_token=  token_result['access_token']
        return access_token.encode('utf-8')
    def geturl(self,url,data):
        data = self.encodeurl(data)
        response = urllib2.urlopen('%s?%s' % (url,data))
        return response.read().decode('utf-8')
         
    def posturl(self,url,data,isjson = True):
        if isjson:
            data = json.dumps(data)
        response = urllib2.urlopen(url,data)
        return response.read().decode('utf-8')
    def encodeurl(self,dict):
        data = ''
        for k,v in dict.items():
            data += '%s=%s%s' % (k,v,'&')
        return data
if __name__ == '__main__':
    if len(sys.argv) == 4:
        touser,notuse,content = sys.argv[1:]        
    else:
        print 'error segments, now exit'
        sys.exit()
    msgsender = WeChatMSG(content)
    access_token_response = msgsender.geturl(msgsender.gettoken_url, msgsender.gettoken_content)
    access_token =  json.loads(access_token_response)['access_token']
    sendmsg_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' % access_token  
    print msgsender.posturl(sendmsg_url,msgsender.main_content)


4.2 shell脚本放到位置

将脚本放入zabbix默认Alert Script执行路径下

mv weixin.sh /usr/local/zabbix/share/zabbix/alertscripts
chown zabbix.zabbix /usr/local/zabbix/share/zabbix/alertscripts/weixin.sh
chmod +x /usr/local/zabbix/share/zabbix/alertscripts/weixin.sh


5. Zabbix服务器设置

5.1.创建媒介

1240

创建media type.jpg

5.2.创建用户并关联媒介

1240

创建用户.jpg

1240

用户关联媒介.jpg

5.3.创建触发器动作发送内容

1240

创建action关联trigger.jpg

1240

报警信息设置.jpg

1240

action关联用户及微信发送.jpg

6. 之后zabbix的trigger触发action后可以收到微信报警

7. 出现问题解决

7.1.curl无结果

如果出现使用cul扩展的时候提示 curl call error(77): Problem with the SSL CA cert (path? access rights?) 或者使用yum 进行更新或者安装软件的时候提示失败
有一种可能就是系统的ca包没有更新
包名为
ca-certificates
更新一下这个包一般通过yum安装或者更新软件就没问题了
我今天遇到的问题是更新了该包以后,curl扩展还是提示这个问题 需要重启一下php 重新加载一下扩展才能解决问题

yum -y install ca-certificates

7.2.没有调用脚本,配置报警脚本路径

vi /usr/local/zabbix/etc/zabbix_server.conf

AlertScriptsPath
默认值:/usr/local/share/zabbix/alertscripts
说明:告警脚本目录

### Option: AlertScriptsPath# Full path to location of custom alert scripts.# Default depends on compilation options.## Mandatory: no# Default:# AlertScriptsPath=${datadir}/zabbix/alertscriptsAlertScriptsPath=/usr/local/zabbix/share/zabbix/alertscripts

重启

/etc/init.d/zabbix_server restart

7.3.发送微信失败1

https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=UP*************KuBXSRK
{"errcode":44004,"errmsg":"empty content"}
44004     文本消息内容为空

7.4.发送微信失败2

{"errcode":60011,"errmsg":"no privilege to access\/modify contact\/party\/agent "}

在微信后台配置:

设置  -> 权限管理 ->  应用权限,  添加要主动发消息的应用到  应用权限 中

7.5.发送微信失败3

{"errcode":82001,"errmsg":"All touser & toparty & totag invalid"}
在微信后台配置:

设置  -> 权限管理 ->  应用权限,  添加要主动发消息的应用到  应用权限 中

7.6.zabbix发给微信没有参数

In Zabbix 3.0 you have to configure the Media Type to pass the parameters manually, they are not passed automatically as $1, $2 and $3 anymore.
You need to add three parameters to the Media Type manually:
{ALERT.SENDTO}
{ALERT.SUBJECT}
{ALERT.MESSAGE}
github原文

7.7.信息换行问题

\n主机:{HOST.NAME}\n地址:{HOST.IP}\n时间:{EVENT.DATE}{EVENT.TIME}\n事件: {TRIGGER.NAME}\n

8. 参考

【全网首发】zabbix如何实现微信报警
微信企业开发者接口文档