MudFeishu
📖 项目简介
MudFeishu 是一套现代化的企业级 .NET 飞书 API 集成 SDK,提供完整的 HTTP API 调用、WebSocket 实时事件订阅和 Webhook 事件处理能力,Native AOT 兼容。SDK 采用策略模式和工厂模式设计,内置自动令牌管理、智能重试、高性能缓存等企业级特性,大幅简化飞书应用的开发难度。
✨ 核心优势
- 🚀 极简 API - 一行代码完成服务注册,开箱即用
- 🏗️ 类型安全 - 强类型数据模型,编译时类型检查
- 🔄 自动令牌管理 - 智能缓存和刷新,无需手动维护
- 🛡️ 企业级稳定 - 统一异常处理、智能重试、详细日志
- 🎯 事件驱动 - 策略模式事件处理,灵活扩展
- 📊 多框架支持 - .NET Standard 2.0、.NET 6.0、.NET 8.0、.NET 10.0
- ⚡ 原生 AOT 支持 - net8.0+ 一等公民支持 Native AOT 发布,全链路源生成 JSON 序列化与配置绑定,严格模式下 IL 警告归零
- 🔒 安全防护 - SSRF 防护、URL 白名单验证、签名验证、加密解密
- 🏢 多应用 / 多租户 - 应用上下文切换、独立令牌缓存与键空间隔离、配置热更新
- 📈 可观测性 - 内置 FeishuMetrics 指标收集,支持 OpenTelemetry 集成
🏗️ 项目架构
整体架构图
graph TB
%% 简化的节点命名
App["业务应用<br/>(Web/移动/微服务)"]
Core["Mud.Feishu<br/>核心API客户端"]
DataModels["Mud.Feishu.DataModels<br/>强类型数据模型"]
WebSocket["Mud.Feishu.WebSocket<br/>实时事件"]
Webhook["Mud.Feishu.Webhook<br/>HTTP回调"]
RedisExt["Mud.Feishu.Redis<br/>分布式去重"]
Auth["Mud.Feishu.Authentication<br/>用户认证中间件"]
Callback["Mud.Feishu.EventCallback<br/>事件回调模型"]
Otel["Mud.Feishu.OpenTelemetry<br/>可观测性"]
Abstraction["Mud.Feishu.Abstractions<br/>事件抽象层"]
Feishu[飞书开放平台]
Config[配置]
Logging[日志]
%% 主要关系
App --> Core
App --> WebSocket
App --> Webhook
App --> Auth
Webhook --> RedisExt
WebSocket --> RedisExt
Otel -.-> Abstraction
%% SDK内部依赖
Core --> Abstraction
Core --> DataModels
WebSocket --> Abstraction
Webhook --> Abstraction
RedisExt --> Abstraction
Auth --> Abstraction
Callback --> Abstraction
%% 通信关系
Core --> Feishu
WebSocket --> Feishu
Feishu --> Webhook
%% 公共依赖
Config -.-> Core
Config -.-> WebSocket
Config -.-> Webhook
Config -.-> RedisExt
Core -.-> Logging
WebSocket -.-> Logging
Webhook -.-> Logging
RedisExt -.-> Logging
%% 布局调整
classDef app fill:#f9f,stroke:#333,stroke-width:2px;
classDef sdk fill:#bbf,stroke:#333,stroke-width:2px;
classDef infra fill:#bfb,stroke:#333,stroke-width:2px;
class App app;
class Core,DataModels,WebSocket,Webhook,RedisExt,Auth,Callback,Otel,Abstraction sdk;
class Feishu,Config,Logging infra;模块功能对比
| 模块 | 核心功能 | 通信方式 | 实时性 | 适用场景 |
|---|---|---|---|---|
| Mud.Feishu | HTTP API 调用 | HTTP 请求 | 低 (主动查询) | 数据查询、操作管理 |
| Mud.Feishu.DataModels | 强类型数据模型 | 编译期引用 | - | 请求/响应模型复用 |
| Mud.Feishu.WebSocket | 实时事件订阅 | WebSocket 长连接 | 高 (实时推送) | 实时通知、即时响应 |
| Mud.Feishu.Webhook | HTTP 回调处理 | HTTP 回调 | 中 (被动接收) | 事件触发、异步处理 |
| Mud.Feishu.Redis | 分布式去重 | Redis | - | 多实例部署、防重复 |
| Mud.Feishu.Authentication | 用户上下文 | JWT Claims | - | 用户级令牌、租户隔离 |
| Mud.Feishu.EventCallback | 事件强类型模型 | 编译期引用 | - | 事件处理类型安全 |
| Mud.Feishu.OpenTelemetry | 追踪与指标采集 | OTLP | - | 可观测性接入 |
📦 项目概览
🚀 快速开始
1️⃣ 安装 NuGet 包
# HTTP API 客户端 (核心模块)
dotnet add package Mud.Feishu
# 事件处理抽象层 (核心模块,Mud.Feishu/WebSocket/Webhook 依赖)
dotnet add package Mud.Feishu.Abstractions
# HTTP API 强类型数据模型 (Mud.Feishu 隐式依赖,通常无需单独安装)
dotnet add package Mud.Feishu.DataModels
# WebSocket 实时事件订阅 (可选)
dotnet add package Mud.Feishu.WebSocket
# Webhook HTTP 回调事件处理 (可选)
dotnet add package Mud.Feishu.Webhook
# 用户认证中间件 (可选)
dotnet add package Mud.Feishu.Authentication
# 事件回调强类型数据模型 (可选)
dotnet add package Mud.Feishu.EventCallback
# Redis 分布式去重扩展 (可选)
dotnet add package Mud.Feishu.Redis
# OpenTelemetry 可观测性扩展 (可选)
dotnet add package Mud.Feishu.OpenTelemetry💡 提示:根据实际需求安装对应包,
Mud.Feishu是核心包,Mud.Feishu.Abstractions和Mud.Feishu.DataModels已作为 Mud.Feishu\WebSocket\Webhook 的依赖自动安装。
2️⃣ 配置文件 (appsettings.json)
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Mud.Feishu": "Debug"
}
},
"FeishuApps": [
{
"AppKey": "default",
"AppId": "your_feishu_app_id",
"AppSecret": "your_feishu_app_secret",
"BaseUrl": "https://open.feishu.cn",
"AllowCustomBaseUrl": false,
"TimeOut": 30,
"RetryCount": 3,
"RetryDelayMs": 1000,
"CircuitBreakerEnabled": true,
"CircuitBreakerFailureThreshold": 20,
"CircuitBreakerSamplingDurationSeconds": 60,
"CircuitBreakerBreakDurationSeconds": 60,
"CircuitBreakerMinimumThroughput": 10,
"TokenRefreshThreshold": 300,
"EnableLogging": true,
"IsDefault": true
}
],
"FeishuWebSocket": {
"AutoReconnect": true,
"MaxReconnectAttempts": 5,
"ReconnectDelayMs": 5000,
"MaxReconnectDelayMs": 30000,
"MaxTotalReconnectTime": "00:30:00",
"ReconnectCooldownTime": "00:00:05",
"EnableReconnectMetrics": true,
"HeartbeatIntervalMs": 25000,
"EnableLogging": true,
"ConnectionTimeoutMs": 10000,
"HealthCheckIntervalMs": 60000,
"InitialReceiveBufferSize": 4096,
"MessageHandlerTimeoutMs": 30000,
"MaxConcurrentHandlers": 32,
"ProtocolKeepAliveInterval": "00:00:20",
"ValidateServerCertificate": true,
"AllowSelfSignedCertificates": false,
"AllowCertificateNameMismatch": false,
"AllowInsecureWebSocket": false,
"SequenceGapThreshold": 0,
"MessageSizeLimits": {
"MaxTextMessageSize": 1048576,
"MaxBinaryMessageSize": 10485760
},
"EventDeduplication": {
"Mode": "InMemory",
"CacheExpiration": "2.00:00:00",
"CleanupInterval": "00:05:00",
"ProcessingTimeout": "00:10:00",
"MaxCacheSize": 100000
}
},
"FeishuWebhook": {
"GlobalRoutePrefix": "feishu",
"EnableRequestLogging": true,
"MaxConcurrentEvents": 10,
"EnforceHeaderSignatureValidation": true,
"TimestampToleranceSeconds": 30,
"NonceValidationFailureMode": "Reject",
"RejectEmptyIdentifiers": true,
"IgnoreUnknownEventTypes": true,
"EventHandlingTimeoutMs": 30000,
"MaxRequestBodySize": 10485760,
"Apps": {
"app1": {
"AppKey": "cli_a1b2c3d4e5f6g7h8",
"VerificationToken": "your_app1_verification_token",
"EncryptKey": "your_app1_encrypt_key_32_bytes_long"
},
"app2": {
"AppKey": "cli_h8g7f6e5d4c3b2a1",
"VerificationToken": "your_app2_verification_token",
"EncryptKey": "your_app2_encrypt_key_32_bytes_long"
}
},
"Retry": {
"EnableRetry": false,
"MaxRetryCount": 3,
"InitialRetryDelaySeconds": 10,
"RetryDelayMultiplier": 2.0,
"MaxRetryDelaySeconds": 300,
"RetryPollIntervalSeconds": 30,
"MaxRetryPerPoll": 10
},
"RateLimit": {
"EnableRateLimit": false,
"WindowSizeSeconds": 60,
"MaxRequestsPerWindow": 100,
"EnableIpRateLimit": true,
"TooManyRequestsStatusCode": 429,
"TooManyRequestsMessage": "请求过于频繁,请稍后再试"
}
}
}💡 TimeSpan 配置说明:
Microsoft.Extensions.Configuration绑定 TimeSpan 时使用TypeDescriptor解析,"hh:mm:ss"三段格式的首段是小时;需要按天配置时使用"d.hh:mm:ss"四段格式(如"2.00:00:00"表示 48 小时)。
3️⃣ 服务注册 (Program.cs)
using Mud.Feishu;
using Mud.Feishu.WebSocket;
using Mud.Feishu.Webhook;
var builder = WebApplication.CreateBuilder(args);
// 注册多应用模式(方式一:从配置文件加载)
builder.Services.AddFeishuApp(builder.Configuration);
// 注册多应用模式(方式二:代码配置)
builder.Services.AddFeishuApp(configure =>
{
configure.AddDefaultApp("default", "cli_xxx", "dsk_xxx");
configure.AddApp("hr-app", "cli_yyy", "dsk_yyy", opt =>
{
opt.TimeOut = 45;
opt.RetryCount = 5;
opt.RetryDelayMs = 2000; // 自定义重试延迟
opt.TokenRefreshThreshold = 300; // Token 刷新阈值(秒)
});
});
// 注册多应用模式(方式三:使用预构建的配置列表)
var configs = new List<FeishuAppConfig>
{
new FeishuAppConfig { AppKey = "default", AppId = "cli_xxx", AppSecret = "dsk_xxx" }, // IsDefault 自动推断
new FeishuAppConfig { AppKey = "hr-app", AppId = "cli_yyy", AppSecret = "dsk_yyy" }
};
builder.Services.AddFeishuApp(configs);
// 注册 HTTP API 服务(懒人模式 - 注册所有服务)
builder.Services.CreateFeishuServicesBuilder()
.AddAllApis()
.Build();
// 注册 HTTP API 服务(构造者模式 - 按需注册)
builder.Services.CreateFeishuServicesBuilder()
.AddOrganizationApi()
.AddMessageApi()
.AddChatGroupApi()
.AddApprovalApi()
.AddTaskApi()
.AddCardApi()
.AddAttendanceApi()
.AddDriveApi()
.AddWikiApi()
.AddDocxApi()
.AddSpreadsheetsApi()
.AddBiTableApi()
.AddCalendarApi()
.AddVideoConferencingApi()
.AddMailApi()
.AddAIApi()
.AddSearchApi()
.AddHelpDeskApi()
.Build();
// 注册 HTTP API 服务(按模块注册)
builder.Services.AddFeishuServices(
FeishuModule.Organization,
FeishuModule.Message,
FeishuModule.ChatGroup,
FeishuModule.Spreadsheets,
FeishuModule.Bitable,
FeishuModule.Calendar,
FeishuModule.VideoConferencing,
FeishuModule.Mail,
FeishuModule.AI,
FeishuModule.Search,
FeishuModule.HelpDesk
);
// 注册 WebSocket 事件订阅服务
builder.Services.CreateFeishuWebSocketServiceBuilder(builder.Configuration, "default")
.AddHandler<MessageEventHandler>()
.Build();
// 注册 Webhook HTTP 回调事件服务
builder.Services.CreateFeishuWebhookServiceBuilder(builder.Configuration)
.AddHandler<MessageReceiveEventHandler>()
.AddHandler<DepartmentCreatedEventHandler>()
.Build();
var app = builder.Build();
// 添加 Webhook 中间件(限流中间件需在 Webhook 中间件之前注册)
// app.UseFeishuRateLimit();
app.UseFeishuWebhook();
app.Run();4️⃣ 验证配置
// 获取用户信息测试
public class TestController : ControllerBase
{
private readonly IFeishuTenantV3User _userApi;
public TestController(IFeishuTenantV3User userApi)
{
_userApi = userApi;
}
[HttpGet("test")]
public async Task<IActionResult> TestConnection()
{
var result = await _userApi.GetUserInfoByIdAsync("test_user_id");
return Ok(new { code = result.Code, message = result.Msg });
}
}🎯 核心功能
🏛️ Mud.Feishu.Abstractions - 事件处理抽象层
统一的事件处理架构,WebSocket 和 Webhook 共享相同的处理器接口
graph LR
A[事件源] --> B{事件类型}
B -->|用户事件| C[UserEventHandler]
B -->|部门事件| D[DepartmentEventHandler]
B -->|消息事件| E[MessageEventHandler]
B -->|未知事件| F[DefaultEventHandler]| 功能特性 | 说明 |
|---|---|
| 策略模式 | 可扩展的事件处理器架构 |
| 工厂模式 | 动态注册和发现处理器 |
| 类型安全 | 强类型数据模型,编译时检查 |
| 自动去重 | 内置事件 ID 去重机制(内存/分布式) |
| 事件拦截器 | 支持事件处理前后的拦截逻辑 |
| 基类处理器 | 简化开发的专用基类 |
| 性能指标 | 内置 FeishuMetrics 指标收集(事件、HTTP、WebSocket、Webhook) |
| SSRF 防护 | URL 白名单验证和私有 IP 检测 |
| SeqID 去重 | WebSocket 二进制消息序列号去重 |
| 令牌存储加密 | EncryptedTokenStore 系列 + EnableTokenEncryption(可选) |
| 原生 AOT | FeishuJsonAot / FeishuJsonDefaults 源生成 JSON 序列化入口 |
支持的基类处理器:
DepartmentCreatedEventHandler- 部门创建DepartmentDeleteEventHandler- 部门删除DefaultFeishuEventHandler<T>- 通用处理器IdempotentFeishuEventHandler<T>- 幂等处理器(自动去重)
核心工具类:
FeishuMetrics/FeishuMetricsHelper- 统一性能指标收集UrlValidator- URL 白名单验证和 SSRF 防护FeishuJsonAot/FeishuJsonDefaults- AOT 安全 JSON 序列化入口TokenKeyBuilder- 令牌键布局单一真相源(Memory / Redis 一致)
🌐 Mud.Feishu - HTTP API 客户端
完整的飞书 API 覆盖,自动令牌管理
| 模块分类 | API 版本 | 主要功能 |
|---|---|---|
| 🔐 认证授权 | V3 | 应用令牌、租户令牌、用户令牌、OAuth 2.0、多应用管理 |
| 👥 组织架构 | V1/V3 | 用户、部门、员工、用户组、职级、职务、角色 |
| 💬 消息服务 | V1 | 文本/图片/卡片消息、批量发送、群聊管理 |
| 📋 审批流程 | V4 | 审批定义、审批实例、审批任务、审批消息、审批订阅 |
| 📝 任务管理 | V2 | 任务创建、更新、分组、附件、评论、自定义字段 |
| 📅 日程会议 | V4 | 日历管理、日程事件、ACL 访问控制 |
| 📹 视频会议 | V1 | 会议管理、会议室、配置、导出、会议数据、纪要、录制、报告 |
| 📄 文档管理 | V1 | 飞书文档、文档块、内容转换 |
| 📚 知识库 | V2 | 知识空间、节点管理、节点复制移动 |
| ☁️ 云盘管理 | V1 | 云空间、文件夹、文件上传、版本管理、权限、评论、订阅 |
| 🎨 画板管理 | V1 | 画板主题、缩略图、节点创建、语法解析 |
| 📊 电子表格 | V2/V3 | 电子表格、区域操作、筛选、数据验证、条件格式 |
| 📋 多维表格 | V1/V2 | 数据表、记录、字段、视图、表单、仪表盘、角色、自动化 |
| ⏰ 考勤管理 | V1 | 考勤组、打卡记录、班次、请假审批、考勤统计、档案 |
| 🎴 卡片管理 | V1/V2 | 卡片管理、卡片元素、消息流卡片 |
| 🤖 AI 能力 | V1 | 文档解析、OCR 识别、语音转文字、文本翻译 |
| 📧 邮箱管理 | V1 | 邮件别名、联系人、草稿、文件夹、邮件组、标签、模板、消息、公共邮箱、规则、会话 |
| 🔍 搜索 | V2 | 数据源搜索、文档/知识库搜索、套件搜索 |
| 🎧 服务台 | V1 | 客服管理、技能、排班、工单、工单消息 |
企业级特性:
- ✅ 自动令牌缓存和刷新(401 恢复真正生效,令牌失效级联清除持久层)
- ✅ 智能重试机制(可配置重试次数和延迟)
- ✅ 高性能缓存(解决缓存击穿)
- ✅ 统一异常处理
- ✅ 连接池管理
- ✅ 详细日志记录
- ✅ 多应用上下文切换支持(
UseApp/BeginScope) - ✅ 配置热更新(
BaseUrl/TimeOut运行期生效,凭据变更即清库) - ✅ 令牌存储加密(可选)
- ✅ 原生 AOT 支持
💡 提示:查看完整 API 文档
📦 Mud.Feishu.DataModels - 强类型数据模型
- ✅ 覆盖全部飞书 API 模块的请求/响应数据模型
- ✅ 强类型设计,编译时类型安全保障
- ✅ 完整 JSON 标注和 XML 文档注释
- ✅ 按模块分目录组织,结构清晰
- ✅ 全量 DTO 由源生成
JsonSerializerContext覆盖(AOT 友好)
🔄 Mud.Feishu.WebSocket - 实时事件订阅
基于 WebSocket 长连接的实时事件推送,支持智能连接管理和错误分类处理
sequenceDiagram
participant Client as 你的应用
participant WS as Mud.Feishu.WebSocket
participant Feishu as 飞书服务器
Client->>WS: 1. 订阅事件
WS->>Feishu: 2. 建立 WebSocket 连接
Feishu-->>WS: 3. 认证成功
loop 实时推送
Feishu-->>WS: 4. 事件消息
WS->>WS: 5. 路由到处理器
WS->>Client: 6. 处理完成
end| 功能分类 | 特性 |
|---|---|
| 连接管理 | 自动重连、心跳检测、连接监控、错误分类处理、重连熔断 |
| 事件处理 | 策略模式、多处理器并行、并发闸门、事件重放 |
| 消息类型 | ping/pong、heartbeat、event、auth |
| 监控运维 | 连接状态、处理统计、健康检查、审计日志、backlog 指标 |
可靠性语义(v3):
- ✅ 事件处理失败不再静默吞异常 - ACK 返回
code=500,飞书服务端将重发,业务处理器必须幂等 - ✅ 可恢复错误 - 网络波动、临时故障等
- ✅ 不可恢复错误 - 认证失败、权限不足等
- ✅ 认证失败按错误码分类,统计总失败次数和失败时间
- ✅ 并发闸门 -
MaxConcurrentHandlers(默认 32) - ✅ 协议级保活 -
ProtocolKeepAliveInterval(默认 20 秒)
💡 提示:查看完整文档
🌐 Mud.Feishu.Webhook - HTTP 回调事件处理
基于中间件模式的事件接收和分发,具备企业级安全防护和性能优化
sequenceDiagram
participant Feishu as 飞书服务器
participant Webhook as Mud.Feishu.Webhook
participant Middleware as 中间件
participant Handler as 事件处理器
Feishu->>Middleware: 1. POST /feishu/{AppKey}
Middleware->>Middleware: 2. 验证时间戳 / Nonce / 签名
Middleware->>Middleware: 3. 解密内容
Middleware->>Webhook: 4. 路由事件
Webhook->>Handler: 5. 调用处理器
Handler-->>Middleware: 6. 处理完成
Middleware-->>Feishu: 7. 返回响应| 功能分类 | 特性 |
|---|---|
| 安全验证 | 时间戳验证、Nonce 两步验证、SHA-256 签名验证、AES-256-CBC 解密、IP 白名单(CIDR)、Content-Type 验证 |
| 事件处理 | 中间件模式、自动路由、策略模式、异步处理、事件拦截器、失败事件重试 |
| 高级功能 | 多应用支持(独立路由/处理器/拦截器)、后台处理、并发控制(支持热更新) |
| 监控运维 | 性能监控、健康检查、请求日志、异常处理、安全审计日志 |
| 安全加固 | 滑动窗口限流、空标识符 fail-closed、生产环境安全项锁定、日志清洗防注入 |
| 性能优化 | 流式请求体读取、源生成器序列化、信号量并发控制、原生 AOT 支持 |
安全增强特性(v3):
- ✅ Nonce 两步验证 - 签名验证前仅检查、签名通过后才标记,签名失败不会误消费 Nonce
- ✅ 空标识符 fail-closed - 空 EventId/Nonce 默认拒绝(
RejectEmptyIdentifiers) - ✅ 生产环境安全项锁定 - 生产环境拒绝关闭签名验证的配置,启动期 fail-fast
- ✅ 重放窗口上限 -
TimestampToleranceSeconds上限 300 秒,且NonceTtl ≥ TimestampToleranceSeconds - ✅ Redis 故障语义分离 - 服务端类致命故障返回 503(让飞书稍后重推),连接类故障按
NonceValidationFailureMode降级 - ✅ 未注册事件静默忽略 -
IgnoreUnknownEventTypes(记录 Debug + unhandled 指标),不再回退兜底处理器 - ✅ at-least-once 语义 - 业务成功后完成标记失败不回滚,处理器需自身幂等
- ✅ 私网 IP 检测 / IP 白名单 - 支持 CIDR 与 IPv4-mapped IPv6 归一
- ✅ 安全审计日志 - 记录所有安全相关事件(成功/失败)
💡 提示:查看完整文档
🔑 Mud.Feishu.Authentication - 用户认证中间件
- ✅ 基于 AsyncLocal 的线程安全用户上下文管理
- ✅ 从 JWT Claims 自动提取飞书用户信息
- ✅ 支持分布式追踪 (ActivitySource)
- ✅ 请求结束后自动清理用户上下文
💡 提示:查看完整文档
📋 Mud.Feishu.EventCallback - 事件回调强类型模型
- ✅ 强类型数据模型(所有事件数据均有完整类型定义和 XML 文档注释)
- ✅ 源代码生成器(自动生成事件处理器基类)
- ✅ 完整事件覆盖(组织架构、即时通讯、审批、任务、云盘、多维表格、考勤等)
- ✅ 原生 AOT 支持
💡 提示:查看完整文档
📦 Mud.Feishu.Redis - Redis 分布式去重
- ✅ 事件去重(Redis Hash + Lua 脚本状态机模式,服务端时钟)
- ✅ Nonce 去重(SET NX EX 防止重放攻击)
- ✅ SeqID 去重(Sorted Set 支持范围查询,
scopeKey实例隔离) - ✅ 统一键构造(
RedisKeyBuilder:分段转义、长度上限、空前缀护栏) - ✅ 可分类异常(
FeishuRedisException+FeishuRedisFailureKind) - ✅ 多应用隔离(所有去重器支持
appKey参数) - ✅ 健康检查(内置 Redis 健康检查)
💡 提示:查看完整文档
📊 Mud.Feishu.OpenTelemetry - 可观测性扩展
- ✅ 一键开启飞书 SDK 分布式追踪与指标采集
- ✅ 自动注册 Feishu ActivitySource 和 Meter(事件处理、Webhook、WebSocket)
- ✅ 自动注册 Mud.HttpUtils 可观测性源(HTTP 请求、Token 刷新、重试)
- ✅ OTLP gRPC 导出,支持 Jaeger/Tempo/Prometheus/Grafana
- ✅ 采样策略配置(ParentBased + TraceIdRatioBased)
- ✅ 资源标签自动填充(service.name、service.version、deployment.environment)
// 一键开启飞书 SDK 的 OpenTelemetry 追踪与指标采集
builder.Services.AddFeishuOpenTelemetry(options =>
{
options.OtlpEndpoint = new Uri("http://otel-collector:4317");
options.ServiceName = "my-feishu-app";
options.SamplingRatio = 0.1; // 生产环境建议 0.1~0.3
});💡 快速开始示例
HTTP API 调用
// 创建用户
[HttpPost("users")]
public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
{
_userApi.UseApp("hr-app");// 多应用场景下切换到 hr-app 应用,单应用场景下可省略
var result = await _userApi.CreateUserAsync(request);
_userApi.UseDefaultApp();// 多应用场景下切换回默认应用, 单应用场景下可省略
return result.Code == 0 ? Ok(result.Data) : BadRequest(result.Msg);
}
// 构造函数注入IFeishuAppManager接口。
private readonly IFeishuAppManager _feishuAppManager;
// 使用IFeishuAppManager获取API接口对象,灵活切换飞书应用。
var tenantJobTitleApi = _feishuAppManager.GetWebApi<IFeishuTenantV3JobTitle>("hr-app");
var result = await tenantJobTitleApi.GetJobTitlesListAsync(10, null);
// 使用作用域切换应用上下文,using 结束后自动恢复
var userApi = _feishuAppManager.GetDefaultWebApi<IFeishuTenantV3User>();
using (userApi.BeginScope("hr-app"))
{
var userResult = await userApi.GetUserInfoByIdAsync("user_123");
}
// 单应用模式下发送消息,无须应用。
var textContent = new MessageTextContent { Text = "Hello World!" };
var result = await messageApi.SendMessageAsync(new SendMessageRequest
{
ReceiveId = "user_123",
MsgType = "text",
Content = JsonSerializer.Serialize(textContent)
}, receive_id_type: "user_id");WebSocket 事件处理
// 实现事件处理器
public class MessageHandler : IFeishuEventHandler
{
public string SupportedEventType => "im.message.receive_v1";
public async Task HandleAsync(EventData eventData, CancellationToken cancellationToken = default)
{
var messageEvent = JsonSerializer.Deserialize<MessageReceiveEvent>(
eventData.Event?.ToString() ?? "{}");
Console.WriteLine($"收到消息: {messageEvent.Message.Content}");
}
}
// 注册处理器
builder.Services.CreateFeishuWebSocketServiceBuilder(builder.Configuration, "default")
.AddHandler<MessageHandler>()
.Build();Webhook 事件处理
// 部门创建事件处理器(继承基类)
public class DepartmentCreatedHandler : DepartmentCreatedEventHandler
{
protected override async Task ProcessBusinessLogicAsync(
EventData eventData,
DepartmentCreatedResult? departmentData,
CancellationToken cancellationToken = default)
{
// 同步到本地数据库(处理器需保证幂等)
await SyncToDatabaseAsync(departmentData);
}
}
// 注册处理器
builder.Services.CreateFeishuWebhookServiceBuilder(builder.Configuration)
.AddHandler<DepartmentCreatedHandler>()
.Build();
// 添加中间件
app.UseFeishuWebhook();多应用事件处理
// WebSocket 多应用事件订阅
builder.Services.CreateFeishuWebSocketServiceBuilder(builder.Configuration, "default")
.AddHandler<DefaultAppEventHandler>()
.Build();
builder.Services.CreateFeishuWebSocketServiceBuilder(builder.Configuration, "hr-app")
.AddHandler<HrAppEventHandler>()
.Build();
// Webhook 多应用事件处理(独立路由、处理器和拦截器)
builder.Services.CreateFeishuWebhookServiceBuilder(builder.Configuration)
.AddHandler<App1Handler>("app1")
.AddInterceptor<App1LoggingInterceptor>("app1")
.AddHandler<App2Handler>("app2")
.Build();多租户部署
多租户 = 多应用。每个租户对应一个
FeishuAppConfig(独立 AppId/AppSecret),通过UseApp/BeginScope切换应用上下文。
// 1. 为每个租户注册应用配置
builder.Services.AddFeishuApp(configure =>
{
configure.AddDefaultApp("tenant-a", "cli_aaa", "dsk_aaa");
configure.AddApp("tenant-b", "cli_bbb", "dsk_bbb");
});
// 2. 注册 HTTP API 服务
builder.Services.CreateFeishuServicesBuilder()
.AddAllApis()
.Build();
// 3. 在请求中按租户切换应用上下文
public class TenantController : ControllerBase
{
private readonly IFeishuAppManager _appManager;
public TenantController(IFeishuAppManager appManager)
{
_appManager = appManager;
}
[HttpGet("tenant/{tenantKey}/users/{userId}")]
public async Task<IActionResult> GetUser(string tenantKey, string userId)
{
// 使用 using 确保作用域结束后自动恢复默认应用
var userApi = _appManager.GetDefaultWebApi<IFeishuTenantV3User>();
using var scope = userApi.BeginScope(tenantKey);
var result = await userApi.GetUserInfoByIdAsync(userId);
return Ok(result);
}
}⚠️ 安全提示:
UseApp/BeginScope仅切换应用上下文(令牌/端点),不做租户隔离授权。 如需限制请求方只能访问其所属租户的数据,应在业务层注册自定义授权逻辑(如基于 Claim 的租户校验中间件)。 组件侧的IAppAccessAuthorizer已对缺失给出错误提示,但本 SDK 不内置授权实现。
🔒 多租户 Redis 隔离:使用 Redis 分布式去重时,应为每个租户设置独立的键前缀 (
EventKeyPrefix/NonceKeyPrefix/SeqIdKeyPrefix),避免跨租户事件冲突。
事件拦截器
// 创建日志拦截器
public class CustomLoggingInterceptor : LoggingEventInterceptor
{
public CustomLoggingInterceptor(ILogger<CustomLoggingInterceptor> logger)
: base(logger)
{
}
protected override Task LogBeforeHandleAsync(
string eventType,
string? eventId,
CancellationToken cancellationToken)
{
_logger.LogInformation("开始处理事件: {EventType}, EventId: {EventId}", eventType, eventId);
return Task.CompletedTask;
}
}
// 注册拦截器
builder.Services.CreateFeishuWebhookServiceBuilder(builder.Configuration)
.AddInterceptor<CustomLoggingInterceptor>()
.AddHandler<DepartmentCreatedHandler>()
.Build();📖 详细文档
- MudFeishu 项目总览 - 组件定位、架构与全部 API 模块使用指南
- 飞书多应用管理及认证授权指南 - 令牌管理、多应用/多租户、配置热更新
- Mud.Feishu.Authentication 用户认证中间件 - 用户上下文与 JWT Claims 提取
- Mud.Feishu.EventCallback 事件回调模型 - 事件强类型模型与代码生成
- Mud.Feishu.WebSocket 实时事件订阅 - 连接管理、重连策略、事件去重
- Mud.Feishu.Webhook 事件回调处理 - 安全验证、解密、多应用与失败重试
- Mud.Feishu.Redis 分布式去重 - 事件/Nonce/SeqID 去重与故障分类
- 更新日志 - 版本更新记录和变更说明
🛠️ 技术栈
框架支持
- .NET Standard 2.0 - 兼容 .NET Framework 4.6.1+
- .NET 6.0 - LTS 长期支持版本
- .NET 8.0 - LTS 长期支持版本(推荐,支持 Native AOT 发布)
- .NET 10.0 - LTS 长期支持版本(推荐,支持 Native AOT 发布)
⚡ Native AOT 支持
MudFeishu 自 3.0.0 起全面适配 .NET Native AOT(net8.0 及以上目标框架一等公民支持),可直接发布为自包含单文件原生二进制:
- 全链路源生成 JSON 序列化 - 所有包内置
JsonSerializerContext(FeishuJsonContext、WebSocketJsonContext、EventCallbackJsonContext等),运行时零反射序列化/反序列化 - 源生成配置绑定 - 启用
EnableConfigurationBindingGenerator,配置 DTO(如FeishuAppConfig)在编译期生成绑定代码;配置 DTO 不使用required修饰,改为Validate()方法校验 - 全局 AOT 分析管控 - net8.0+ 全部工程启用
IsAotCompatible/EnableAotAnalyzer/EnableTrimAnalyzer/TrimMode=full,并提供FeishuJsonAotAOT 安全序列化辅助类与 rd.xml 裁剪兜底 - 质量门禁保障 -
verify-build.ps1集成 AOT 严格模式冒烟构建(逐工程AotStrictMode+--no-incremental),断言AOT00x/IL2026/IL3050诊断为 0 - 专用验证工程 -
Demos/Mud.Feishu.AotVerification覆盖 JSON 序列化、HTTP 客户端、事件处理、WebSocket 协议消息在 AOT 下的端到端验证(win-x64 / linux-x64 双 RID)
dotnet publish -r win-x64 -c Release /p:PublishAot=true⚠️ 注意事项:
- Native AOT 仅支持 net8.0+ 目标框架;netstandard2.0 / net6.0 目标不启用 AOT 分析
- 自定义类型的序列化请通过
FeishuJsonDefaults.ConfigureUserResolver等入口注册自定义JsonSerializerContext,避免运行时反射序列化- 扩展配置 DTO 时不要使用
required修饰(源生成绑定器通过new T()构造),请在Validate()方法中完成必填校验
核心依赖
| 包 | 版本 | 说明 |
|---|---|---|
| Mud.HttpUtils | v2.0.7 | HTTP 客户端工具类(含源代码生成器) |
| Mud.HttpUtils.Generator | v2.0.7 | HTTP 客户端代码生成器(编译时) |
| Microsoft.Extensions.Http | v8.0.1 / v10.0.9 | HTTP 客户端工厂 |
📄 许可证
本项目遵循 MIT 许可证,允许商业和非商业用途。
🔗 相关链接
📖 官方文档
- 飞书开放平台文档 - 飞书 API 官方文档和最佳实践
- NuGet 包管理器 - .NET 包管理官方平台
📦 NuGet 包
- Mud.Feishu.Abstractions - 事件处理抽象层
- Mud.Feishu - 核心 HTTP API 客户端库
- Mud.Feishu.DataModels - HTTP API 强类型数据模型库
- Mud.Feishu.WebSocket - WebSocket 实时事件订阅库
- Mud.Feishu.Webhook - Webhook HTTP 回调事件处理库
- Mud.Feishu.Authentication - 飞书用户认证中间件库
- Mud.Feishu.EventCallback - 飞书事件回调强类型数据模型
- Mud.Feishu.Redis - Redis 分布式去重扩展库
- Mud.Feishu.OpenTelemetry - OpenTelemetry 可观测性扩展库
🛠️ 开发资源
- 项目仓库 - 源代码和开发文档
- Mud.HttpUtils - 声明式 HTTP 客户端与源码生成器
- 示例项目 - 完整的使用示例和演示代码
- 测试项目 - 完整的单元测试和集成测试
🤝 社区支持
如果觉得 MudFeishu 对你有帮助,请给个 ⭐Star 支持一下!
Made with ❤️ by MudTools