[Background] When Zabbix tool is used in o&M system, wechat public account and wechat enterprise account should be added for message push function of abnormal data reminder.

[System environment]

Linux系统、Python3、Pip
Copy the code

[Application tools]

Mac Pro ---- FinalShell
Copy the code

I. Enterprise wechat information push

Why choose wechat enterprise number?

This is because the wechat enterprise number needs to be created in the enterprise directory first, so that the employee can pay attention to the enterprise number. In this way, the privacy of alarm information can be realized. If you use the public account, as long as all the people who pay attention to the public account can receive alarm messages, easy to cause information leakage. And enterprise accounts with fewer than 200 employees are free and have no application restrictions.Copy the code

Implementation steps

  1. Register for wechat enterprise account

    Open the following link to register wechat enterprise number: https://work.weixin.qq.com/wework_admin/register_wx?from=myhome choose no business license to register below (limited number of 200 employees), as shown in the figure below, if it is normal big enterprise to use, please register normally.Copy the code

Fill in the enterprise name to complete the registration, then need to specify the enterprise number administrator, according to the steps to bind the administrator wechat.

  1. Create an alarm application on the enterprise

Role in application of this warning is as follows: Zabbix_server — — — — — — — — – > the alarm application — — — — — — — — > WeChat ID operations personnel

Create an application on the Enterprise as shown below:

After filling in the relevant information, the application can be created. For example, the application created in this article is called Zabbix Alarm

Important information from the Enterprise

Here are a few important bits of information from the Enterprise that will be used later in the script

  • corpid

    Enterprise ID number, obtained as shown below:

    Apply the security code and Agentid to get the place as shown below:

At this point, the important parameter – enterprise application information can be obtained:

Crop_id, corp_secret, agent_id

Zabbix alarm script

External script storage path (default) :

/usr/share/zabbix/alertscripts/
Copy the code

You can modify the external script storage path and address file

vim /etc/zabbix/zabbix_server.conf
Copy the code

You can see it around line 500.

The python script code is as follows (replace the ‘XXXXX’ section below)

#! /usr/bin python3

import requests
import json
import sys
# Enterprise number and application related information
corp_id = 'xxxxxxx'
corp_secret = 'xxxxxxx'
agent_id = xxxxxxx
Path to the access_token file
file_path = '/tmp/access_token.log'
def get_access_token_from_file() :
    try:
        f = open(file_path,'r+')
        this_access_token = f.read()
        print('get success %s' % this_access_token)
        f.close()
        return this_access_token
    except Exception as e:
        print(e)
The token function is called when the token recorded in the text is invalid
def get_access_token() :
    get_token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s' % (corp_id, corp_secret)
    print(get_token_url)
    r = requests.get(get_token_url)
    request_json = r.json()
    this_access_token = request_json['access_token']
    print(this_access_token)
    r.close()
    Write the obtained access_token to text
    try:
        f = open(file_path,'w+')
        f.write(this_access_token)
        f.close()
    except Exception as e:
        print(e)
    # return the obtained access_token value
    return this_access_token
# snedMessage
# loop indefinitely until the message is successfully sent
flag = True
while(flag):
    Get access_token from text
    access_token = get_access_token_from_file()
    try:
        to_user = '@all'
        message = sys.argv[3]
        send_message_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' % access_token
        print(send_message_url)
        message_params = {
                            "touser":to_user,
                            "msgtype":"text"."agentid":agent_id,
                            "text": {"content" : message
                            },
                            "safe":0
                        }
        r = requests.post(send_message_url, data=json.dumps(message_params))
        print('post success %s ' % r.text)
        If not, run the exception and let it execute the function in the exception handler
        request_json = r.json()
        errmsg = request_json['errmsg']
        iferrmsg ! ='ok': raise
        # Message sent successfully, stop the loop
        flag = False
    except Exception as e:
        print(e)
        access_token = get_access_token()

Copy the code

Note: The current sending object is @all. You can modify the startup parameters to obtain the corresponding object (the enterprise wechat user ID) and send the message.

