我有篇博客写到如何用微信发送告警消息,实现了发送文字消息,不能带图片,这样不是很直观,最近又研究了一下如何发送图片,写了脚本实现了发送文字+图片的告警。

    效果如下:

zabbix通过微信企业号发送图文消息_第1张图片

先发送文字消息,下面挨着graph。


    这里只提供脚本和思路,具体配置请看我的另一篇博客:(http://wuhf2015.blog.51cto.com/8213008/1688614#662543)


    实现方式:

  1. 在Action中设置Default Subject的格式为"状态:#{TRIGGER.STATUS}#主机:#{HOST.NAME}#键名:#{ITEM.KEY}#"。这样可以在脚本里做判断,如果状态为OK则不发送图片,如果状态为problem则发送图片。

    zabbix通过微信企业号发送图文消息_第2张图片

  2. 脚本有了{HOST.NAME}和{ITEM.KEY}这两个参数后,可以通过查询Mysql或者调用zabbix_api的方式得到我们必要的变量ItemID,有了这个变量才能获取图片。

  3. 通过itemid从zabbix中获取图片后,我们需要将图片上传到微信企业号的临时素材里,上传后我们会得到一个media_id

  4. 我们将media_id通过p_w_picpath格式发送出来就能收到图片消息了。


zabbix通过微信企业号发送图文消息_第3张图片


    脚本:

#!/bin/bash
#SCRIPT_NAME:weixin.sh
#get graph to you
#V2-2016-05-23
#wuhf
#email:[email protected]

gettoken() {
ID='xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
SECRET='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
URL="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$ID&corpsecret=$SECRET"
Gtoken=$(/usr/bin/curl -s -G $URL | awk -F\" '{print $4}')
}
gettoken

AppID=3
PartyID=2
UserID="$1"
Title="$2"
Msg="$3"

getitemid() {
DBServer="127.0.0.1"
DBUser="root"
DBName="zabbix"
DBPort="3306"
DBPassword="123456"
Hostname=$(echo $Title |awk -F"#" '{print $4}')
Key=$(echo $Title |awk -F"#" '{print $6}')
Return=$(sudo mysql -u$DBUser -h$DBServer -P$DBPort -p$DBPassword --database=$DBName -e "select itemid from items where hostid=(select hostid from hosts where name = \"$Hostname\" ) and key_ = \"$Key\";")
Itemid=$(echo $Return |awk '{print $2}')
}
#获取itemid可以通过数据库查询,也可以通过zabbix_api,我自己用的是api
#getitemid

getgraph() {
zabbix_user='xxxxxxxxxxxxxxxxxx'
zabbix_pass='xxxxxxxxxxxxxxxxxx'
zabbix_url="http://127.0.0.1/zabbix/"
cookie="/tmp/cookie"
p_w_picpath_path="/tmp/"
STime=$(date +%Y%m%d%H%M%S)
Period=7200
Width=640
High=200
sudo /usr/bin/curl -s -c $cookie -b $cookie -d "name=$zabbix_user&password=$zabbix_pass&autologin=1&enter=Sign+in" $zabbix_url/index.php
sudo /usr/bin/curl -s -b $cookie -F "itemids=$Itemid" -F "period=$Period" -F "stime=$STime" -F "width=$Width" -F "high=$High" $zabbix_url/chart.php > $p_w_picpath_path$Itemid.png
}
#定义这个函数是要利用上面的itemid获取图片保存到/tmp下面
#getgraph

postgraph() {
PIC_URL="$p_w_picpath_path$Itemid.png"
M_URL="https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=$Gtoken&type=p_w_picpath"
Media=$(sudo curl -s -F media=@"$PIC_URL" "$M_URL" | awk -F"\"" '{print $8}')
}
#定义这个函数是要将/tmp下面的png文件上传到微信临时素材接口,永久素材接口有上限5000,所以不建议使用
#postgraph
#debug
#echo $PIC_URL$Media > /tmp/pic.txt

p_w_picpath() {
    printf '{\n'
    printf '\t"touser": "'"$UserID"\"",\n"
    printf '\t"toparty": "'"$PartyID"\"",\n"
    printf '\t"msgtype": "p_w_picpath",\n'
    printf '\t"agentid": "'" $AppID "\"",\n"
    printf '\t"p_w_picpath": {\n'
    printf '\t\t"media_id": "'"$Media"\""\n"
    printf '\t},\n'
    printf '\t"safe":"0"\n'
    printf '}\n'
}

text() {
    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'
}

#我这里定义p_w_picpath和text两个格式,是要将一条告警消息分两次发送,先发送text然后发送图片,原因就是微信企业号提供的news发送的为图片链接,如果zabbix是内网监听,那么链接就无意义了,而mpnews每天最多发送100条,超过就返回错误,所以放弃。

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

if echo $Title | grep "PROBLEM" ;then
getitemid
getgraph
postgraph
sudo /usr/bin/curl --data-ascii "$(text)" $url
sudo /usr/bin/curl --data-ascii "$(p_w_picpath)" $url
sudo rm -f $PIC_URL
else
sudo /usr/bin/curl --data-ascii "$(text)" $url
fi

    互相学习:

    脚本参照了下面这两篇博客:

  • http://babyfenei.blog.51cto.com/443861/1728604

  • http://grass51.blog.51cto.com/4356355/1094098


    注意:

    1.key_ 中不能带引号,例如grpsum{"zabbix server",net.if.in[eth0],last,0}这样就不正确

    2.Action中的Default Subject项一定按照我写的来