Operations 8 min read

How to Send Zabbix Alerts with Images to DingTalk via Python

This guide explains how to extract an item ID from Zabbix alerts, capture the corresponding chart image, upload it to a public server, format the alert as markdown, and deliver it through a DingTalk robot webhook using a Python script.

Ops Development Stories
Ops Development Stories
Ops Development Stories
How to Send Zabbix Alerts with Images to DingTalk via Python

Implementation Idea

First, the alert must contain an

itemid

; use a regular expression to extract it.

Build a session or use cookies to log in, request the chart image using the

itemid

, save it locally, then upload it to a public web server so the markdown image link can be accessed.

Convert the alert information to markdown format.

Construct a request to send the message via DingTalk webhook.

Configure DingTalk Robot

DingTalk robot requires security settings; define a keyword “通知” so that messages must contain this word.

Script Implementation

Because the image must be copied to a remote server, set up password‑less SSH in advance; the script runs as the Zabbix user, and the web server directory should have appropriate security policies.

<code>#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests,time
import json,sys,re,os

zabbixserver_url ='http://192.168.99.200/index.php'
# Define remote web server address for image copy
pname_path='http://47.103.15.51/dingding_pic/'
# URL to get the chart image
testUrl = "http://192.168.99.200/chart.php"
host='192.168.99.200'

def get_itemid():
    itemid=re.search(r'ITEM ID:(\d+)',sys.argv[2]).group(1)
    return itemid

def get_picture(itemid,pname):
    myRequests = requests.Session()
    try:
        loginHeaders = {
            "Host":host,
            "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
        }
        # Login payload
        playLoad = {
            "name": "Admin",
            "password": 'zabbix',
            "autologin": "1",
            "enter": "Sign in",
        }
        myRequests.post(url=zabbixserver_url, headers=loginHeaders, data=playLoad)
        testUrlplayLoad = {
           "from": "now-10m",
           "to": "now",
           "itemids": itemid,
           "width": "700",
        }
        testGraph =  myRequests.get(url=testUrl,params=testUrlplayLoad)
        IMAGEPATH = os.path.join('/usr/lib/zabbix/alertscripts/dingding_pic/', pname)
        with open(IMAGEPATH,'wb') as f:
            f.write(testGraph.content)
        os.system("sudo scp %s [email protected]:/usr/share/nginx/html/dingding_pic" %IMAGEPATH)
        pname_url = pname_path+pname
        return pname_url
    except Exception as e:
        print(e)
        return False

def send_msg(pname_url,info3):
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    print(info3)
    data = {
        "msgtype": "markdown",
        "markdown": {
            "title": info1,
            "text": "## 通知:\n"+info3+"![screenshot](%s)\n"%(pname_url)
        },
        "at":{
            "atMobiles": reminders,
            "isAtAll": False,
        },
        }
    r = requests.post(url=webhook_url,json=data,headers=headers)
    print(r.text)

def info_text():
    new_text = ""
    x = info2.split('\n')
    for i in x:
        if re.search('ITEM ID',str(i)):
            pass
        else:
            new_text+="- "+str(i)+('\n')
    print(type(new_text))
    return new_text

if __name__ == '__main__':
    os.system("echo hello >> /tmp/syslog.md")
    pname = str(int(time.time()))+'.png'
    info1 = str(sys.argv[1])
    info2 = str(sys.argv[2])
    info3 = info_text()
    with open('/tmp/syslog.md','a') as f:
        f.write(info1)
        f.write(info2)
        f.close()
    reminders = []
    webhook_url = 'https://oapi.dingtalk.com/robot/send?access_token=...'
    itemid = get_itemid()
    pname_url=get_picture(itemid,pname)
    print(pname_url)
    send_msg(pname_url,info3)
</code>

Define Alert Media Type

In the Zabbix web UI, go to Administration → Media types, create a new media type of type “Script”, set the script name to the Python file (e.g.,

zabbix_email_pic.py

), configure the script parameters, and save.

Define Alert Action

Navigate to Configuration → Actions, create a new action, and use the image‑based message template.

<code>操作
默认标题 Zabbix告警:服务器:{HOSTNAME}发生: {TRIGGER.NAME}故障!
ITEMID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}
恢复操作
Zabbix告警:服务器:{HOST.NAME}发生: {TRIGGER.NAME}已恢复!
ITEMID:{ITEM.ID}
告警主机:{HOST.NAME}
告警主机:{HOST.IP}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE}
事件ID:{EVENT.ID}
</code>

Final Result

Trigger a test alarm to see the image‑included notification in DingTalk, email, or WeChat.

All three channels are now configured to receive Zabbix alerts with pictures.

monitoringpythonautomationZabbixDingTalkAlert
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.