即时通讯平台–企业微信客户端搭建

背景介绍

本学期我搭建了基于光学传感器的道路环境感知系统,可以对道路中的车辆进行识别与跟踪,速度监控与流量统计。速度监控与流量统计的结果若只能本地展示,需要耗费大量人力资源看守监控,缺乏实用性,因此,我们搭建企业微信客户端,将速度监控与流量统计的结果与监控截图,实时发送给相关人员,减少人力资源的使用,大大提高项目的实用性与实时性;同时,企业微信可以将消息定向发布,避免隐私泄露,提高安全性。

下面,我从创建企业微信调用API接口,实现自动发布文字与图片消息,逐一介绍搭建方法,下图为小组建立的企业微信效果图。

企业微信接收消息服务器配置 Java配置 企业微信服务端_微信

建立自己的企业微信

我将详细介绍企业微信的创建过程,需要留意的是企业微信的ID,是企业号的标识;企业应用的AgentID,是创建的应用标识、Secret,是该应用管理组的凭证密钥。

1. 注册企业微信 :企业微信注册

扫码关联微信账号,然后填写管理员信息与企业相关信息。

企业微信接收消息服务器配置 Java配置 企业微信服务端_小程序_02

2. 创建企业应用

创建好企业微信后,扫码进入企业微信后台,在应用管理中,选择创建应用。应用是后续推送相关消息的助手,上传个酷酷的头像和名称后,一定要记得选择相关的部门与成员,这个后续会涉及到推送消息的对象。如果只选择成员的话,后续加入新成员,要记得修改添加。

企业微信接收消息服务器配置 Java配置 企业微信服务端_微信_03

3. 获取企业Id与应用的AgentId和Secret:这三个后续调用API接口时会用到。

查看企业微信Id

企业微信接收消息服务器配置 Java配置 企业微信服务端_小程序_04


查看应用AgentID、Secret:在应用管理中,选择之前创建好的应用

企业微信接收消息服务器配置 Java配置 企业微信服务端_小程序_05

调用企业微信API,编写Python脚本

概述:

企业微信开放了消息发送接口,企业可以使用这些接口让自定义应用与企业微信后台或用户间进行双向通信。
因此,我们在创建好一个自建应用,且拿到了可用的应用id及secret,可以调用api控制应用,调用api的过程,本质上就是发送http请求给企业微信后台,而发送消息就是一个post请求,其参数为 access_token 和 消息体。因此我们需要针对这两部分编写程序,获取token、定义文本和图片的消息体。

接口概括

消息接口总体上分为主动发送单聊消息、接收单聊消息以及发送消息到群三部分

1.主动发送应用消息:企业后台调用接口通过应用向指定成员发送单聊消息

2.接收消息:企业后台接收来自成员的消息或事件
2.1要使用接收消息,需要在应用中设置开发者的回调服务器配置。
2.2接收消息分为两种:1. 成员在应用客户端里发送的消息;2. 某种条件下触发的事件消息。
2.3开发者后台在接收消息后,可以在响应的返回包里带上回复消息,企业微信会将这条消息推送给成员。这就是“被动回复消息”。

3发送消息到群聊会话:企业后台调用接口创建群聊后,可通过应用推送消息到群内。(暂不支持接收群聊消息)

消息接口流程图如下:(图中"URL"为用户配置的接收消息服务器地址)

企业微信接收消息服务器配置 Java配置 企业微信服务端_发送消息_06

1.声明头文件

import requests
import json
import urllib.request

2.定义WeChat类,初始化函数

这里需要填写自己创建的企业微信与应用的相关信息

class WeChat:
    def __init__(self):
        self.ID = '企业Id'
        self.Secret = '应用的Secret'
        self.AppID = 'AgentId'
        self.UserID = "ZhangSan|LiSi"  # 接收者用户名

这里我是按照接收者的用户名发送消息,也可以设置部门,按照部门进行发生消息

3.定义get_token函数,依据企业ID与凭证密钥Secret获取权限。

def get_token(self):  ##获取TOKEN
        gurl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}".format(self.ID, self.Secret)
        r = requests.get(gurl)
        dict_result = (r.json())
        return dict_result['access_token']

4. 定义get_media_ID函数,上传图片素材,获取图片ID

发送图片消息时,利用get_media_ID函数,先上传图片素材,获取图片的ID标识号。

def get_media_ID(self, path):  ##上传到临时素材  图片ID
        Gtoken = self.get_token()
        img_url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token={}&type=image".format(Gtoken)
        files = {'image': open(path, 'rb')}
        r = requests.post(img_url, files=files)
        re = json.loads(r.text)
        return re['media_id']

5. 定义sent_text函数,发送文字消息

这部分是定义发送文本消息的信息体,下面整理了消息体的参数说明

