Skip to content

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 集成

🏗️ 项目架构 ​

整体架构图 ​

mermaid
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.FeishuHTTP API 调用HTTP 请求低 (主动查询)数据查询、操作管理
Mud.Feishu.DataModels强类型数据模型编译期引用-请求/响应模型复用
Mud.Feishu.WebSocket实时事件订阅WebSocket 长连接高 (实时推送)实时通知、即时响应
Mud.Feishu.WebhookHTTP 回调处理HTTP 回调中 (被动接收)事件触发、异步处理
Mud.Feishu.Redis分布式去重Redis-多实例部署、防重复
Mud.Feishu.Authentication用户上下文JWT Claims-用户级令牌、租户隔离
Mud.Feishu.EventCallback事件强类型模型编译期引用-事件处理类型安全
Mud.Feishu.OpenTelemetry追踪与指标采集OTLP-可观测性接入

📦 项目概览 ​

组件描述NuGet下载
Mud.Feishu.Abstractions事件订阅抽象层,提供策略模式和工厂模式的事件处理架构,内置 FeishuMetrics 指标收集和事件去重NugetNuget
Mud.Feishu核心 HTTP API 客户端库,支持组织架构、消息、群聊、云文档、画板、电子表格、多维表格等完整飞书功能NugetNuget
Mud.Feishu.DataModels飞书 HTTP API 强类型数据模型库,覆盖全部 API 模块的请求/响应模型NugetNuget
Mud.Feishu.Authentication飞书用户认证中间件,基于 AsyncLocal 实现线程安全的用户上下文管理NugetNuget
Mud.Feishu.EventCallback飞书事件回调强类型数据模型,支持源代码生成器自动生成事件处理器NugetNuget
Mud.Feishu.WebSocket飞书 WebSocket 客户端,支持实时事件订阅、事件去重、消息序号验证和智能重连NugetNuget
Mud.Feishu.Webhook飞书 Webhook 事件处理组件,支持自定义验证器、频率限制、多应用模式和健康检查NugetNuget
Mud.Feishu.RedisRedis 分布式去重扩展,支持事件/Nonce/SeqID 去重、失败分类和多应用隔离NugetNuget
Mud.Feishu.OpenTelemetryOpenTelemetry 适配包,一键开启飞书 SDK 的分布式追踪与指标采集NugetNuget

🚀 快速开始 ​

1️⃣ 安装 NuGet 包 ​

bash
# 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) ​

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) ​

csharp
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️⃣ 验证配置 ​

csharp
// 获取用户信息测试
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 共享相同的处理器接口

mermaid
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(可选)
原生 AOTFeishuJsonAot / 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 长连接的实时事件推送,支持智能连接管理和错误分类处理

mermaid
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 回调事件处理 ​

基于中间件模式的事件接收和分发,具备企业级安全防护和性能优化

mermaid
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)
csharp
// 一键开启飞书 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 调用 ​

csharp
// 创建用户
[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 事件处理 ​

csharp
// 实现事件处理器
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 事件处理 ​

csharp
// 部门创建事件处理器(继承基类)
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();

多应用事件处理 ​

csharp
// 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 切换应用上下文。

csharp
// 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),避免跨租户事件冲突。

事件拦截器 ​

csharp
// 创建日志拦截器
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();

📖 详细文档 ​


🛠️ 技术栈 ​

框架支持 ​

  • .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,并提供 FeishuJsonAot AOT 安全序列化辅助类与 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)
bash
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.HttpUtilsv2.0.7HTTP 客户端工具类(含源代码生成器)
Mud.HttpUtils.Generatorv2.0.7HTTP 客户端代码生成器(编译时)
Microsoft.Extensions.Httpv8.0.1 / v10.0.9HTTP 客户端工厂

📄 许可证 ​

本项目遵循 MIT 许可证,允许商业和非商业用途。


🔗 相关链接 ​

📖 官方文档 ​

📦 NuGet 包 ​

🛠️ 开发资源 ​

🤝 社区支持 ​


如果觉得 MudFeishu 对你有帮助,请给个 ⭐Star 支持一下!

Made with ❤️ by MudTools