2024 年最新使用 ntwork 框架搭建企业微信机器人详细教程

NTWORK 概述

基于 PC 企业微信的 api 接口,支持收发文本、群@、名片、图片、文件、视频、链接卡片等。

下载安装 ntwork

pip install ntwork

国内源安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ntwork

企业微信版本下载

官方下载:https://dldir1.qq.com/wework/work_weixin/WeCom_4.0.8.6027.exe

简单基础案例

import sys
import ntworkwework = ntwork.WeWork()# 打开pc企业微信, smart: 是否管理已经登录的企业微信`在这里插入代码片`
wework.open(smart=True)# 等待登录
wework.wait_login()# 向文件助手发送一条消息
wework.send_text(conversation_id="FILEASSIST", content="hello, NtWork")try:while True:pass
except KeyboardInterrupt:ntwork.exit_()sys.exit()

获取联系人列表、群列表

# -*- coding: utf-8 -*-
import sys
import ntworkwework = ntwork.WeWork()# 打开pc企业微信, smart: 是否管理已经登录的微信
wework.open(smart=True)# 等待登录
wework.wait_login()# 获取内部(同事)列表并输出
contacts = wework.get_inner_contacts()
print("内部(同事)联系人列表: ")
print(contacts)# 获取外部(客户)列表并输出
contacts = wework.get_external_contacts()
print("外部(客户)联系人列表: ")
print(contacts)# 获取群列表并输出
rooms = wework.get_rooms()
print("群列表: ")
print(rooms)try:while True:pass
except KeyboardInterrupt:ntwork.exit_()sys.exit()

监听消息自动回复

import sys
import ntworkwework = ntwork.WeWork()# 打开pc企业微信, smart: 是否管理已经登录的微信
wework.open(smart=True)# 注册消息回调
@wework.msg_register(ntwork.MT_RECV_TEXT_MSG)
def on_recv_text_msg(wework_instance: ntwork.WeWork, message):data = message["data"]sender_user_id = data["sender"]self_user_id = wework_instance.get_login_info()["user_id"]conversation_id: str = data["conversation_id"]# 判断消息不是自己发的并且不是群消息时,回复对方if sender_user_id != self_user_id and not conversation_id.startswith("R:"):wework_instance.send_text(conversation_id=conversation_id, content=f"你发送的消息是: {data['content']}")try:while True:pass
except KeyboardInterrupt:ntwork.exit_()sys.exit()

使用 fastapi 框架

通过 fastapi 的 swagger 在线文档可以很方便的管理 ntwork 接口:案例

常见问题解决方案

版本不匹配异常

如果出现ntwork.exception.WeWorkVersionNotMatchError异常异常, 请确认是否安装github上指定的企业微信版本,如果确认已经安装,还是报错,可以在代码中添加以下代码,跳过微信版本检测

import ntwork
ntwork.set_wework_exe_path(wework_version='4.0.8.6027') 

账号克隆登录

新建一些 ntwork.wework 实例,然后调用 open 方法。

import ntwork# 多开3个微信
for i in range(3):wework = ntwork.WeWork()wework.open(smart=False)

更完善的多实例管理查看 fastapi_example例子

如何监听输出所有的消息

# 注册监听所有消息回调
import ntwork@wework.msg_register(ntwork.MT_ALL)
def on_recv_text_msg(wework_instance: ntwork.WeWork, message):print("########################")print(message)

完全例子查看examples/msg_register_all.py

如何关闭 ntwork 日志

os.environ['NTWORK_LOG'] = "ERROR" 要在import ntwork前执行

# -*- coding: utf-8 -*-
import os
import sys
import time
os.environ['NTWORK_LOG'] = "ERROR"import ntwork

如何关闭 cmd 窗口

先使用pip install pywin32 安装pywin32模块, 然后在代码中添加以下代码, 完整例子查看examples/cmd_close_event.py

import sys
import ntwork
import win32apidef on_exit(sig, func=None):ntwork.exit_()sys.exit()# 当关闭cmd窗口时
win32api.SetConsoleCtrlHandler(on_exit, True)

Pyinstaller 打包 exe

使用 pyinstaller 打包 ntwork 项目,需要添加 --collect-data=ntwork 选项