After uploading the server specified folder, you can run Python in the server environment to verify the script. (XXXX. py is the wechat script)

Python3 xxxx.py 'parameter 1'' parameter 2'Copy the code

The log output is as follows:

python3 gzh_wechat.py 'openidxxxxxxxxxxxxxxx' get success 43_fhNx5B49qQOjvTr-7fY8JBFerQG6n164H45WT1NDccGlEdIvSPIsG1CnsZ377E2VEMlA7D4k55iaawzzip7YIISlly3KcZXnt_gfV6J6kZOS60gnz1HxQ 0fI3QgIrRxuvhTxYp7ebA1d0yBlLSIaAFAHOE https://qyapi.weixin.qq.com/cgi-bin/message/template/send?access_token=43_fhNx5B49qQOjvTr-7fY8JBFerQG6n164H45WT1NDccGlEd IvSPIsG1CnsZ377E2VEMlA7D4k55iaawzzip7YIISlly3KcZXnt_gfV6J6kZOS60gnz1HxQ0fI3QgIrRxuvhTxYp7ebA1d0yBlLSIaAFAHOE post success {"errcode":0,"errmsg":"ok","msgid":1803177490043944963}Copy the code

Configure ZABBIX – Manage – Alarm Media Type – Create media type

What parameters are passed to the Script when the Script is called

{ALTER.SENDTO} # To whom. This parameter is valid in email alarms, but not in wechat alarms

{ALTER.SUBJECT} # Alarm title. This parameter is valid for email alarms but not for wechat alarms

{ALTER.MESSAGE} # Alarm content, useful in wechat alarm

  • Modify the alarm content format

Modify the style of the alarm content to make the alarm content more comfortable (the title of the alarm is useless in wechat alarm, and the person to whom it is sent is basically useless)

As shown below:

Enterprise directory

Add all the people who want to receive alarms to the Enterprise register. The logic is (first create the member in the register, then invite the member to join, or let him scan the code to join).

As shown below:

To this enterprise wechat notice Over.

2. Wechat Public Account Message Push (Python)

Prepare content in advance

App_id, app_secret (obtained from wechat public account management background)

Template_id (wechat public account management background – template Id) and template content parameters.

Implementation steps

The specific configuration content of the same enterprise wechat is the same, the specific steps are as above;

The script code

#! /usr/bin/python3

import requests
import json
import sys
# Enterprise number and application related information
app_id = 'xxxxxxxx'
app_secret = 'xxxxxxxxxxxxxxxx'
Path to the access_token file
file_path = '/tmp/access_token.log'
def get_access_token_from_file() :
    try:
        f = open(file_path,'r+')
        this_access_token = f.read()
        print('get success %s' % this_access_token)
        f.close()
        return this_access_token
    except Exception as e:
        print(e)
The token function is called when the token recorded in the text is invalid
def get_access_token() :
    get_token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s' % (app_id, app_secret)
    print(get_token_url)
    r = requests.get(get_token_url)
    request_json = r.json()
    this_access_token = request_json['access_token']
    print(this_access_token)
    r.close()
    Write the obtained access_token to text
    try:
        f = open(file_path,'w+')
        f.write(this_access_token)
        f.close()
    except Exception as e:
        print(e)
    # return the obtained access_token value
    return this_access_token
# snedMessage
# loop indefinitely until the message is successfully sent
flag = True
while(flag):
    Get access_token from text
    access_token = get_access_token_from_file()
    to_user = sys.argv[1]
    subject = sys.argv[2]
    message = sys.argv[3]
    try:
        send_message_url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s' % access_token
        print(send_message_url)
        message_params = {
                            "touser": to_user,
                            "template_id":"-CUCjl5B1CEb_QxZFZABZ2erzz_kbLoJFiIhi3PcWaQ"."data": {"first" : {
                                    "value":subject,
                                    "color":"# 173177"
                                },
                                "keyword1" : {
                                    "value":message,
                                    "color":"# 173177"
                                },
                                "keyword2" : {
                                    "value":"39.8"."color":"# 173177"
                                },
                                "remark": {"value":"Welcome to buy again!."color":"# 173177"
                                }
                            }
                        }
        r = requests.post(send_message_url, data=json.dumps(message_params))
        print('post success %s ' % r.text)
        If not, run the exception and let it execute the function in the exception handler
        request_json = r.json()
        errmsg = request_json['errmsg']
        iferrmsg ! ='ok': raise
        # Message sent successfully, stop the loop
        flag = False
    except Exception as e:
        print(e)
        access_token = get_access_token()

