返回首页

简道云消息集成推送到飞书技术文档

企业级简道云工作流自动化与飞书消息通知解决方案

1. 项目概述

简道云消息集成推送到飞书系统是企业级工作流自动化解决方案,实现了简道云工作流与飞书消息的无缝集成。该系统能够接收简道云Webhook通知,根据工作流映射配置将消息发送到对应的飞书群,并支持@特定用户。系统同时支持内部员工通过飞书Open ID接收消息和外部用户通过邮箱接收消息,构建了完整的跨平台工作流通知体系。

1.1 核心功能

1.2 应用场景

该系统适用于需要将简道云工作流通知自动化发送到飞书的企业场景,特别是:

1.3 技术栈

技术类别 具体技术 用途
后端框架 Python Flask 构建Web服务和API
数据库 JSON文件存储 存储员工信息和配置
简道云API 简道云开放平台API 获取用户信息和工作流数据
飞书API 飞书开放平台API 发送消息和获取用户信息
部署方式 独立服务器部署 提供稳定的Webhook服务

2. 系统架构设计

简道云消息集成推送到飞书系统采用模块化设计,各组件之间通过明确的接口通信,实现了高内聚、低耦合的架构。系统主要包含以下核心组件:

Webhook接收模块

  • 接收简道云Webhook请求
  • 验证Webhook签名
  • 解析Webhook数据
  • 调用消息处理模块

消息处理模块

  • 处理简道云消息
  • 匹配用户信息
  • 调用飞书消息发送模块
  • 记录消息发送结果

飞书消息发送模块

  • Webhook消息发送
  • 卡片消息发送
  • @用户提醒
  • 消息结果处理

用户管理模块

  • 员工信息管理
  • 飞书Open ID管理
  • 外部用户邮箱管理
  • 简道云ID映射

配置管理模块

  • 飞书Token管理
  • 工作流映射管理
  • 系统配置管理
  • API密钥管理

数据同步模块

  • 批量更新简道云ID
  • 同步飞书Open ID
  • 定期更新员工信息
简道云消息集成推送到飞书系统架构图 简道云平台 触发工作流,发送Webhook 发送Webhook通知 Webhook接收模块 接收、验证和解析Webhook 调用消息处理 消息处理模块 匹配用户,调用飞书发送 调用消息发送 飞书消息发送模块 发送Webhook消息和卡片消息 调用飞书API 飞书API 发送消息到飞书 员工信息配置 feishu_open_ids.js 读取员工信息 工作流映射配置 workflow_chat_mappings.js 读取映射关系 飞书Token配置 feishu_token.js 读取Token 简道云ID映射配置 update_jdy_ids.py 读取映射关系

2. 简道云配置

2.1 简道云开放平台配置

要使用简道云消息集成功能,首先需要在简道云开放平台进行相关配置:

