python发送企业微信群webhook消息(文本、文件)

python 复制代码
import datetime
import os
import time
from copy import copy

import requests
from loguru import logger
from urllib3 import encode_multipart_formdata


class WeiXin_Robot:
    def __init__(
            self,
            url: str = ""
    ):

        # 测试car
        test_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"

        self.url = url or test_url
        self.mHeader = {'Content-Type': 'application/json; charset=UTF-8'}


    def send_cars_msg(self, car_dict):
        logger.info(f"{car_dict=}")
        cars = f"  ##通知\n" \
               f"一一一一一一一一一一一一一一\n"
        for vin, info in car_dict.items():
            info_str = f"{vin}:<font color=\"info\">{info}</font>\n"
            cars += info_str
        data = {
            "msgtype": "markdown",
            "markdown": {
                'content': cars
            }
        }
        self.send(data=data)

    def send_error_msg(self, info):
        data = {
            "msgtype": "text",
            "text": {
                "content":
                    f"企业微信异常提醒\n"
                    f"问题描述:{info.get('desc')}\n"
                    f"名称:{info.get('name')}\n"
                    f"id:{info.get('media_id')}\n",
                "mentioned_mobile_list": ["18817957261"]
            }
        }
        self.send(data=data)

    def send(self, data):
        try:
            info = requests.post(url=self.url, json=data, headers=self.mHeader)
            if info.json().get("errcode") == 0 and info.json().get("errmsg") == "ok":
                logger.info(f"企业微信通知发送成功,msg={info.json()}")
            else:
                logger.warning(f"企业微信通知发送异常,{info.json()=}")
        except Exception as e:
            logger.warning("企业微信通知发送异常")
            logger.warning(e)
            pass

    # file_path: e.g /root/data/test_file.xlsx
    # 如果D:\\windows\\ 下面file_name的split需要调整一下
    # upload_file 是为了生成 media_id, 供消息使用
    def upload_file(self, file_path):
        try:
            key = self.url.split('=')[1]
            wx_upload_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={key}&type=file"
            file_name = file_path.split("/")[-1]
            with open(file_path, 'rb') as f:
                length = os.path.getsize(file_path)
                data = f.read()
            print(file_name)
            headers = {"Content-Type": "application/octet-stream"}
            params = {
                "name": 'media',
                "filename": file_name,
                "filelength": length,
            }
            file_data = copy(params)
            file_data['file'] = (file_path.split('/')[-1:][0], data)
            encode_data = encode_multipart_formdata(file_data)
            file_data = encode_data[0]
            headers['Content-Type'] = encode_data[1]
            r = requests.post(wx_upload_url, data=file_data, headers=headers)
            print(r.text)
            if r.json().get("errcode") == 0 and r.json().get("errmsg") == "ok":
                logger.info(f"上传文件到企业微信成功,msg={r.json()},{file_path=}")
                media_id = r.json()['media_id']
                return media_id
            else:
                logger.warning(f"上传文件到企业微信异常,{r.json()=},{file_path=}")

        except Exception as e:
            logger.warning("上传文件到企业微信失败")
            logger.warning(e)
            pass

    # media_id 通过上一步上传的方法获得
    def send_file(self, file_path=None, media_id=""):
        """企业微信发送文件"""
        if not media_id:
            media_id = self.upload_file(file_path=file_path)
            time.sleep(1)
        try:
            # headers = {"Content-Type": "text/plain"}
            data = {
                "msgtype": "file",
                "file": {
                    "media_id": media_id
                }
            }
            for i in range(3):
                r = requests.post(url=self.url, json=data, headers=self.mHeader)
                if r.json().get("errcode") == 0 and r.json().get("errmsg") == "ok":
                    logger.info(f"企业微信发送文件成功,msg={r.json()},{file_path=},{media_id=}")
                    break
                else:
                    logger.warning(f"企业微信发送文件异常,{r.json()=},{file_path=}")
                    logger.warning('3s后再次尝试发送文件...')
                    time.sleep(3)
                    if i == 2:
                        self.send_error_msg(
                            info={
                                'desc': f'企业微信发送文件异常',
                                "name": file_path,
                                'media_id': media_id,
                            })
            # print(r.text)
        except Exception as e:
            logger.warning("企业微信发送文件异常")
            logger.warning(e)
            pass


if __name__ == "__main__":
    pass
相关推荐
小丁爱养花1 天前
接口自动化测试 - pytest [1]
python·自动化·pytest
wjs20241 天前
JSP 点击量统计
开发语言
xiaopengbc1 天前
泛型在Java集合框架中的应用有哪些?
java·开发语言·python
萧鼎1 天前
深入理解 Python `ssl` 库:安全通信的基石
python·安全·ssl
tpoog1 天前
[C++项目组件]Etcd的简单介绍和使用
开发语言·c++·etcd
蔗理苦1 天前
2025-10-01 Python不基础 1——字节码和虚拟机
开发语言·python
lly2024061 天前
PostgreSQL LIMIT 语句详解
开发语言
山,离天三尺三1 天前
线程中互斥锁和读写锁相关区别应用示例
linux·c语言·开发语言·面试·职场和发展
讓丄帝愛伱1 天前
阿里开源 Java 诊断神器Arthas
java·linux·开发语言·开源
扑克中的黑桃A1 天前
Python快速入门专业版(十一):布尔值与None:Python逻辑判断的基石(深度解析真值、假值与空状态处理)
python