Copy the code

Emphasizes the

1. Upload the folder on the application server. The script location is as follows:

2. After uploading the file, you need to give the footstep file operation permission. Currently, I have checked all permissions:

Or input

chmon u+x xxxx.py
Copy the code

(If there is still a permission problem after granting permission, the server needs to be restarted.)

Restart command: rebootCopy the code

3. Special attention should be paid to the script code. After installing Python, you need to find the startup file to configure the Python environment

/usr/bin/python3
Copy the code

(This path is applied to the startup of the Python script)

If not, you can use the following statement:

whereis python3
Copy the code

4. After the script is copied to the specified location and Python is installed, execute the following statement. The script installation depends on:

pip3 install requests
Copy the code
python3 --version
pip3 --version
Copy the code

3. Wechat public account message push (shell)

Prepare content in advance

App_id, app_secret (obtained from wechat public account management background)

Template_id (wechat public account management background – template Id) and template content parameters.

Implementation steps

The specific configuration content of the same enterprise wechat is the same, the specific steps are as above;

The script code

#! /bin/sh
#Wechat message sending script 

#Global configuration --
#Wechat official account appID
appID=xxxxxx

#Wechat official account AppSecret
appsecret=xxxxxxx

#Wechat official account sending message template
tpl_id=-xxxxxxxxxxxx
#Message template:
#   {{first.DATA}} 
#{{keyword1.DATA}} 
#{{keyword2.data}}
#
# {{remark.DATA}}