打包成单个 exe 程序

pyinstaller -F --collect-data=ntwork main.py

将所有的依赖文件打包到一个目录中

pyinstaller -y --collect-data=ntwork main.py

打包 fastapi_example 示例,需要添加 --paths=. --collect-data=ntchat

pyinstaller -F --paths=. --collect-data=ntchat main.py

登录日志预览

2024-04-12 00:45:21,949 - WeWorkManager - INFO - initialize wework, version: 4.0.8.6027
2024-04-12 00:45:21,949 - WeWorkManager - DEBUG - new wework instance
2024-04-12 00:45:21,982 - WeWorkInstance - INFO - open wework pid: 57024
2024-04-12 00:45:23,671 - WeWorkManager - DEBUG - accept client_id: 1
2024-04-12 00:45:26,225 - WeWorkInstance - DEBUG - on recv message: {'data': {'account': '', 'acctid': 'WangPaiGeGe', 'avatar': 'https://wework.qpic.cn/wwpic3az/457956_UJkq5TJkTfCnA5x_1712341231/0', 'corp_id': '1970325052533916', 'document_root': 'C:\\Users\\Administrator\\Documents\\WXWork\\1688856738534700', 'email': '', 'job_name': '', 'mobile': '19561983930', 'nickname': '', 'pid': 57024, 'position': '', 'sex': 1, 'user_id': '1688856738534700', 'username': '王牌哥哥'}, 'type': 11026}
2024-04-12 00:45:26,241 - WeWorkInstance - INFO - login success, name: 王牌哥哥

私聊自动回复案例

import sys
import ntworkwework = ntwork.WeWork()# 打开 pc 企业微信, smart: 是否管理已经登录的微信
wework.open(smart=True)# 注册消息回调
@wework.msg_register(ntwork.MT_RECV_TEXT_MSG)
def on_recv_text_msg(wework_instance: ntwork.WeWork, message):data = message["data"]sender_user_id = data["sender"]self_user_id = wework_instance.get_login_info()["user_id"]conversation_id: str = data["conversation_id"]# 判断消息不是自己发的并且不是群消息时,回复对方if sender_user_id != self_user_id and not conversation_id.startswith("R:"):wework_instance.send_text(conversation_id=conversation_id, content=f"你发送的消息是: {data['content']}")try:while True:pass
except KeyboardInterrupt:ntwork.exit_()sys.exit()

消息属性

私聊消息属性说明

{'appinfo': 'CAQQiZrgsAYYpMv0mZmAgAMgyIKKUw==','at_list': [],'content': '我喜欢你','content_type': 0,'conversation_id': 'S:1688856625489316_1688856738534700','is_pc': 0,'local_id': '34','receiver': '1688856738534700','send_time': '1712852233','sender': '1688856625489316','sender_name': '唤醒手腕','server_id': '1000235'
}

群聊消息属性说明

{'appinfo': 'CAQQiKTgsAYYpMv0mZmAgAMg99ak/Ak=','at_list': [],'content': '我喜欢你','content_type': 0,'conversation_id': 'R:1970325052533916','is_pc': 0,'local_id': '41','receiver': '1688856738534700','send_time': '1712853512','sender': '1688856625489316','sender_name': '唤醒手腕','server_id': '1000258'
}

案例:故障离线表格统计

读取故障数据源码

import re# 假设这是你的消息体字符串
test_message = """  
【故障位置】化州西收费站97车道
【故障情况】不能缴费
【填报人】唤醒手腕
"""def analysis_repair_data(message):# 定义正则表达式模式,用于匹配每个字段pattern = r"【故障位置】(.*)\n【故障情况】(.*)\n【填报人】(.*)"# 使用re.search来查找匹配项match = re.search(pattern, message, re.DOTALL)if match:fault_location = match.group(1).strip()  # 提取故障位置fault_situation = match.group(2).strip()  # 提取故障情况reporter = match.group(3).strip()  # 提取填报人return {"fault_location": fault_location,"fault_situation": fault_situation,"reporter": reporter}else:return False

读取维修数据源码

