聊天里的文件处理不只是下载保存四字。从收到文件到最终归档利用完整链路有四步每步都有要注意的细节。一、感知——知道有文件来了用户在聊天里发文件时Webhook 回调推送消息消息类型标识区分文件消息和文本消息。回调里不包含文件本体只带文件引用临时地址或标识和文件名。感知环节的核心是别漏回调 5 秒内响应 1000文件引用入库丢异步队列不在回调里做下载——下载耗时可能超 5 秒。二、下载——把文件拿到本地拿到文件引用后调下载接口把文件从临时地址拉到本地存储。下载可能失败临时地址过期、网络超时要有重试机制。大文件下载要考虑超时和分片。下载完成后校验文件大小和类型防止下载不完整。三、分类——按文件类型走不同处理下载到本地后按扩展名分类PDF 报表 → 解析提取数据入业务系统Excel 订单 → 解析行列入库Word 合同 → 存档备查图片附件 → 走 OCR 或存图床。分类规则放配置表里新增文件类型时改配置不改代码。不能识别的类型默认存档不做处理。四、归档——文件可检索可追溯文件存到对象存储或本地目录元数据落库消息 ID、发送人、群 ID、文件名、文件类型、存储路径、接收时间、处理状态。归档做好后按发送人查文件、按时间查文件、按文件类型查文件都能做到。文件不再是一次性附件而是可检索的业务资产。四步链路对照处理步骤做什么关键注意点感知回调收到文件消息5 秒响应、引用入库下载拉取文件到本地临时地址时效、重试分类按类型走不同处理配置驱动、兜底存档归档存储 元数据落库可检索可追溯文件处理完整链路app.post(/webhook) def webhook(): d request.json if d.get(messageType) 49: # 文件消息 file_q.put({ msg_id: d[msgId], ref: d[content], name: d.get(fileName, unknown), from: d[fromUser], time: d[createTime] }) return {code: 1000} def file_worker(): while True: job file_q.get() raw download_with_retry(job[ref]) # 下载重试 ext job[name].rsplit(., 1)[-1].lower() handler FILE_HANDLERS.get(ext, archive_only) result handler(raw, job) # 分类处理 path save_to_oss(raw, job[msg_id]) # 归档 db.save_file(job[msg_id], job[from], job[name], path, result)落地建议文件处理最常踩的坑是以为回调里带文件内容。记住回调只给引用内容要自己下载。四步链路里感知和下载必须异步化5 秒限制分类和归档可以慢慢做。文件类型识别要留兜底——不能识别的存起来别丢接口规范参考 Eyun 开发文档。