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" />
                    
Directory.Packages.props
<PackageReference Include="Bitzsoft.Integrations.TeamWork.DingTalk" />
                    
Project file
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
                    
#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
                    
Install as a Cake Addin
#tool nuget:?package=Bitzsoft.Integrations.TeamWork.DingTalk&version=1.0.0-alpha.10&prerelease
                    
Install as a Cake Tool

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)仅支持标记完成,RecallTodoAsyncNotSupportedException

依赖

说明
Bitzsoft.Integrations.TeamWork 协同办公抽象层
Bitzsoft.Integrations.Compatibility 基础工具库
Bitzsoft.Integrations.RequestLogging 出站请求记录管道
Microsoft.Extensions.Configuration.Abstractions 配置抽象
Microsoft.Extensions.Http IHttpClientFactory
Microsoft.Extensions.Options.ConfigurationExtensions Options 配置节点绑定

相关包

Product 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.

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