import re# 假设这是你的消息体字符串
test_message = """  
【故障编号】 
【维修情况】已修复  
【维修人】xxx  
"""def analysis_solve_data(message):# 定义正则表达式模式,用于匹配每个字段pattern = r"""  【故障编号】(.*)  【维修情况】(.*)  【维修人】(.*)  """pattern = re.compile(pattern, re.DOTALL | re.VERBOSE)# 使用re.search来查找匹配项match = pattern.search(message)if match:serial = match.group(1).strip()  # 提取故障编号repair_situation = match.group(2).strip()  # 提取维修情况repair_person = match.group(3).strip()  # 提取维修人return {"serial": serial,"repair_situation": repair_situation,"repair_person": repair_person}else:return False

更新离线 Excel 表格源码

from datetime import datetimefrom openpyxl.reader.excel import load_workbook# 加载工作簿
wb = load_workbook(filename='故障维修登记表.xlsx')
# 选择活动工作表或者通过名字选择工作表
ws = wb.active  # 使用活动工作表def insert_new_note(repair_data):# 获取行数row_count = ws.max_rownow = datetime.now()# 使用f-string格式化时间formatted_time = f"{now:%Y%m%d-%H%M%S}"data = {"index": row_count,"serial": formatted_time,"fault_location": repair_data['fault_location'],"fault_situation": repair_data['fault_situation'],"reporter": repair_data['reporter'],"repair_situation": "","repair_person": ""}row_num = row_count + 1ws.cell(row=row_num, column=1).value = data['index']ws.cell(row=row_num, column=2).value = data['serial']ws.cell(row=row_num, column=3).value = data['fault_location']ws.cell(row=row_num, column=4).value = data['fault_situation']ws.cell(row=row_num, column=5).value = data['reporter']ws.cell(row=row_num, column=6).value = data['repair_situation']ws.cell(row=row_num, column=7).value = data['repair_person']# 保存工作簿到文件wb.save("故障维修登记表.xlsx")return data['serial']def finish_old_note(solve_data):target_name = solve_data['serial']# 遍历所有行,查找目标值state = Falsefor index, row in enumerate(ws.iter_rows(values_only=True)):if row[1] == "编号":continueif row[1] == target_name:  # 假设"Name"在第一列# 找到目标行后,修改该行的数据# 这里假设我们要修改的是第二列的数据,将其改为"New Value"ws.cell(row=(index + 1), column=6).value = solve_data['repair_situation']ws.cell(row=(index + 1), column=7).value = solve_data['repair_person']state = Truewb.save("故障维修登记表.xlsx")break  # 找到后就退出循环if state:return solve_data['serial']else:return False

主程序 app.py 源码

# -*- coding: utf-8 -*-
import sys
from datetime import datetimeimport ntworkfrom read_repair_data import analysis_repair_data
from read_solve_data import analysis_solve_data
from update_excel import insert_new_note, finish_old_notewework = ntwork.WeWork()# 打开 pc 企业微信, smart: 是否管理已经登录的微信
wework.open(smart=True)# 注册消息回调
@wework.msg_register(ntwork.MT_RECV_TEXT_MSG)
def on_recv_text_msg(wework_instance: ntwork.WeWork, message):data = message["data"]if data['content'][0:1] != "【":returnsender_user_id = data["sender"]self_user_id = wework_instance.get_login_info()["user_id"]conversation_id: str = data["conversation_id"]# 判断消息不是自己发的并且不是群消息时,回复对方if sender_user_id != self_user_id and conversation_id.startswith("R:"):insert_data = analysis_repair_data(data['content'])if insert_data:serial = insert_new_note(insert_data)now = datetime.now()# 使用f-string格式化时间formatted_time = f"{now:%Y-%m-%d %H:%M:%S}"print(f"【反馈结果】【{formatted_time}】请注意存在新的反馈:{serial}")wework_instance.send_text(conversation_id=conversation_id, content=f"【反馈结果】反馈成功\n【故障编号】{serial}")insert_data = analysis_solve_data(data['content'])if insert_data:serial = finish_old_note(insert_data)if serial:# 使用f-string格式化时间now = datetime.now()formatted_time = f"{now:%Y-%m-%d %H:%M:%S}"print(f"【维修结果】【{formatted_time}】请注意存在新的维修:{serial}")wework_instance.send_text(conversation_id=conversation_id, content=f"【维修结果】维修成功\n【故障编号】{str(serial)}")else:wework_instance.send_text(conversation_id=conversation_id, content=f"【操作警告】故障编号不存在!")try:while True:pass
except KeyboardInterrupt:ntwork.exit_()sys.exit()

