首页 > 数字化转型 > CRM > Mud.Feishu 通过特性系统定义 API 契约
// 元数据驱动API定义[HttpClientApi(
RegistryGroupName = "Organization",
TokenManage = nameof(ITenantTokenManager),
Timeout = 50
)]
[Header(Consts.Authorization)]public interface IFeishuTenantV3User{
[Get("/open-apis/contact/v3/users/{user_id}")]
Task<FeishuApiResult<GetUserInfoResult>?> GetUserInfoByIdAsync(
[Path] string user_id,
[Query] string? user_id_type = null);
[Post("/open-apis/contact/v3/users")]
Task<FeishuApiResult<CreateOrUpdateUserResult>?> CreateUserAsync(
[Body] CreateUserRequest userModel,
[Query("user_id_type")] string? user_id_type = Consts.User_Id_Type);
}
1. HttpClientApi 特性(接口级)
/// <summary>/// HTTP客户端API特性,用于标记需要生成HTTP客户端包装类的接口/// </summary>[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false)]internal class HttpClientApiAttribute : Attribute{ /// <summary>
/// HTTP请求的内容类型,默认 "application/json"
/// </summary>
public string ContentType { get; set; } = "application/json"; /// <summary>
/// HTTP连接超时时间(秒),默认50秒
/// </summary>
public int Timeout { get; set; } = 50; /// <summary>
/// 服务注册的分组名称
/// </summary>
public string? RegistryGroupName { get; set; } /// <summary>
/// 令牌管理服务接口的名称
/// </summary>
public string? TokenManage { get; set; } /// <summary>
/// 生成的客户端类是否为抽象类
/// </summary>
public bool IsAbstract {f2n4.org.cn get; set; } /// <summary>
/// 生成的客户端类继承自哪个类
/// </summary>
public string? InheritedFrom { get; set; }
}
2. HTTP 方法特性(方法级)
HTTP 方法特性
GET
POST
PUT
DELETE
PATCH
HEAD
OPTIONS
查询资源
创建资源
更新资源
删除资源
部分更新
获取元数据
获取允许方法
3. 参数绑定特性(参数级)
| 特性 | 说明 | 示例 |
|---|---|---|
[Path] |
绑定到URL路径参数 |
{user_id} |
[Query] |
绑定到查询字符串 |
?page_size=10 |
[Body] |
绑定到请求体 | JSON 请求体 |
[Header] |
绑定到请求头 |
Authorization: Bearer xxx |
[Token] |
自动附加认证令牌 | 自动获取令牌管理器 |
Mud.Feishu 采用三层接口设计模式,实现清晰的职责划分和灵活的扩展能力。
接口层级架构
基础抽象层
IsAbstract=true
通用查询方法
支持多种令牌类型
具体实现层
租户令牌接口
TenantTokenManager
用户令牌接口
UserTokenManager
应用令牌接口
AppTokenManager
模块化扩展
Organization 模块
Message 模块
ChatGroup 模块
Approval 模块
Task 模块
Card 模块
其它 模块
// 基础抽象接口[HttpClientApi(IsAbstract = true, InheritedFrom = nameof(FeishuV3User))]public interface IFeishuV3User{ // 通用查询方法
[Get("/open-apis/contact/v3/users/{user_id}")]
Task<FeishuApiResult<GetUserInfoResult>?> GetUserInfoByIdAsync(
[Path] string user_id,
[Query] string? user_id_type = null);
}// 租户令牌接口[HttpClientApi(TokenManage = nameof(ITenantTokenManager),
RegistryGroupName = "Organization",
InheritedFrom = nameof(FeishuV3User))]
[Header(Consts.Authorization)]public interface IFeishuTenantV3User : IFeishuV3User{ // 租户特有的方法:创建、更新、删除用户
[Post("/open-apis/contact/v3/users")]
Task<FeishuApiResult<CreateOrUpdateUserResult>?> CreateUserAsync(
[Body] CreateUserRequest userModel);
[Patch("/open-apis/contact/v3/users/{user_id}")]
Task<FeishuNullDataApiResult?> UpdateUserAsync(
[Path] string user_id,
[Body] UpdateUserRequest userModel);
}// 用户令牌接口[HttpClientApi(TokenManage = nameof(IUserTokenManager),
RegistryGroupName = "Organization",
InheritedFrom = nameof(FeishuV3User))]
[Header(Consts.Authorization)]public interface IFeishuUserV3User : IFeishuV3User{ // 用户特有的方法:更新个人信息
[Patch("/open-apis/contact/v3/users/{user_id}")]
Task<FeishuNullDataApiResult?> UpdateMyProfileAsync(
[Path] string user_id,
[Body] UpdateUserRequest userModel);
}
原始接口定义:
[HttpClientApi(TokenManage = nameof(ITenantTokenManager),
RegistryGroupName f2z4.org.cn= "Organization")]
[Header(Consts.Authorization)]public interface IFeishuTenantV3User{
[Get("/open-apis/contact/v3/users/{user_id}")]
Task<FeishuApiResult<GetUserInfoResult>?> GetUserInfoByIdAsync(
[Path] string user_id,
[Query] string? user_id_type = null);
}
生成的实现类:
internal class FeishuTenantV3User : IFeishuTenantV3User{ private readonly IEnhancedHttpClient _httpClient; private readonly ITokenManager _tokenManager; public FeishuTenantV3User(
IEnhancedHttpClient httpClient,
ITenantTokenManager tokenManager)
{
_httpClient = httpClient;
_tokenManager = tokenManager;
} public async Task<FeishuApiResult<GetUserInfoResult>?> GetUserInfoByIdAsync( string user_id, string? user_id_type = null,
CancellationToken cancellationToken = default)
{ string access_token = await _tokenManager.GetTokenAsync(); if (string.IsNullOrEmpty(access_token))
{ throw new InvalidOperationException("无法获取访问令牌");
} if (string.IsNullOrEmpty(user_id))
{ throw new ArgumentNullException("user_id");
}
user_id = user_id.Trim(); string url = "/open-apis/contact/v3/users/" + user_id; using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
NameValueCollection queryParams = HttpUtility.ParseQueryString(string.Empty); if (!string.IsNullOrEmpty(user_id_type))
{ string encodedValue = HttpUtility.UrlEncode(user_id_type);
queryParams.Add("user_id_type", encodedValue);
} if (!string.IsNullOrEmpty(department_id_type))
{ string encodedValue2 = HttpUtility.UrlEncode(department_id_type);
queryParams.Add("department_id_type", encodedValue2);
} if (queryParams.Count > 0)
{
_ = url + "?" + queryParams.ToString();
}
request.Headers.Add c4af.org.cn("Authorization", access_token); return await _httpClient.SendAsync<FeishuApiResult<GetUserInfoResult>>(request, cancellationToken);
}
}
Mud.Feishu 提供灵活的服务注册方式,支持按需引入功能模块。
// 构建者模式提供流畅APIbuilder.Services.AddFeishuServices() .ConfigureFrom(configuration) .AddOrganizationApi() // 组织管理 .AddMessageApi() // 消息服务 .AddTokenManagers() // 令牌管理 .Build();
// 按枚举模块注册services.AddFeishuModules( configuration, FeishuModule.Organization, FeishuModule.Message );
// 快速注册令牌管理器services.fzb8.org.cn AddFeishuTokenManagers(configuration);// 快速注册所有服务services.AddFeishuAllServices(configuration);
建造者模式
枚举模块
快速注册
开始服务注册
选择注册方式
AddFeishuServices
AddFeishuModules
AddFeishuAllServices
ConfigureFrom
配置绑定
添加功能模块
AddOrganizationApi
AddMessageApi
AddChatGroupApi
AddApprovalApi
AddTaskApi
AddCardApi
AddFeishuHttpClient
AddTokenManagers
AddOrganizationWebApiHttpClient
AddFeishuHttpClient
AddTokenManagers
AddMessageWebApiHttpClient
AddFeishuHttpClient
AddTokenManagers
AddChatGroupWebApiHttpClient
AddFeishuHttpClient
AddTokenManagers
AddApprovalWebApiHttpClient
AddFeishuHttpClient
AddTokenManagers
AddTaskWebApiHttpClient
AddFeishuHttpClient
AddTokenManagers
AddCardsWebApiHttpClient
Build
验证配置
服务注册
服务注册完成
/// <summary>/// 飞书 API 配置选项类/// </summary>public class FeishuOptions{ /// <summary>
/// 飞书应用唯一标识,创建应用后获得
/// 示例值: "cli_a1b2c3d4e5f6g7h8"
/// </summary>
public required string? AppId { get; set; } /// <summary>
/// 应用秘钥,创建应用后获得
/// 示例值: "dskLLdkasdjlasdKK"
/// </summary>
public required string?a4j5.org.cn AppSecret { get; set; } /// <summary>
/// 飞书 API 基础地址
/// 默认值: "https://open.feishu.cn"
/// </summary>
public string? BaseUrl { get; set; } /// <summary>
/// HTTP 请求超时时间(秒)
/// 默认值:30秒
/// </summary>
public string? TimeOut { get; set; } /// <summary>
/// 失败重试次数
/// 默认值:3次
/// </summary>
public int? RetryCount j5d1.org.cn{ get; set; } /// <summary>
/// 是否启用日志记录,默认为true
/// </summary>
public bool EnableLogging { get; set; } = true;
}
{
"Feishu": {
"AppId": "cli_appid",
"AppSecret": "dskxxxxxx",
"BaseUrl": "https://open.feishu.cn",
"TimeOut": "60",
"RetryCount": 3,
"EnableLogging": true,
"WebSocket": {
"AutoReconnect": true,
"MaxReconnectAttempts": 5,
"ReconnectDelayMs": 5000,
"HeartbeatIntervalMs": 30000,
"ConnectionTimeoutMs": 10000,
"ReceiveBufferSize": 4096,
"EnableLogging": true,
"EnableMessageQueue": true,
"MessageQueueCapacity": 1000,
"ParallelMultiHandlers": true
},
"Webhook": {
"RoutePrefix": t1s4.org.cn"feishu/Webhook",
"AutoRegisterEndpoint": true,
"VerificationToken": "your_verification_token",
"EncryptKey": f1z3.org.cn"your_encrypt_key",
"EnableRequestLogging": true,
"EnableExceptionHandling": true,
"EventHandlingTimeoutMs": 30000,
"MaxConcurrentEvents": 10
}
}}
/// <summary>/// 构建服务注册,包含配置验证/// </summary>public IServiceCollection Build(){ // 验证配置
if (!_configuration.IsConfigured)
{ throw new InvalidOperationException( "必须先配置 FeishuOptions,请使用 ConfigureFrom 或 ConfigureOptions 方法。");
} // 验证至少添加了一个服务
if (!_configuration.HasAnyService())
{ throw new InvalidOperationException( "至少需要添加一个服务,请使用相应的 Add 方法。");
} // 添加配置验证
_services.AddOptions<FeishuOptions>()
.Validate(options => ValidateFeishuOptionsInternal(options), "飞书服务需要在配置文件中正确配置 AppId 和 AppSecret。")
.ValidateOnStart(); return _services;
}/// <summary>/// 内部验证飞书选项的方法///a3f5.org.cn </summary>private static bool ValidateFeishuOptionsInternal(FeishuOptions options) =>
!string.IsNullOrEmpty(options.AppId) && !string.IsNullOrEmpty(options.AppSecret);
IFeishu[令牌类型][版本][资源][扩展]令牌类型:k2g5.org.cn Tenant/User/App 或无(基础接口) 版本:V1/V2/V3 等飞书API版本 资源:User/Departments/Message/ChatGroup等 扩展:Batch/Stream/Manager等(可选)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3107820/ ,如需转载,请注明出处,否则将追究法律责任。