参数

是否必须

说明

touser


指定接收消息的成员,成员ID列表。特殊情况:指定为"@all",则向该企业应用的全部成员发送

toparty


指定接收消息的部门,部门ID列表,,最多支持100个。当touser为"@all"时忽略本参数

totag


指定接收消息的标签,标签ID列表,最多支持100个。当touser为"@all"时忽略本参数

msgtype


消息类型,此时固定为:text

agentid


企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值

content


消息内容,最长不超过2048个字节,超过将截断(支持id转译)

enable_id_trans


表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。

enable_duplicate_check


表示是否开启重复消息检查,0表示否,1表示是,默认0

duplicate_check_interval


表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时

def send_text(self, text):  ##发送文字
        post_data = {}
        msg_content = {}
        msg_content['content'] = text  ## 消息内容,最长不超过2048个字节
        post_data['touser'] = self.UserID
        # post_data['toparty'] = PartyID
        post_data['msgtype'] = 'text'
        post_data['agentid'] = self.AppID
        post_data['text'] = msg_content
        post_data['safe'] = '0'  # 表示是否是保密消息,0表示否,1表示是,默认0
        Gtoken = self.get_token()
        purl1 = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(Gtoken)
        json_post_data = json.dumps(post_data)
        request_post = urllib.request.urlopen(purl1, json_post_data.encode(encoding='UTF8'))
        return request_post

6定义send_pic函数,发送图片消息

发送图片消息与文本消息不同的地方在于,需要先上传图片素材,获取media_ID,msgtype的参数值也要改为“image”,其他地方和发送文本消息相似。

def send_pic(self, path):  ##发送图片
        img_id = self.get_media_ID(path)
        post_data1 = {}
        msg_content1 = {}
        msg_content1['media_id'] = img_id
        post_data1['touser'] = self.UserID
        # post_data1['toparty'] = PartyID
        post_data1['msgtype'] = 'image'
        post_data1['agentid'] = self.AppID
        post_data1['image'] = msg_content1
        post_data1['safe'] = '0'
        Gtoken = self.get_token()
        purl2 = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(Gtoken)
        json_post_data1 = json.dumps(post_data1)
        request_post = urllib.request.urlopen(purl2, json_post_data1.encode(encoding='UTF8'))
        return request_post

完整代码

填入自己注册企业微信的ID和应用的AgentID与Secret,就可以直接调用send_text和send_pic函数分别发送文字与图片消息。

# !/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
import json
import urllib.request


class WeChat:
    def __init__(self):
        self.ID = '企业ID'
        self.Secret = '应用密钥'
        self.AppID = 'AgentID'
        self.UserID = "ZhangSan|LiSi"  # 接收者用户名

    def get_token(self):  ##获取TOKEN
        gurl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}".format(self.ID, self.Secret)
        r = requests.get(gurl)
        dict_result = (r.json())
        return dict_result['access_token']

    def get_media_ID(self, path):  ##上传到临时素材  图片ID
        Gtoken = self.get_token()
        img_url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token={}&type=image".format(Gtoken)
        files = {'image': open(path, 'rb')}
        r = requests.post(img_url, files=files)
        re = json.loads(r.text)
        return re['media_id']

    ##

    def send_text(self, text):  ##发送文字
        post_data = {}
        msg_content = {}
        msg_content['content'] = text  ## 消息内容,最长不超过2048个字节
        post_data['touser'] = self.UserID
        # post_data['toparty'] = PartyID
        post_data['msgtype'] = 'text'
        post_data['agentid'] = self.AppID
        post_data['text'] = msg_content
        post_data['safe'] = '0'  # 表示是否是保密消息,0表示否,1表示是,默认0
        Gtoken = self.get_token()
        purl1 = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(Gtoken)
        json_post_data = json.dumps(post_data)
        request_post = urllib.request.urlopen(purl1, json_post_data.encode(encoding='UTF8'))
        return request_post

    def send_pic(self, path):  ##发送图片
        img_id = self.get_media_ID(path)
        post_data1 = {}
        msg_content1 = {}
        msg_content1['media_id'] = img_id
        post_data1['touser'] = self.UserID
        # post_data1['toparty'] = PartyID
        post_data1['msgtype'] = 'image'
        post_data1['agentid'] = self.AppID
        post_data1['image'] = msg_content1
        post_data1['safe'] = '0'
        Gtoken = self.get_token()
        purl2 = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={}".format(Gtoken)
        json_post_data1 = json.dumps(post_data1)
        request_post = urllib.request.urlopen(purl2, json_post_data1.encode(encoding='UTF8'))
        return request_post


if __name__ == "__main__":
    wx = WeChat()
    wx.send_text("车辆超速")
    wx.send_pic("图片路径")