填报故障真机演示

在这里插入图片描述

维修故障真机演示

在这里插入图片描述

Excel 表格情况预览

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/9929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

H5 css动画效果

你可以使用 CSS 动画来实现这个效果。下面是一个简单的示例代码&#xff0c;展示了如何使用 CSS 中的关键帧动画来放大然后缩小一张图片&#xff0c;并使动画循环播放&#xff1a; html <!DOCTYPE html> <html lang"en"><head><meta charset&qu…

机器学习-Padans

机器学习-Padans 面对人生的烦恼与挫折&#xff0c;最重要的是摆正自己的心态&#xff0c;积极面对一切。再苦再累&#xff0c;也要保持微笑。笑一笑&#xff0c;你的人生会更美好&#xff01; 目录 机器学习-Padans 1.DataFrame 2.画图 3. 扩展&#xff1a; 1.DataFrame #…

Spring MVC分页示例

Spring MVC分页示例 分页用于在不同部分显示大量记录。在这种情况下&#xff0c;我们将在一页中显示10、20或50条记录。对于其余记录&#xff0c;我们提供链接。 我们可以在Spring MVC中简单地创建分页示例。在此分页示例中&#xff0c;我们使用MySQL数据库来获取记录。 创建…

Web实时通信的学习之旅:轮询、WebSocket、SSE的区别以及优缺点

文章目录 一、通信机制1、轮询1.1、短轮询1.2、长轮询 2、Websocket3、Server-Sent Events 二、区别1、连接方式2、协议3、兼容性4、安全性5、优缺点5.1、WebSocket 的优点&#xff1a;5.2、WebSocket 的缺点&#xff1a;5.3、SSE 的优点&#xff1a;5.4、SSE 的缺点&#xff1…

AI图书推荐:ChatGPT全面指南—用AI帮你更健康、更富有、更智慧

你是否在努力改善你的健康&#xff1f; 你是否长期遭受财务困难&#xff1f; 你想丰富你的思想、身体和灵魂吗&#xff1f; 如果是这样&#xff0c;那么这本书就是为你准备的。 《ChatGPT全面指南—用AI帮你更健康、更富有、更智慧》&#xff08;CHATGPT Chronicles AQuick…

【ArcGISProSDK】condition属性

示例 通过caption属性可以看出esri_mapping_openProjectCondition的条件是一个工程被打开 condition的作用 由此可知示例中的Tab实在工程被打开才能使用&#xff0c;否则他禁用显示灰色&#xff0c;在未禁用的时候说明条件满足。 参考文档 insertCondition 元素 (arcgis.com…

操作系统实战(三)(linux+C语言实现)

实验目的 加深对进程调度概念的理解&#xff0c;体验进程调度机制的功能&#xff0c;了解Linux系统中进程调度策略的使用方法。 练习进程调度算法的编程和调试技术。 实验说明 1.在linux系统中调度策略分为3种 SCHED_OTHER&#xff1a;默认的分时调度策略&#xff0c;值为0…

HC-05的简介与使用

蓝牙概述 蓝牙&#xff08;Bluetooth&#xff09;是一种用于无线通信的技术标准&#xff0c;允许设备在短距离内进行数据交换和通信。它是由爱立信&#xff08;Ericsson&#xff09;公司在1994年推出的&#xff0c;以取代传统的有线连接方式&#xff0c;使设备之间能够实现低功…

机器学习-L1正则/L2正则

机器学习-L1正则/L2正则 目录 1.L1正则 2.L2正则 3.结合 1.L1正则 L1正则是一种用来约束模型参数的技术&#xff0c;常用于机器学习和统计建模中&#xff0c;特别是在处理特征选择问题时非常有用。 想象一下&#xff0c;你在装备行囊准备去旅行&#xff0c;但你的行囊有一…

CAP与BASE分布式理论

