企业微信二次开发如何实现机器人文件处理?API接口上传、解析与发送方案
最近做的企微二开,机器人要能处理文件——客户发来订单 Excel,机器人解析后回一份汇总报告;销售让机器人发产品资料 PDF 给客户。和之前聊的文件自动处理不同,那篇重点是接收客户文件做业务解析,这篇重点是机器人自己上传、解析、发送文件的完整闭环——机器人怎么调 CDN 接口上传文件、怎么解析文件内容、怎么把文件发给客户。把调了哪些接口记下来。
Eyun 平台开放的企微 API,统一 POST+JSON,鉴权用 App Token 加 appid(Authorization: Bearer eyk_xxxx),路径 {BASE_URL}/wx-api/api/<模块>/<动作>,响应封套 {code, data, detail, message, time},code 为 0 成功。
文件上传:调 CDN 接口
机器人生成文件后(比如解析完 Excel 生成汇总报告),要上传到 CDN 拿 fileId,再用 fileId 发送。上传调 CDN 模块:
import requests
BASE = "https://api.eyun.com"
HEADERS = {"Authorization": "Bearer eyk_xxxx", "Content-Type": "application/json"}
def upload_file(appid, file_path, file_name):
with open(file_path, "rb") as f:
resp = requests.post(
f"{BASE}/wx-api/api/cdn/upload",
headers={"Authorization": HEADERS["Authorization"]}, # 上传不带Content-Type
files={"file": (file_name, f)},
data={"appid": appid}
)
body = resp.json()
if body["code"] == 0:
return body["data"]["fileId"] # 拿到fileId用于发送
raise Exception(body["message"])
上传是 multipart/form-data,不是 JSON,所以 Content-Type 要去掉,让 requests 自动设。返回的 fileId 是文件在 CDN 的唯一标识,后续发送文件用。
文件下载:调 CDN 接口
客户发来文件,机器人要下载解析。下载调 CDN 模块:
def download_file(appid, file_id, save_path):
resp = requests.post(
f"{BASE}/wx-api/api/cdn/download",
headers=HEADERS,
json={"appid": appid, "fileId": file_id},
stream=True
)
if resp.json().get("code") == 0:
with open(save_path, "wb") as f:
for chunk in resp.iter_content(8192):
f.write(chunk)
return save_path
raise Exception(resp.json()["message"])
下载是流式的,大文件不会爆内存。fileId 从客户发文件消息的回调里拿。下载完存本地或 OSS,解析完删本地文件。
文件解析:按类型处理
下载完按扩展名识别类型,分别解析:
import openpyxl
import PyPDF2
def parse_file(file_path, file_name):
ext = file_name.rsplit(".", 1)[-1].lower()
if ext in ["xlsx", "xls"]:
return parse_excel(file_path)
elif ext == "pdf":
return parse_pdf(file_path)
elif ext == "csv":
return parse_csv(file_path)
else:
return {"type": "unknown", "content": ""}
def parse_excel(file_path):
wb = openpyxl.load_workbook(file_path)
ws = wb.active
headers = [c.value for c in ws[1]]
rows = []
for row in ws.iter_rows(min_row=2, values_only=True):
rows.append(dict(zip(headers, row)))
return {"type": "excel", "headers": headers, "rows": rows}
解析返回结构化数据,机器人基于数据生成回复或报告。表头别名匹配(订单号/订单编号)适应不同客户格式。
发送文件:调消息接口
机器人解析完生成报告文件,上传 CDN 拿 fileId 后,调消息接口发文件给客户:
def send_file(appid, to_uin, file_id, file_name):
resp = requests.post(
f"{BASE}/wx-api/api/message/sendFile",
headers=HEADERS,
json={
"appid": appid,
"to": to_uin,
"fileId": file_id,
"fileName": file_name
}
)
return resp.json()["code"] == 0
fileId 是上传时拿到的,fileName 是客户看到的文件名。发送文件接口和发送文本接口走不同路径——sendFile 而不是 sendText。
完整闭环:接收→解析→生成→发送
客户发 Excel,机器人解析后生成汇总报告发回去,完整流程:
def handle_file_and_reply(appid, from_uin, file_id, file_name):
# 1. 下载文件
local_path = f"/tmp/{file_id}_{file_name}"
download_file(appid, file_id, local_path)
# 2. 解析文件
parsed = parse_file(local_path, file_name)
if parsed["type"] == "excel":
# 3. 生成汇总报告
report_path = generate_report(parsed["rows"])
report_name = f"汇总报告_{file_name}"
# 4. 上传报告到CDN
report_file_id = upload_file(appid, report_path, report_name)
# 5. 发送报告文件给客户
send_file(appid, from_uin, report_file_id, report_name)
# 6. 发文字说明
requests.post(
f"{BASE}/wx-api/api/message/sendText",
headers=HEADERS,
json={"appid": appid, "to": from_uin,
"content": f"已解析 {len(parsed['rows'])} 条数据,汇总报告见文件"}
)
# 清理本地文件
import os
os.remove(local_path)
if 'report_path' in locals():
os.remove(report_path)
整个闭环涉及五个接口调用:cdn/download 下载、解析(本地)、cdn/upload 上传、message/sendFile 发文件、message/sendText 发文字说明。关于文件处理相关接口,在Eyun 企业微信 API 平台有完整说明。
文件处理的几个坑
-
上传是 multipart,不是 JSON,Content-Type 不能带
-
fileId 有有效期(几天),过期的要重新上传
-
大文件上传超时要设长(timeout=120)
-
解析 Excel 大文件要分批读,不然内存爆
-
发送文件后客户可能看不到预览(企微客户端限制),要配文字说明
写在最后
机器人文件处理这套东西,本质是把企微的 CDN 接口和消息接口串起来——cdn/download 下载客户文件、本地解析、cdn/upload 上传处理结果、message/sendFile 发文件给客户。把上传下载做对、解析做扎实、闭环跑通,机器人真正能处理文件——而不是只会发文字的半成品。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)