#Obtain the wechat public number AccessToken and cache it in the local function
getAccessToken(){
    if [ -f "/var/log/zabbix/.wechat_accesstoken" ]; then
        access_token=`cat /var/log/zabbix/.wechat_accesstoken | awk -F":" '{print $1}'`
        expires_in=`cat /var/log/zabbix/.wechat_accesstoken | awk -F":" '{print $2}'`
        time=`cat /var/log/zabbix/.wechat_accesstoken | awk -F":" '{print $3}'`
            if [ -z $access_token ] || [ -z $expires_in ] || [ -z $time ]; then
            rm -f /var/log/zabbix/.wechat_accesstoken
            getAccessToken 
        fi
    else
        content=$(curl "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appID&secret=$appsecret")
#       echo "get content: $content"access_token=`echo $content | awk -F "\"" '{print $4}'` expires_in=`echo $content | awk -F "\"" '{print $7}' | cut -d"}"  -f1|cut -c2-` echo "access_token = $access_token" >> /var/log/zabbix/.wechat_accesstoken_log#       echo "expires_in = $expires_in"time=$(date +%s) echo "$access_token:$expires_in:$time" > /var/log/zabbix/.wechat_accesstoken if [ -z $access_token ] ||  [ -z $expires_in ] || [ -z $time ]; then echo "not get access_token" >> /var/log/zabbix/.wechat_accesstoken_log exit 0 fi fi remain=$[$(date +%s) - $time] echo "remain:$remain">> /var/log/zabbix/.wechat_accesstoken_log limit=$[$expires_in - 7020] echo "limit:$limit">> /var/log/zabbix/.wechat_accesstoken_log if [ $remain -gt $limit ]; then rm -f /var/log/zabbix/.wechat_accesstoken getAccessToken fi }#Sending message functionSendMessage () {json message body = # news ` cat < < EOF {" touser ":" $openid ", "template_id" : "$tpl_id", "url" : "$url." "data":{ "first": { "value":"$first", "color":"#FF0000" }, "keyword1":{ "value":"$keyword1", "color":"#173177" }, "keyword2": { "value":"$keyword2", "color":"#173177" }, "remark":{ "value":"$remark", "color":"#FF0000" } } } EOF ` info=`curl -X POST -H "Content-Type: application/json" https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$access_token -d "$message"` echo  "info:$info">> /var/log/zabbix/.wechat_accesstoken_log }
#Help information function
#usage() {
#    cat <<EOF
#usage: $0 [-u openids -s summary -n name -t time -d detail -l link] [-h]
#u wechat user openid , multiple comma separated
#s message summary
#n project name
#t alarm time
#d message detail
#l link address
#h output this help and exit
#EOF
#}


#Gets script execution parameters
#while getopts ":u:s:n:t:d:h:l:" op; do
#    case $op in
#        u)openids="$OPTARG";;
#        s)first="$OPTARG";;
#        n)name="$OPTARG";;
#        t)date="$OPTARG";;
#        d)remark="$OPTARG";;
#        l)url="$OPTARG";;
#        *)
#        usage
#        exit 0
#        ;;
#    esac
#done

#The conditions are met to send the message
if [[ -n $1 && -n $2 && -n $3  && -n $4 ]]; then
    url=$2
    first=$3
    keyword1=$4
    keyword2=$5
    remark=$6
    echo `date +"%Y-%m-%d %H:%M:%S"` >> /var/log/zabbix/.wechat_accesstoken_log
    echo "send message : $url $openid $first $keyword1 $keyword2 $remark" >> /var/log/zabbix/.wechat_accesstoken_log 
    getAccessToken
   
    OLD_IFS="$IFS"
    IFS=","
    arr=($1)
    IFS="$OLD_IFS"
    for openid in ${arr[@]}
    do
        sendMessage
    done
    exit $?
else
    echo `date +"%Y-%m-%d %H:%M:%S"` >> /var/log/zabbix/.wechat_accesstoken_log
    echo "error." >> /var/log/zabbix/.wechat_accesstoken_log
#    usage
    exit 1
fi
Copy the code

2. Configure script triggers and actions

Specific configuration process:

Article 1. The users

1.1 Managing Users -> Creating Users

1.2 Add alarm media for users

1.3 Granting User Rights (Super Admin in a certain city, user type: Super Admin)

2. Trigger (configuration-host-trigger)

2.1 Select host – Click trigger in the list – Click Create trigger

2.2 Adding a Trigger

Note:

Expression writing;

Problem event generation mode: 1. Single (only triggered in response to the action operation and script); 2. Multiple (repeated response to action operations and scripts at a certain time)

Allow manual shutdown (otherwise, manual operation cannot be performed later during shutdown, so select it);

Click Enabled/Disabled to switch status directly;

3. Action (Configuration-Action)

3.1 Adding Actions (Multiple actions can be added for operation arrangement of “or”, “and” and “not”)

3.2 Action – Operation

Fault {trigger. STATUS}, server :{HOSTNAME1} occurs :{trigger. NAME} fault!

Alarm host :{HOSTNAME1}

Alarm TIME :{event.date} {event.time}

Alarm level :{TRIGGER.SEVERITY}

Alarm information: {trigger.name}

Alarm item :{trigger.key1}

{item.name}:{item.value}

Current STATUS :{trigger. STATUS}:{item.value1}

EVENT ID: {EVENT. ID}

Server :{host. NAME}: {TRIGGER.NAME} recovered!

Alarm HOST :{host. NAME}

Alarm Address :{host. IP}

Monitoring ITEM :{item.name}

Monitoring value :{item. LASTVALUE}

Alarm level :{TRIGGER.SEVERITY}

Current STATUS :{trigger.status}

Alarm information :{trigger.name}

Alarm TIME :{event.date} {event.time}

RECOVERY TIME :{event.recovery. DATE} {event.recovery. TIME}

Duration :{event.age}

EVENT ID: {EVENT. ID}

Don’t forget to update when you’re done adding.

Reference: zabbix4.2 WeChat alarm configuration script tutorial idc.wanyunshuju.com/zab/1028.ht…