2.1.1 获取简道云API密钥

  1. 登录简道云开放平台(https://open.jiandaoyun.com/)
  2. 进入开发者后台,点击"创建应用"
  3. 填写应用基本信息,包括应用名称、描述等
  4. 获取API密钥和API密钥Secret
  5. 配置API访问权限

2.1.2 配置简道云工作流Webhook

在简道云工作流设计界面,需要配置以下内容:

  1. 打开简道云工作流设计界面
  2. 选择需要配置的工作流
  3. 添加"Webhook"节点
  4. 配置Webhook URL为:
http://your-server-ip:3100/jiandaoyun/webhook
  1. 选择触发事件(如流程启动、流程完成等)
  2. 配置请求方式为POST
  3. 保存配置并启用Webhook

2.2 简道云ID映射配置

系统支持通过脚本批量更新员工的简道云ID:

# 员工简道云编号映射 taiwan_staff_jdy_map = { "叶XX": "3b82a585", "唐XX": "989g4394", "王XX": "91b4a866", # ... 更多员工映射 }; # 批量更新简道云ID的逻辑 def update_feishu_open_ids(): # 读取feishu_open_ids.js文件 # 批量更新员工的简道云ID # 保存更新后的文件 pass

2.3 运行简道云ID更新脚本

# 运行update_jdy_ids.py脚本更新简道云ID python3 update_jdy_ids.py

3. 飞书配置

3.1 飞书开放平台配置

要使用飞书消息集成功能,首先需要在飞书开放平台进行相关配置:

3.1.1 创建飞书应用

  1. 登录飞书开放平台(https://open.feishu.cn/)
  2. 进入开发者后台,点击"创建应用"
  3. 填写应用基本信息,包括应用名称、描述等
  4. 选择应用类型(自建应用或商店应用)
  5. 点击"创建"按钮完成应用创建

3.1.2 配置应用权限

在应用详情页面,需要配置以下权限:

3.1.3 获取应用凭证

在应用详情页面,获取以下凭证:

3.2 飞书群机器人配置

对于群消息发送,需要在飞书群中添加机器人:

  1. 打开飞书群,点击群设置
  2. 选择"群机器人",点击"添加机器人"
  3. 选择"自定义机器人",填写机器人名称和描述
  4. 获取机器人的Webhook地址
  5. 将Webhook地址配置到workflow_chat_mappings.js文件中

3.3 配置文件说明

配置文件 用途 说明
feishu_open_ids.js 员工信息配置 存储员工姓名、飞书Open ID、邮箱和简道云ID的映射关系
feishu_token.js 飞书Token配置 存储飞书API调用所需的tenant_access_token
workflow_chat_mappings.js 工作流映射配置 配置简道云工作流名称与飞书群的对应关系

3.4 配置文件示例

3.4.1 feishu_open_ids.js

const FEISHU_OPEN_IDS = [ { "name": "张三", "open_id": "ou-xxx", "email": "zhangsan@example.com", "jdy_id": "123456", "update_date": "2026-01-12" }, { "name": "李四", "open_id": "ou-yyy", "email": "lisi@example.com", "jdy_id": "", "update_date": "2026-01-12" } ];

3.4.2 workflow_chat_mappings.js

const WORKFLOW_CHAT_MAPPINGS = { "面试信息": { "webhook_url": "https://open.feishu.cn/open-apis/bot/v2/hook/xxx", "chat_id": "oc_xxx" }, "请假审批": { "webhook_url": "https://open.feishu.cn/open-apis/bot/v2/hook/yyy", "chat_id": "oc_yyy" } };

4. Webhook处理机制

4.1 Webhook处理流程

  1. 接收Webhook请求:系统监听指定端口,接收简道云发送的Webhook请求
  2. 验证请求合法性:验证Webhook请求的签名,确保请求来自可信的简道云服务器
  3. 解析Webhook数据:提取Webhook中的关键信息,包括工作流名称、触发事件、参与者等
  4. 匹配工作流映射:根据工作流名称匹配对应的飞书群配置
  5. 匹配用户信息:根据参与者信息匹配对应的飞书用户
  6. 调用消息发送模块:将处理后的信息传递给飞书消息发送模块
  7. 记录处理结果:记录Webhook处理结果,便于后续查询和调试

4.2 Webhook数据结构

简道云Webhook请求包含以下关键信息:

{ "event": "workflow_trigger", "timestamp": 1640995200, "data": { "workflow_name": "面试信息", "entry_id": "entry_123456", "to": "李四", "from": "张三", "status": "pending", "url": "https://www.jiandaoyun.com/form/entry/123456", "fields": { "field1": "value1", "field2": "value2" } } }

4.3 工作流映射机制

系统通过workflow_chat_mappings.js文件实现简道云工作流与飞书群的映射,支持以下特性:

4.4 代码实现

4.4.1 Webhook接收处理

@app.route('/jiandaoyun/webhook', methods=['POST']) def jiandaoyun_webhook(): """接收简道云Webhook通知""" try: # 接收并解析Webhook数据 data = request.get_json() # 验证Webhook签名(可选) # verify_signature(data) # 提取关键信息 workflow_name = data.get('data', {}).get('workflow_name', '') entry_id = data.get('data', {}).get('entry_id', '') to_user = data.get('data', {}).get('to', '') from_user = data.get('data', {}).get('from', '') status = data.get('data', {}).get('status', '') url = data.get('data', {}).get('url', '') # 根据工作流名称匹配飞书群配置 workflow_config = get_workflow_config(workflow_name) if not workflow_config: print(f"未找到工作流配置: {workflow_name}") return jsonify({"code": 404, "msg": "Workflow not found"}), 404 # 处理消息发送逻辑 # ... 省略消息发送逻辑 return jsonify({"code": 0, "msg": "success"}), 200 except Exception as e: print(f"Webhook处理异常: {str(e)}") return jsonify({"code": 500, "msg": "Internal server error"}), 500

5. 消息发送机制

5.1 消息发送流程

  1. 接收简道云Webhook通知
  2. 解析Webhook请求,提取关键信息
  3. 根据接收人信息匹配飞书用户
  4. 根据工作流名称匹配飞书群
  5. 调用飞书API发送消息
  6. 记录消息发送结果

5.2 消息类型

消息类型 描述 使用场景 实现方式
Webhook消息 通过飞书群机器人发送的文本消息 群内通知、@提醒 调用飞书群机器人Webhook
卡片消息 通过飞书API发送的交互式卡片 详细通知、操作引导 调用飞书ephemeral API

5.3 用户匹配策略

系统采用以下策略匹配飞书用户:

  1. 优先根据jdy_id匹配

    通过简道云ID直接匹配飞书用户,这是最准确的匹配方式。

  2. 根据name匹配,优先空jdy_id记录

    如果jdy_id匹配失败,则根据用户名进行匹配,优先匹配jdy_id为空的记录,避免姓名冲突。

  3. 双轨制消息发送

    内部用户通过飞书Open ID接收消息,外部用户通过邮箱接收消息。

5.4 代码实现

5.4.1 获取用户联系方式

def get_user_contact_by_jdy_username(jdy_username, jdy_payload=None): """根据简道云用户名获取对应的飞书联系方式(open_id或email)""" # 1. 优先根据jdy_id匹配 for staff in feishu_data: if staff.get('jdy_id') == jdy_username: open_id = staff.get('open_id') email = staff.get('email') # 优先使用open_id,只有当open_id不存在时才使用email if open_id: return {'type': 'open_id', 'value': open_id} elif email: return {'type': 'email', 'value': email} else: return None # 2. 如果jdy_id匹配失败,且提供了jdy_payload,则根据name匹配 if jdy_payload: name = jdy_payload.get('data', {}).get('to', '') if name: # 先查找jdy_id为空且name匹配的记录 for staff in feishu_data: if staff.get('name') == name and staff.get('jdy_id') == '': open_id = staff.get('open_id') email = staff.get('email') if open_id: return {'type': 'open_id', 'value': open_id} elif email: return {'type': 'email', 'value': email} else: return None # 如果没有找到jdy_id为空的记录,再查找所有name匹配的记录 for staff in feishu_data: if staff.get('name') == name: open_id = staff.get('open_id') email = staff.get('email') if open_id: return {'type': 'open_id', 'value': open_id} elif email: return {'type': 'email', 'value': email} else: return None return None

5.4.2 发送Webhook消息

def send_feishu_webhook_message(webhook_url, contact, entry_name): """通过飞书机器人Webhook发送@提醒消息""" # 根据联系方式类型构建不同的@语法 if contact['type'] == 'open_id': at_syntax = f"" else: # email类型 at_syntax = f"" # 构建Webhook消息,包含@提醒 webhook_payload = { "msg_type": "text", "content": { "text": f"{at_syntax} 你有新的待办:{entry_name},请查看" } } # 发送Webhook请求 try: response = requests.post(webhook_url, json=webhook_payload, timeout=10) response.raise_for_status() result = response.json() if result.get('code') == 0: return True else: print(f"Webhook消息发送失败: {result.get('msg')}") return False except Exception as e: print(f"Webhook请求异常: {str(e)}") return False

5.4.3 发送卡片消息

def send_feishu_ephemeral_message(tenant_access_token, chat_id, contact, entry_name, notify_text, url): """发送仅特定人可见的飞书消息卡片""" # 构建卡片消息内容 card = { "config": { "wide_screen_mode": True }, "elements": [ { "tag": "div", "text": { "tag": "lark_md", "content": notify_text } }, { "tag": "div", "actions": [ { "tag": "button", "text": { "tag": "plain_text", "content": "查看详情" }, "type": "primary", "url": url } ] } ], "header": { "title": { "content": entry_name, "tag": "plain_text" }, "type": "blue" } } # 构建请求体 payload = { "chat_id": chat_id, "msg_type": "interactive", "card": card } # 根据联系方式类型添加对应的字段 if contact['type'] == 'open_id': payload['open_id'] = contact['value'] else: # email类型 payload['email'] = contact['value'] # 发送API请求 headers = { "Authorization": f"Bearer {tenant_access_token}", "Content-Type": "application/json" } try: response = requests.post( "https://open.feishu.cn/open-apis/ephemeral/v1/send", json=payload, headers=headers, timeout=10 ) response.raise_for_status() result = response.json() if result.get('code') == 0: return True else: print(f"卡片消息发送失败: {result.get('msg')}") return False except Exception as e: print(f"卡片消息请求异常: {str(e)}") return False

6. 用户管理

6.1 员工信息管理界面

系统提供了Web界面用于管理员工信息,访问地址为:

http://your-server-ip:3100/staff

6.2 员工信息字段

字段名 类型 用途 是否必填
name 字符串 员工姓名
jdy_id 字符串 简道云ID
open_id 字符串 飞书Open ID 否(与email二选一)
email 字符串 员工邮箱 否(与open_id二选一)
update_date 日期 更新日期 自动生成

6.3 批量更新员工信息

系统支持通过脚本批量更新员工信息:

# 运行get_feishu_open_ids.py脚本更新飞书Open ID python3 get_feishu_open_ids.py # 运行get_jdy_user_info.py脚本同步简道云用户信息 python3 get_jdy_user_info.py

6.4 支持姓名相同的员工

系统允许添加姓名相同但简道云ID或飞书ID不同的员工记录,通过以下机制实现:

7. API参考

7.1 简道云API调用

7.1.1 获取简道云用户信息

GET https://open.jiandaoyun.com/api/v1/user/{user_id}

请求参数

  • user_id: 简道云用户ID

请求头

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

响应

{"code": 0, "msg": "success", "data": {"user_id": "123456", "name": "张三", "email": "zhangsan@example.com"}}

7.1.2 获取简道云工作流列表

GET https://open.jiandaoyun.com/api/v1/workflow/list

请求参数

  • app_id: 简道云应用ID
  • page: 页码,默认1
  • page_size: 每页数量,默认20

请求头

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

响应

{"code": 0, "msg": "success", "data": {"workflows": [{"workflow_id": "wf_123456", "name": "面试信息"}], "total": 1}}

7.2 飞书API调用

7.2.1 获取tenant_access_token

POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal

请求参数

  • app_id: 飞书应用ID
  • app_secret: 飞书应用密钥

响应

{"code": 0, "msg": "success", "tenant_access_token": "t-xxx", "expire": 7200}

7.2.2 发送ephemeral卡片消息

POST https://open.feishu.cn/open-apis/ephemeral/v1/send

请求参数

  • chat_id: 目标群ID
  • open_id: 可见卡片的用户open_id(与email二选一)
  • email: 可见卡片的用户邮箱(与open_id二选一)
  • msg_type: 消息类型,固定为"interactive"
  • card: 卡片内容,JSON格式

响应

{"code": 0, "msg": "success", "data": {"message_id": "om-xxx"}}

7.3 内部API

7.3.1 获取工作流映射配置

函数 get_workflow_config(workflow_name)

参数

  • workflow_name: 简道云工作流名称

返回值

包含工作流映射配置的字典:

{"webhook_url": "https://open.feishu.cn/open-apis/bot/v2/hook/xxx", "chat_id": "oc_xxx"}

7.3.2 获取用户联系方式

函数 get_user_contact_by_jdy_username(jdy_username, jdy_payload=None)

参数

  • jdy_username: 简道云用户名
  • jdy_payload: 简道云消息payload,可选

返回值

包含联系方式类型和值的字典:

{"type": "open_id", "value": "ou-xxx"}

7.3.3 发送Webhook消息

函数 send_feishu_webhook_message(webhook_url, contact, entry_name)

参数

  • webhook_url: 飞书机器人Webhook地址
  • contact: 用户联系方式字典
  • entry_name: 消息标题

返回值

布尔值,表示消息是否发送成功

8. 故障排除

8.1 常见问题

8.1.1 Webhook接收失败

问题描述: 简道云发送的Webhook请求未能被系统接收。

可能原因及解决方案:

8.1.2 工作流映射匹配失败

问题描述: 系统无法根据工作流名称匹配对应的飞书群配置。

解决方案:

8.1.3 用户匹配失败

问题描述: 系统无法根据简道云用户名匹配对应的飞书用户。

解决方案:

8.1.4 消息发送失败

问题描述: 调用飞书API发送消息失败。

可能原因及解决方案:

8.1.5 @提醒不生效

问题描述: 发送的消息中@提醒没有正确显示。

解决方案:

9. 最佳实践

9.1 架构设计最佳实践

9.2 性能优化

9.3 安全性最佳实践

9.4 运维最佳实践

9.5 配置管理最佳实践