Files
wingautomation/README.md
T
2026-07-24 11:34:38 +08:00

9.3 KiB
Raw Blame History

文件传输自动化系统

飞书审批驱动的企业文件传输与权限自动化管理系统。

系统架构

飞书审批事件 ──→ Express 服务 ──→ 群晖 NAS API(文件复制)
                    │         ──→ JumpServer API(远程命令)
                    │         ──→ Nextcloud API(文件共享)
                    │
                    ├── SQLite(操作日志)
                    ├── 管理后台(Web UI)
                    └── 飞书机器人(告警通知)

快速开始

1. 环境要求

  • Node.js >= 18
  • 可访问群晖 NAS、JumpServer、Nextcloud 的网络
  • 公网 IP 或域名(用于飞书事件回调)

2. 安装部署

# 克隆项目
git clone <your-repo> file-transfer-automation
cd file-transfer-automation

# 安装依赖
npm install

# 复制配置文件并填写
cp .env.example .env
# 编辑 .env 填入实际的 API 密钥和地址

# 启动
npm start

或使用 Docker

cp .env.example .env
# 编辑 .env
docker-compose up -d

3. 验证

访问 http://你的服务器IP:3000/health 确认服务正常。


飞书应用创建指南(从零开始)

第一步:创建企业自建应用

  1. 打开 飞书开放平台,用管理员账号登录
  2. 点击「创建企业自建应用」
  3. 填写应用名称(如"文件传输自动化")和描述
  4. 创建后进入应用详情页,记录 App IDApp Secret

第二步:配置权限

在应用详情页 →「权限管理」中,搜索并开通以下权限:

权限名称 权限标识 用途
获取审批实例详情 approval:instance:read 读取审批表单内容
同意审批 approval:instance:approve 自动提交审批意见
查看审批定义 approval:approval:read 获取审批配置
添加审批评论 approval:instance:comment 添加审批评论

第三步:配置事件订阅

  1. 进入应用详情页 →「事件订阅」
  2. 请求地址填写:http://你的公网IP:3000/api/feishu/event
  3. 系统会发送验证请求,确保服务已启动
  4. 添加事件:搜索「审批实例状态变更」(approval_instance)
  5. 记录 Verification Token(页面顶部显示)

注意:飞书要求回调地址必须是公网可访问的 HTTP/HTTPS 地址。

第四步:发布应用

  1. 进入「版本管理与发布」
  2. 创建版本 → 提交审核
  3. 管理员在飞书管理后台审核通过

第五步:配置审批流程

在飞书管理后台 → 审批管理中:

  1. 创建/编辑三个审批表单(文件传入、文件传出、红区组权限)
  2. 在审批流程设计中,添加「机器人审批」节点(让应用自动处理)
  3. 记录每个审批的 审批定义 Code(在审批设置页面的 URL 中可以看到)

第六步:配置告警机器人

  1. 在飞书中创建一个告警通知群
  2. 群设置 → 群机器人 → 添加机器人 → 自定义机器人
  3. 记录 Webhook 地址,填入 .envFEISHU_ALERT_WEBHOOK

API 接入说明

群晖 NAS (Synology DSM)

前提条件:

  • DSM 6.0+ 或 7.0+
  • 开启 FileStation API(默认开启)
  • 准备一个有文件管理权限的账号

获取配置:

  • SYNOLOGY_HOST: NAS 地址,如 https://192.168.1.100:5001
  • 使用自签证书时设 SYNOLOGY_SKIP_TLS=true
  • 确保运行本服务的服务器能访问 NAS 的 5001 端口

验证连接:

curl -k "https://NAS_IP:5001/webapi/auth.cgi?api=SYNO.API.Auth&version=6&method=login&account=admin&passwd=xxx&format=sid"

JumpServer 3.x

前提条件:

  • JumpServer 3.x 版本
  • 有 API Key 权限(在 JumpServer 控制台 → 系统设置 → API Key 中创建)
  • ic1 服务器已作为资产录入 JumpServer

获取配置:

  • JUMPSERVER_HOST: JumpServer 地址
  • JUMPSERVER_KEY_ID / JUMPSERVER_KEY_SECRET: API Key
  • JUMPSERVER_ASSET_IC1: 在 JumpServer 控制台 → 资产管理 → 找到 ic1 → URL 中的 UUID
  • JUMPSERVER_SYSTEM_USER: 连接 ic1 使用的系统用户(如 root)

验证连接:

curl -H "Authorization: Token KEY_ID:KEY_SECRET" https://JUMPSERVER_HOST/api/v1/assets/hosts/

Nextcloud

