Bitzsoft.Integrations.TeamWork.DingTalk
1.0.0-alpha.10
This is a prerelease version of Bitzsoft.Integrations.TeamWork.DingTalk.
dotnet add package Bitzsoft.Integrations.TeamWork.DingTalk --version 1.0.0-alpha.10
NuGet\Install-Package Bitzsoft.Integrations.TeamWork.DingTalk -Version 1.0.0-alpha.10
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Bitzsoft.Integrations.TeamWork.DingTalk" Version="1.0.0-alpha.10" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bitzsoft.Integrations.TeamWork.DingTalk" Version="1.0.0-alpha.10" />
<PackageReference Include="Bitzsoft.Integrations.TeamWork.DingTalk" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Bitzsoft.Integrations.TeamWork.DingTalk --version 1.0.0-alpha.10
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Bitzsoft.Integrations.TeamWork.DingTalk, 1.0.0-alpha.10"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Bitzsoft.Integrations.TeamWork.DingTalk@1.0.0-alpha.10
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Bitzsoft.Integrations.TeamWork.DingTalk&version=1.0.0-alpha.10&prerelease
#tool nuget:?package=Bitzsoft.Integrations.TeamWork.DingTalk&version=1.0.0-alpha.10&prerelease
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Bitzsoft.Integrations.TeamWork.DingTalk
钉钉协同办公服务实现 — 对接钉钉开放平台 API。
功能特性
基于 Bitzsoft.Integrations.TeamWork 抽象层实现钉钉 6 个核心能力:
- 组织架构:部门递归遍历、员工分页查询与增删改(
/topapi/v2) - 消息推送:工作通知(文本)、卡片消息(Markdown)、消息撤回(
corpconversation) - 统一待办:创建(按办理人)、查询、标记完成;撤回钉钉不支持(抛
NotSupportedException)(workrecord) - 审批流:发起、状态查询(含
RUNNING/COMPLETED/TERMINATED→ 统一枚举映射)、撤回(processinstance) - SSO 登录:新版 OAuth2 扫码授权、授权码换令牌、令牌刷新、令牌校验、用户信息(
login.dingtalk.com+api.dingtalk.com/v1.0) - 健康检查:通过轻量级鉴权调用探活
- 第三方请求日志:内置 RequestLogging DelegatingHandler,记录所有出站 HTTP 请求与响应
认证机制
钉钉两代 API 共存,本实现按场景分别对接:
| 场景 | Host | 鉴权 |
|---|---|---|
| 组织/消息/待办/审批/健康 | oapi.dingtalk.com |
企业应用 access_token(查询参数,DingTalkAuthHandler 自动注入) |
| SSO 用户令牌/用户信息 | api.dingtalk.com |
OAuth2 用户 Bearer 令牌(由调用方自置) |
| OAuth2 授权页 | login.dingtalk.com |
无 |
DingTalkAuthHandler 仅对 oapi.dingtalk.com 请求追加 access_token 查询参数(显式排除 gettoken 路径防自递归),SSO 请求透传。令牌缓存采用双重检查锁 + SemaphoreSlim,提前 5 分钟刷新,避免边界过期与并发击穿。
安装
.NET CLI
dotnet add package Bitzsoft.Integrations.TeamWork.DingTalk
PackageReference
<PackageReference Include="Bitzsoft.Integrations.TeamWork.DingTalk" Version="1.0.0" />
配置
appsettings.json
{
"TeamWork": {
"DingTalk": {
"AppKey": "钉钉应用 AppKey",
"AppSecret": "钉钉应用 AppSecret",
"AgentId": 123456,
"BaseUrl": "https://oapi.dingtalk.com",
"NewApiBaseUrl": "https://api.dingtalk.com",
"LoginBaseUrl": "https://login.dingtalk.com",
"CallbackToken": "回调 Token(可选)",
"CallbackAesKey": "回调加解密 AES Key(可选)"
}
}
}
| 参数 | 必填 | 默认值 | 说明 |
|---|---|---|---|
AppKey |
是 | — | 钉钉应用 AppKey |
AppSecret |
是 | — | 钉钉应用 AppSecret |
AgentId |
是 | — | 应用 AgentId(工作通知必填) |
BaseUrl |
否 | https://oapi.dingtalk.com |
oapi 基地址(组织/消息/待办/审批/健康) |
NewApiBaseUrl |
否 | https://api.dingtalk.com |
新版 API 基地址(SSO) |
LoginBaseUrl |
否 | https://login.dingtalk.com |
OAuth2 授权页基地址 |
CallbackToken |
否 | — | 事件回调 Token |
CallbackAesKey |
否 | — | 事件回调加解密 Key |
配置在 DI 注册时经 DingTalkOptionsValidator 校验,AppKey/AppSecret/AgentId 缺失或 URL 非 HTTPS 将启动即失败(fail-fast)。
注册服务
从 IConfiguration 绑定(推荐)
using Bitzsoft.Integrations.TeamWork.DingTalk;
builder.Services.AddBitzsoftDingTalkTeamWork(
builder.Configuration, "TeamWork:DingTalk");
委托配置
builder.Services.AddBitzsoftDingTalkTeamWork(opts =>
{
opts.AppKey = "your-app-key";
opts.AppSecret = "your-app-secret";
opts.AgentId = 123456;
});
第三方请求日志
内置 Bitzsoft.Integrations.RequestLogging 出站请求记录管道,默认使用 NullRequestLogStore 不持久化。
// ① 默认:启用记录管道但不持久化(日志丢弃)
services.AddBitzsoftDingTalkTeamWork(configuration, "TeamWork:DingTalk");
// ② 持久化:宿主注册 IRequestLogStore 实现后,所有出站请求自动落库
services.AddRequestLogging<MyRequestLogStore>(opts =>
{
opts.MaxInMemoryBodyBytes = 64 * 1024; // 仅控制内存/加密临时文件切换,不截断正文
opts.SensitiveFields.Add("mySecret");
});
services.AddBitzsoftDingTalkTeamWork(configuration, "TeamWork:DingTalk");
使用示例
消息推送
using Bitzsoft.Integrations.TeamWork.Models.Message;
using Bitzsoft.Integrations.TeamWork.Interfaces;
public class NoticeService(ITeamWorkMessageProvider message)
{
public Task<MessageSendResult> NotifyAsync(IReadOnlyList<string> userIds) =>
message.SendWorkNotificationAsync(new WorkNotificationRequest
{
ToUserIds = userIds,
Title = "系统通知",
Content = "您有一条新待办"
});
public Task<MessageSendResult> NotifyCardAsync(IReadOnlyList<string> userIds) =>
message.SendCardMessageAsync(new CardMessageRequest
{
ToUserIds = userIds,
Title = "Markdown 卡片",
Content = "## 标题\n> 正文"
});
}
组织架构
public class OrgService(ITeamWorkOrgProvider org)
{
// parentId 为空时从根部门递归获取整棵子树
public Task<IReadOnlyList<DepartmentInfo>> GetDeptsAsync() => org.GetDepartmentsAsync();
// departmentId 为空时查询根部门直接成员
public Task<IReadOnlyList<EmployeeInfo>> GetEmployeesAsync() => org.GetEmployeesAsync();
}
SSO 单点登录
public class LoginController(ITeamWorkSsoProvider sso)
{
public string BuildLoginUrl(string redirectUri) => sso.GetAuthorizationUrl(redirectUri);
public async Task<UserInfo> LoginAsync(string code, string redirectUri)
{
var token = await sso.GetAccessTokenAsync(code, redirectUri);
return await sso.GetUserInfoAsync(token.AccessToken);
}
}
待办与审批
public class BizService(ITeamWorkTodoProvider todo, ITeamWorkApprovalProvider approval)
{
public Task<string> CreateTodoAsync(string userId) => todo.CreateTodoAsync(new TodoCreateRequest
{
Subject = "待处理工单",
AssigneeUserIds = new[] { userId },
ActionUrl = "https://app/todo/1"
});
public Task<string> StartApprovalAsync(string userId) => approval.StartApprovalAsync(new ApprovalStartRequest
{
ProcessCode = "PROC-LEAVE",
OriginatorUserId = userId,
FormData = new Dictionary<string, string> { ["days"] = "1" }
});
}
核心类型一览
| 类型 | 说明 |
|---|---|
DingTalkTeamWorkProvider |
钉钉实现(同时实现 6 个核心接口,注册为 Singleton) |
DingTalkOptions |
配置(AppKey / AppSecret / AgentId / BaseUrl 等) |
ITeamWorkOrgProvider |
组织架构接口(部门、员工增删改查) |
ITeamWorkMessageProvider |
消息推送接口(工作通知、卡片消息、撤回) |
ITeamWorkTodoProvider |
统一待办接口(创建、状态更新、查询、撤回) |
ITeamWorkApprovalProvider |
审批流接口(发起、状态查询、撤回) |
ITeamWorkSsoProvider |
SSO 登录接口(授权 URL、换令牌、用户信息) |
ITeamWorkHealthProvider |
健康检查接口(连通性探活) |
平台限制说明
- 部门接口(
listsub)仅返回下一级子部门,GetDepartmentsAsync内部递归获取整棵子树。 - 员工接口(
user/list)按部门查询,GetEmployeesAsync默认查根部门直接成员;全公司员工需遍历各部门。 - 待办(
workrecord)仅支持标记完成,RecallTodoAsync抛NotSupportedException。
依赖
| 包 | 说明 |
|---|---|
Bitzsoft.Integrations.TeamWork |
协同办公抽象层 |
Bitzsoft.Integrations.Compatibility |
基础工具库 |
Bitzsoft.Integrations.RequestLogging |
出站请求记录管道 |
Microsoft.Extensions.Configuration.Abstractions |
配置抽象 |
Microsoft.Extensions.Http |
IHttpClientFactory |
Microsoft.Extensions.Options.ConfigurationExtensions |
Options 配置节点绑定 |
相关包
- Bitzsoft.Integrations.TeamWork -- 协同办公抽象层
- Bitzsoft.Integrations.TeamWork.All -- 聚合包(自动注册全部供应商)
- Bitzsoft.Integrations.TeamWork.WeCom -- 企业微信实现
- Bitzsoft.Integrations.TeamWork.Feishu -- 飞书实现
- Bitzsoft.Integrations.Compatibility -- 基础工具库
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- Bitzsoft.Integrations.Compatibility (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.Core (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.TeamWork (>= 1.0.0-alpha.10)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http (>= 10.0.10)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.10)
-
net5.0
- Bitzsoft.Integrations.Compatibility (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.Core (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.TeamWork (>= 1.0.0-alpha.10)
- Microsoft.Extensions.Configuration.Abstractions (>= 5.0.0)
- Microsoft.Extensions.Http (>= 5.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 5.0.0)
-
net8.0
- Bitzsoft.Integrations.Compatibility (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.Core (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.0-alpha.10)
- Bitzsoft.Integrations.TeamWork (>= 1.0.0-alpha.10)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http (>= 10.0.10)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-alpha.10 | 27 | 7/26/2026 |
| 1.0.0-alpha.9 | 59 | 7/12/2026 |
| 1.0.0-alpha.8 | 310 | 7/1/2026 |
| 1.0.0-alpha.7 | 70 | 6/16/2026 |
| 1.0.0-alpha.6 | 69 | 6/16/2026 |
| 1.0.0-alpha.5 | 61 | 6/14/2026 |