一、分布式理论 1.CAP理论 CAP理论是说对于分布式数据存储&#xff0c;最多只能同时满足一致性&#xff08;C&#xff0c;Consistency&#xff09;、可用性&#xff08;A&#xff0c; Availability&#xff09;、分区容忍性&#xff08;P&#xff0c;Partition Tolerance&…

debian testing (预计13版本)wps字体无法正常显示

背 景 本人使用debian办公&#xff0c;原来使用的是debian 12,由于“生命不息&#xff0c;折腾不止“&#xff0c;终于将稳定版的debian 12升级为testing. 结果发现&#xff0c;debian 12能够正常使用的wps存在部分字体无法正常显示&#xff0c;经研究发现&#xff0c;原来是w…

(三十九)第 6 章 树和二叉树(二叉树的三叉链表存储)

1. 背景说明 2. 示例代码 1) errorRecord.h // 记录错误宏定义头文件#ifndef ERROR_RECORD_H #define ERROR_RECORD_H#include <stdio.h> #include <string.h> #include <stdint.h>// 从文件路径中提取文件名 #define FILE_NAME(X) strrchr(X, \\) ? strrc…

JINGWHALE 虚拟现实物质与空间理论 —— 全息世界

JINGWHALE 对此论文相关未知以及已知概念、定理、公式、图片等内容的感悟、分析、创新、创造等拥有作品著作权。未经 JINGWHALE 授权&#xff0c;禁止转载与商业使用。 一、虚拟现实物质与空间理论 物质是由离散的奇点JING粒子&#xff0c;依据不同的维度粒度&#xff0c;通过…

uniapp开发微信小程序,选择地理位置uni.chooseLocation

<view click"toCommunity">点击选择位置</view>toCommunity() {const that thisuni.getSetting({success: (res) > {const status res.authSetting// 如果当前设置是&#xff1a;不允许&#xff0c;则需要弹框提醒客户&#xff0c;需要前往设置页面…

EXPLORER - Stone Age

一个程式化的包,包含史前建筑、巨石结构、角色、自然资产、工具和各种道具,可以添加到你的游戏中。 包装内容: + 570 资产。 男性和女性角色,包括数十件服装、皮肤和配饰。 - 8 - 预制角色变体 安装后即可直接使用。 - 15 - 包括动画(8个男性动画和7个女性动画),与Mecan…

从零开始搭建Ubuntu CTF-pwn环境

下面就将介绍如何从零搭建一个CTF-pwn环境&#xff08;由于学习仍在进行&#xff0c;故一些环境如远程执行环境还没有搭建的经历&#xff0c;如今后需要搭建&#xff0c;会在最后进行补充&#xff09; 可以在ubuntu官方网站上下载最新的长期支持版本:(我下载的是22.04版本) h…

指针系列三

文章目录 1.字符指针&#xff1a;2.数组指针&#xff1a;3.二维数组传参的本质4.函数指针变量typedef 关键字 5.函数指针数组6.转移表 1.字符指针&#xff1a; 字符指针&#xff0c;也称为字符串指针&#xff0c;是指向内存中的字符或字符串的指针。 在C语言中&#xff0c;字符…

【树莓派4B】如何用树莓派的串口发送数据给单片机

文章目录 查看路由器中的树莓派IProot连接打开vnc远程桌面服务打开win的远程桌面软件输入IP和端口串口发送数据硬件连接树莓派发送 查看路由器中的树莓派IP root连接 打开vnc远程桌面服务 vncserver :1打开win的远程桌面软件 输入IP和端口 192.168.3.33:1输入密码qwer1234后点…

嫁接打印的技术要点

所谓嫁接打印&#xff0c;是一种增减材混合制造的方式。它将已成形的模具零件当作基座&#xff0c;在此基础上“生长”出打印的零件。其中基座通常采用传统加工方式制造&#xff0c;而打印部分则使用专用的金属粉末&#xff0c;通过 3D 打印技术成型。 嫁接打印之所以备受欢迎&…

Docker + Django跨域解决方案

什么是Django Django 是一个开源的高级 Python Web 框架&#xff0c;它鼓励快速开发并遵循可重用和可维护的实践。Django 是在 MTV&#xff08;模型-模板-视图&#xff09;模式的基础上设计的&#xff0c;这个模式类似于但不同于 MVC&#xff08;模型-视图-控制器&#xff09;模…