前提条件:

  • Nextcloud 已启用 WebDAV(默认启用)
  • 准备一个有文件管理权限的账号
  • 如需共享功能,确保 files_sharing 应用已启用

获取配置:

  • NEXTCLOUD_HOST: Nextcloud 地址
  • 用户名/密码用于 WebDAV 认证

验证连接:

curl -u user:pass https://NEXTCLOUD_HOST/remote.php/dav/files/user/ -X PROPFIND

部署方案

方案 A:公网 IP 服务器(推荐)

本服务非常轻量(Node.js + SQLite,内存占用约 50-100MB),适合部署在有公网 IP 的服务器上。

# 使用 Docker 部署
docker-compose up -d

# 或直接运行
npm install --production
NODE_ENV=production node src/index.js

配合 Nginx 反向代理(可选,用于 HTTPS):

server {
    listen 443 ssl;
    server_name automation.yourcompany.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

方案 B:无公网 IP 的内网服务器

如果服务必须部署在内网(比如需要直接访问群晖 NAS),有两种方式接收飞书事件:

方式 1:内网穿透(frp

在公网服务器上部署 frps,内网服务器部署 frpc:

# frpc.ini(内网服务器)
[server]
server_addr = 公网服务器IP
server_port = 7000

[file-automation]
type = http
local_port = 3000
custom_domains = automation.yourcompany.com

飞书事件回调地址填:http://automation.yourcompany.com/api/feishu/event

方式 2:飞书长连接模式(推荐)

飞书支持 WebSocket 长连接模式,不需要公网回调地址。修改事件接收方式:

// 使用 @larksuiteoapi/node-sdk 的长连接模式
const { Client, EventDispatcher } = require('@larksuiteoapi/node-sdk');

const client = new Client({ appId, appSecret });
const wsClient = client.event.wsClient; // WebSocket 长连接
wsClient.start(); // 主动连接飞书,无需公网IP

长连接模式需要安装 @larksuiteoapi/node-sdk 包,适合内网部署场景。

方案 C:混合部署

公网服务器放一个轻量转发层(只接收飞书回调),内网服务器跑主业务逻辑:

飞书 ──→ 公网服务器(转发) ──→ 内网服务器(业务处理) ──→ 群晖/JumpServer/Nextcloud

审批表单字段设计

为了让自动化系统正确解析,审批表单字段名需要与代码中的映射一致:

文件传入审批

字段名 类型 说明
申请人 文本/人员 申请人姓名
文件名称 文本 要传入的文件名

文件传出审批

字段名 类型 说明
申请人 文本/人员 申请人姓名
文件路径 文本 文件在服务器上的完整路径
传出目的 单选 内部使用 / 客户发布
客户名缩写 文本 仅客户发布时填写
文件过期日期 日期 仅客户发布时填写

红区组权限审批

字段名 类型 说明
待添加人员 文本/人员 人员姓名
申请类型 单选 添加至已有group / 新建group
group名称 文本 Linux 组名

如果你的表单字段名不同,修改 src/routes/feishu-event.js 中的字段映射即可。


管理后台

访问 http://服务器IP:3000/admin,使用 .env 中配置的 ADMIN_PASSWORD 登录。

功能包括:

  • 仪表盘:今日操作统计、系统状态
  • 操作日志:按类型/状态/时间/关键词筛选,保留30天
  • 预设命令:管理可在 ic1 上执行的预设命令
  • API配置:动态管理配置项

安全机制

  1. 白名单目录:所有文件操作路径必须在白名单内(/IN_R, /OUT_R, /OUT, /wingsemi, /WCPS-Files, /OUT-RED
  2. 路径穿越防护:自动规范化路径,阻止 ../ 攻击
  3. 命令注入防护:禁止 ;$(、反引号、rm -rf 等危险模式
  4. 审批绑定:每次操作记录审批单号、申请人、时间,保留一个月
  5. 防重复处理:同一审批实例不会重复执行
  6. 管理接口限速15分钟内最多100次请求

日志

  • 运行日志:data/logs/combined.log(自动轮转,单文件10MB
  • 错误日志:data/logs/error.log
  • 操作记录:SQLite 数据库 data/automation.db(可通过管理后台查看)

故障排查

问题 可能原因 解决方法
飞书事件收不到 回调地址不通/应用未发布 检查公网访问、确认应用已审核通过
群晖操作失败 Session 过期/权限不足 检查账号权限、确认 FileStation API 开启
JumpServer 命令超时 资产连接慢/网络问题 增加 timeout、检查 ic1 连通性
Nextcloud 403 权限不足/共享功能未启用 检查用户权限、启用 files_sharing
审批意见提交失败 无待处理任务 确认审批流程中有机器人审批节点