GaoXinLibrary.TencentSDK 1.0.18

There is a newer version of this package available.
See the version list below for details.
dotnet add package GaoXinLibrary.TencentSDK --version 1.0.18
                    
NuGet\Install-Package GaoXinLibrary.TencentSDK -Version 1.0.18
                    
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="GaoXinLibrary.TencentSDK" Version="1.0.18" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GaoXinLibrary.TencentSDK" Version="1.0.18" />
                    
Directory.Packages.props
<PackageReference Include="GaoXinLibrary.TencentSDK" />
                    
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 GaoXinLibrary.TencentSDK --version 1.0.18
                    
#r "nuget: GaoXinLibrary.TencentSDK, 1.0.18"
                    
#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 GaoXinLibrary.TencentSDK@1.0.18
                    
#: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=GaoXinLibrary.TencentSDK&version=1.0.18
                    
Install as a Cake Addin
#tool nuget:?package=GaoXinLibrary.TencentSDK&version=1.0.18
                    
Install as a Cake Tool

GaoXinLibrary.TencentSDK

腾讯平台统一 .NET 服务端 SDK,整合 企业微信(Wecom)微信(小程序、公众号、开放平台、QQ 互联) 核心接口。

一个包覆盖腾讯主流开放平台,开箱即用、接口对齐官方文档、支持依赖注入与多实例。

NuGet


✨ 特性

  • 🎯 统一包 — 微信小程序、公众号、开放平台、QQ 互联、企业微信,一个 NuGet 包全部搞定
  • 🔌 依赖注入友好 — 提供 AddWechatMiniProgramService / AddWechatOfficialService / AddWechatOpenService / AddQQConnectService / AddWecomService 扩展方法,开箱即注入
  • 🔑 Keyed Services 多实例 — 同一平台注册多套凭证(如多个企业微信应用),通过 [FromKeyedServices("name")] 注入
  • 🔄 access_token 自动管理 — 内置缓存与自动刷新,无需手动维护 Token 生命周期
  • 🛡️ 消息回调加解密 — 企业微信与公众号回调消息的签名校验、AES 加解密一站式支持
  • 📦 会话内容存档 — 企业微信会话存档原生 SDK 封装(含 RSA 解密)
  • 🔄 瞬态故障自动重试 — 网络抖动、连接超时、服务端 5xx 等临时性故障自动按指数退避重试,可通过 RetryOptions 配置
  • 🎯 多目标框架 — 同时支持 .NET 8 / .NET 9 / .NET 10,各版本自动匹配对应的 Microsoft.Extensions.*
  • 📖 XML 文档注释 — 所有公开 API 均附带完整 XML 文档,IDE 智能提示开箱即用

📦 安装

NuGet 包管理器

dotnet add package GaoXinLibrary.TencentSDK

Package Manager Console

Install-Package GaoXinLibrary.TencentSDK

要求

依赖 版本
.NET 8.0 / 9.0 / 10.0
Microsoft.Extensions.DependencyInjection.Abstractions 对应 TFM 版本
Microsoft.Extensions.Http 对应 TFM 版本
Microsoft.Extensions.Options 对应 TFM 版本

🗂️ 功能概览

微信(Wechat)

小程序 — WechatMiniProgramClient
模块 属性 服务接口 核心功能
登录与手机号 Auth IMiniProgramAuthService Code2SessionAsync 登录凭证校验 / GetPhoneNumberAsync 获取手机号 / CheckSessionKeyAsync 校验 session_key / ResetUserSessionKeyAsync 重置 session_key
小程序码 QrCode IMiniProgramQrCodeService GetUnlimitedAsync 不限制小程序码 / GetQrCodeAsync 有限小程序码 / CreateQrCodeAsync 小程序二维码
订阅消息 SubscribeMessage IMiniProgramSubscribeMessageService SendAsync 发送订阅消息
内容安全 Security IMiniProgramSecurityService MsgSecCheckAsync 文本内容安全检测 / MediaCheckAsync 音视频内容安全异步检测 / GetUserRiskRankAsync 获取用户安全等级
发货信息 Shipping IMiniProgramShippingService UploadShippingInfoAsync 发货信息录入 / UploadCombinedShippingInfoAsync 合单发货录入 / GetOrderAsync 查询订单发货状态 / IsTradeManagedAsync 查询交易结算确认
OCR Ocr IMiniProgramOcrService IdCardAsync 身份证 / BankCardAsync 银行卡 / DrivingAsync 行驶证 / DrivingLicenseAsync 驾驶证 / BizLicenseAsync 营业执照 / CommAsync 通用印刷体 / AiCropAsync 图片智能裁切
链接生成 Link IMiniProgramLinkService GenerateSchemeAsync 生成 URL Scheme / GenerateUrlLinkAsync 生成 URL Link / GenerateShortLinkAsync 生成 Short Link
数据分析 DataAnalysis IMiniProgramDataAnalysisService GetDailySummaryTrendAsync 概况趋势 / GetDailyVisitTrendAsync 访问趋势 / GetVisitPageAsync 访问页面 / GetUserPortraitAsync 用户画像 / GetVisitDistributionAsync 访问分布
物流助手 Express IMiniProgramExpressService GetAllDeliveryAsync 获取快递公司列表 / GetOrderAsync 查询运单 / GetPathAsync 获取运单轨迹
运维中心 Operation IMiniProgramOperationService GetDomainInfoAsync 域名配置 / GetPerformanceAsync 性能数据 / GetSceneListAsync 访问来源 / GetVersionListAsync 客户端版本 / RealtimeLogSearchAsync 实时日志 / GetFeedbackListAsync 用户反馈 / GetFeedbackMediaAsync 反馈图片 / JsErrSearchAsync JS 错误列表 / GetJsErrDetailAsync JS 错误详情 / GetGrayReleasePlanAsync 分阶段发布详情
硬件设备 Device IMiniProgramDeviceService SendMessageAsync 发送设备消息
客服消息 CustomMessage IMiniProgramCustomMessageService SendAsync 发送客服消息 / SetTypingAsync 下发输入状态
OpenAPI OpenApi IMiniProgramOpenApiService ClearQuotaAsync 清除调用次数 / ClearApiQuotaAsync 重置指定 API 调用次数 / ClearQuotaByAppSecretAsync 使用 AppSecret 重置 / GetQuotaAsync 查询调用额度 / GetRidInfoAsync 查询 rid 信息 / CallbackCheckAsync 网络通信检测 / GetApiDomainIpAsync API 服务器 IP / GetCallbackIpAsync 推送服务器 IP
公众号 — WechatOfficialClient
模块 属性 服务接口 核心功能
OAuth 网页授权 OAuth IOfficialOAuthService BuildAuthUrl 构造授权 URL / GetAccessTokenAsync code 换取 access_token / RefreshTokenAsync 刷新 token / GetUserInfoAsync 拉取用户信息
自定义菜单 Menu IOfficialMenuService CreateAsync 创建菜单 / GetAsync 查询菜单 / DeleteAsync 删除菜单
模板消息 TemplateMessage IOfficialTemplateMessageService SendAsync 发送模板消息
用户管理 User IOfficialUserService GetInfoAsync 获取用户信息 / BatchGetInfoAsync 批量获取 / GetListAsync 用户列表 / GetAllOpenIdsAsync 全部 OpenId(自动分页) / UpdateRemarkAsync 设置备注名 / BatchBlacklistAsync 拉黑用户 / BatchUnblacklistAsync 取消拉黑 / GetBlacklistAsync 黑名单列表 / ChangeOpenIdAsync 迁移后转换 OpenId
服务号二维码 QrCode IOfficialQrCodeService 带参二维码:CreateTemporaryAsync/CreatePermanentAsync/BuildShowUrl / 扫码打开小程序:AddOrUpdateJumpRuleAsync/GetJumpRulesAsync/PublishJumpRuleAsync/DeleteJumpRuleAsync / 长短链:GenerateShortLinkAsync/FetchShortLinkAsync
素材管理 Material IOfficialMaterialService GetCountAsync 素材总数 / GetMaterialAsync 获取永久素材 / DeleteMaterialAsync 删除永久素材 / BatchGetAsync 素材列表 / UploadTempMaterialAsync 上传临时素材(Stream / ReadOnlyMemory) / DownloadTempMaterialBytesAsync 下载临时素材 byte[] / DownloadTempMaterialReadOnlyAsync 下载 ReadOnlyMemory / AddPermanentMaterialAsync 新增永久素材(Stream / ReadOnlyMemory)
JS-SDK JsSdk IOfficialJsSdkService GetTicketAsync 获取 jsapi_ticket(自动缓存) / CreateSignature 计算签名 / InvalidateTicketCache 使缓存失效 / RefreshTicketAsync 强制刷新 / SetTicket 手动设置 / GetSharedTicketAsync 获取共享加密 Ticket
用户标签 Tag IOfficialTagService CreateAsync 创建标签 / GetAllAsync 获取全部标签 / UpdateAsync 编辑标签 / DeleteAsync 删除标签 / GetUsersAsync 标签下粉丝列表 / BatchTagAsync 批量打标签 / BatchUntagAsync 批量取消 / GetUserTagsAsync 获取用户标签
草稿箱 Draft IOfficialDraftService AddAsync 新建草稿 / GetAsync 获取草稿 / DeleteAsync 删除草稿 / BatchGetAsync 草稿列表 / GetCountAsync 草稿总数
发布能力 Publish IOfficialPublishService SubmitAsync 发布草稿 / GetAsync 查询发布状态 / DeleteAsync 删除发布 / GetArticleAsync 获取已发布文章 / BatchGetAsync 成功发布列表
留言管理 Comment IOfficialCommentService OpenAsync 打开评论 / CloseAsync 关闭评论 / ListAsync 查看评论 / ReplyAsync 回复评论 / DeleteAsync 删除评论 / DeleteReplyAsync 删除回复 / MarkElectAsync 精选 / UnmarkElectAsync 取消精选
客服消息 CustomMessage IOfficialCustomMessageService SendAsync 发送客服消息 / SetTypingAsync 下发输入状态 / AddKfAccountAsync 添加客服帐号 / UpdateKfAccountAsync 修改客服帐号 / DeleteKfAccountAsync 删除客服帐号 / GetKfListAsync 获取所有客服
群发消息 Message IOfficialMessageService MassSendAllAsync 按标签群发 / MassSendAsync 按 OpenId 群发 / MassDeleteAsync 删除群发 / MassPreviewAsync 预览 / MassGetAsync 查询发送状态 / SetIndustryAsync 设置行业 / GetIndustryAsync 获取行业 / AddTemplateAsync 获得模板 ID / GetTemplateListAsync 模板列表 / DeleteTemplateAsync 删除模板
数据统计 DataAnalysis IOfficialDataAnalysisService GetUserSummaryAsync 用户增减 / GetUserCumulateAsync 累计用户 / GetArticleSummaryAsync 图文群发每日 / GetArticleTotalAsync 图文群发总数据 / GetUserReadAsync 图文统计 / GetUserShareAsync 分享转发 / GetUpstreamMsgAsync 消息发送概况 / GetInterfaceSummaryAsync 接口分析
智能接口 Ai IOfficialAiService SemanticSearchAsync 语义理解 / OcrIdCardAsync 身份证 OCR / OcrBankCardAsync 银行卡 OCR / OcrDrivingAsync 行驶证 OCR / OcrBizLicenseAsync 营业执照 OCR
门店管理 Poi IOfficialPoiService AddAsync 创建门店 / GetAsync 查询门店 / GetListAsync 门店列表 / UpdateAsync 修改门店 / DeleteAsync 删除门店
微信发票 Invoice IOfficialInvoiceService 商户开票:SetAuthFieldAsync/GetAuthFieldAsync/SetPayMchAsync/GetPayMchAsync/SetContactAsync/GetContactAsync / 开票平台:GetPlatformInvoiceUrlAsync/GetPlatformPdfAsync/UpdatePlatformInvoiceStatusAsync/UploadPlatformPdfAsync/CreatePlatformCardAsync/InsertInvoiceAsync / 发票报销&自助打印:GetReimburseInvoiceAsync/UpdateReimburseInvoiceStatusAsync/BatchUpdateReimburseInvoiceStatusAsync/BatchGetReimburseInvoiceAsync / 极速开发票:GetUserTitleUrlAsync/GetSelectTitleUrlAsync/ScanTitleAsync / 非税票据:GetNonTaxAuthUrlAsync/CreateNonTaxCardAsync/InsertNonTaxInvoiceAsync
OpenAPI OpenApi IOfficialOpenApiService ClearQuotaAsync 清空调用 quota / GetQuotaAsync 查询调用额度 / GetRidInfoAsync 查询 rid 信息
消息回调 Callback IOfficialCallbackService VerifyUrl 明文模式验证 / VerifyUrlEncrypted 安全模式验证 / ParseMessage 解析明文消息 / DecryptAndParse 解密并解析消息 / EncryptReply 加密被动回复 / GetCallbackIpAsync 获取微信服务器 IP
开放平台 — WechatOpenClient
模块 属性 服务接口 核心功能
网站登录 WebLogin IOpenPlatformService BuildAuthUrl 构造扫码登录 URL / GetAccessTokenAsync code 换取 access_token / RefreshTokenAsync 刷新 token / GetUserInfoAsync 获取用户信息 / CheckAccessTokenAsync 检验凭证有效性 / GetPcOpenSdkTicketAsync 获取 PC OpenSDK ticket
QQ 互联 — QQConnectClient
模块 属性 服务接口 核心功能
QQ 登录 Login IQQConnectService BuildAuthUrl 构造授权页面 URL / GetAccessTokenAsync code 换取 access_token / RefreshTokenAsync 刷新 token / GetOpenIdAsync 获取用户 OpenID / GetUserInfoAsync 获取用户信息

企业微信(Wecom) — WecomClient

模块 属性 服务接口 核心功能
成员管理 User IUserService 创建 / 读取 / 更新 / 删除 / 批量删除 / userId⇄openId 转换 / 手机号/邮箱查 userId / 邀请成员 / 分页列表
部门管理 Department IDepartmentService 创建 / 更新 / 列表 / 详情 / 删除
标签管理 Tag ITagService 创建 / 删除 / 添加删除成员 / 列表
应用消息 Message IMessageService 文本 / Markdown / 图文 / 文本卡片 / 小程序通知 / 模版卡片 / 更新模版卡片 / 撤回
群机器人 Webhook IWebhookService 文本 / Markdown / 图文 / 图片 / 文件 Webhook 推送
应用管理 Agent IAgentService 获取应用信息 / 应用列表 / 设置应用 / 设置工作台模板 / 自定义菜单管理
自定义菜单 Menu IMenuService 创建 / 获取 / 删除应用菜单(AgentId 自动取自 WecomOptions,无需手动传入)
素材管理 Media IMediaService 上传临时素材 / 上传图片 / 获取素材
群聊会话 GroupChat IGroupChatService 创建群聊 / 修改 / 获取 / 发送群聊消息
OAuth OAuth IOAuthService 构造授权 URL / code 换取用户身份 / user_ticket 换取敏感信息
JS-SDK JsSdk IJsSdkService 企业级/应用级 jsapi_ticket 自动缓存与共享、H5 JS-SDK 签名
消息回调 Callback ICallbackService URL 验证 / 消息解析与解密 / 被动回复加密 / 回调 IP 段 / 通讯录变更回调(成员/部门/标签)/ 审批状态回调 / 异步任务完成回调
智能机器人 SmartRobot ISmartRobotService 回调 URL 验证 / 消息解密与解析(text / image / voice / video / location / link / attachment) / 事件解析(enter_chat / subscribe / click 等) / 被动回复加密(text / image / voice / video / news / markdown / template_card) / 主动发送消息 / 智能表格群聊列表 / 群聊详情 / 修改群聊
智能机器人长连接 SmartRobotWs ISmartRobotWsClient WebSocket 长连接(无需公网 IP / 消息加解密)/ 订阅消息与事件 / 回复欢迎语 / 回复消息(支持流式)/ 更新模板卡片 / 主动推送消息 / 分片上传素材 / 心跳保活 / 文档工具调用回传(API 模式)
微信客服 Kf IKfService 微信客服管理
打卡 Checkin ICheckinService 打卡规则 / 打卡数据查询
审批 Approval IApprovalService 审批模板详情 / 提交审批申请(支持 ApplyEventBuilder 链式构建)/ 批量获取审批单号(支持自动分页 GetAllApprovalNoAsync)/ 审批详情 / 假期管理 / 审批状态变更回调
会话存档 MsgAudit IMsgAuditService 会话内容存档(含 RSA 解密)
企业互联 CorpGroup ICorpGroupService 上下游企业管理
互联企业 LinkedCorp ILinkedCorpService 互联企业通讯录
异步导出 Export IExportService 异步数据导出任务
异步导入 AsyncImport IAsyncImportService 增量更新成员 / 全量覆盖成员 / 全量覆盖部门 / 获取异步任务结果
二次验证 SecondVerify ISecondVerifyService 获取二次验证信息 / 登录二次验证确认
安全管理 Security ISecurityService 文件防泄漏规则 / 设备管理
高级功能账号 AdvancedAccount IAdvancedAccountService 分配 / 取消 / 列表查询高级功能账号
操作日志 OperationLog IOperationLogService 成员操作记录 / 管理端操作日志
账号 ID 管理 AccountId IAccountIdService tmp_external_userid 转换
IP 段查询 IpRange IIpRangeService 获取接口 IP 段 / 获取回调 IP 段
客户联系 ExternalContact IExternalContactService 成员配置列表 / 客户列表 / 详情 / 批量获取 / 修改备注 / 客户群列表 / 联系统计 / 新客户欢迎语
企业支付 CorpPay ICorpPayService 对外收款账单列表 / 收款项目账单列表
邮件 Email IEmailService 发送邮件 / 获取未读数
文档 Document IDocumentService 新建 / 获取基础信息 / 重命名 / 删除 / 分享文档
日程 Calendar ICalendarService 日历增删改查 / 日程增删改查 / 按日历获取日程
会议 Meeting IMeetingService 创建 / 修改 / 取消 / 详情 / 成员会议列表
微盘 Wedrive IWedriveService 空间创建 / 重命名 / 解散 / 详情 / 文件列表 / 创建文件 / 重命名 / 删除 / 移动
直播 Living ILivingService 创建 / 修改 / 取消直播 / 删除回放 / 详情 / 成员直播列表
公费电话 Dial IDialService 获取公费电话拨打记录
汇报 Report IReportService 批量获取汇报记录单号 / 汇报详情
人事助手 Hr IHrService 员工字段配置 / 花名册信息查询与更新
会议室 MeetingRoom IMeetingRoomService 添加 / 列表 / 编辑 / 删除会议室 / 查询预定信息 / 预定 / 取消预定
电子发票 Invoice IInvoiceService 查询 / 批量查询 / 更新 / 批量更新发票状态
智能表格 SmartSheet ISmartSheetService 子表增删改查 / 字段增删改查 / 记录增删改查 / 视图列表
收集表 CollectForm ICollectFormService 创建 / 修改 / 获取收集表 / 获取答案

🚀 快速开始

微信小程序

using GaoXinLibrary.TencentSDK.Wechat;
using GaoXinLibrary.TencentSDK.Wechat.Core;

// 创建客户端
var client = WechatMiniProgramClient.Create(new WechatMiniProgramOptions
{
    AppId     = "your_appid",
    AppSecret = "your_appsecret"
});

// 小程序登录:通过 js_code 换取 session 信息
var session = await client.Auth.Code2SessionAsync("js_code_from_wx_login");
Console.WriteLine($"OpenId: {session.OpenId}, SessionKey: {session.SessionKey}");

// 获取手机号
var phone = await client.Auth.GetPhoneNumberAsync("phone_code_from_button");
Console.WriteLine($"手机号: {phone.PhoneNumber}");

// 生成小程序码
var qrCodeBytes = await client.QrCode.GetUnlimitedQrCodeAsync("scene_value", "pages/index/index");

// 发送订阅消息
await client.SubscribeMessage.SendAsync(new { /* ... */ });

// 内容安全检测
var result = await client.Security.MsgSecCheckAsync("待检测的文本内容");

微信公众号

using GaoXinLibrary.TencentSDK.Wechat;
using GaoXinLibrary.TencentSDK.Wechat.Core;
using GaoXinLibrary.TencentSDK.Wechat.Models.OfficialAccount;

var client = WechatOfficialClient.Create(new WechatOfficialOptions
{
    AppId                 = "your_appid",
    AppSecret             = "your_appsecret",
    CallbackToken         = "your_callback_token",         // 消息回调用
    CallbackEncodingAesKey = "your_43char_encoding_aes_key" // 消息回调用
});

// OAuth 网页授权
var authUrl = client.OAuth.BuildAuthUrl(redirectUri: "https://example.com/callback");
// 用户同意后,通过 code 换取用户信息
// var userInfo = await client.OAuth.GetUserInfoAsync("code_from_callback");

// 发送模板消息
await client.TemplateMessage.SendAsync(new
{
    touser      = "OPENID",
    template_id = "TEMPLATE_ID",
    url         = "https://example.com",
    data        = new { /* 模板数据 */ }
});

// JS-SDK 签名
var jsConfig = await client.JsSdk.GetConfigAsync("https://example.com/page");

// 拉黑用户 / 取消拉黑
await client.User.BatchBlacklistAsync(new BatchBlacklistRequest
{
    OpenIdList = new() { "OPENID_1", "OPENID_2" }
});
await client.User.BatchUnblacklistAsync(new BatchBlacklistRequest
{
    OpenIdList = new() { "OPENID_1" }
});

// 迁移场景:转换 OpenId
var changed = await client.User.ChangeOpenIdAsync(new ChangeOpenIdRequest
{
    FromAppId = "gh_91ae50dfeb1c",
    OpenIdList = new() { "OLD_OPENID" }
});

// 服务号二维码(永久字符串场景值)
var qr = await client.QrCode.CreatePermanentAsync("scene:campaign-2026");
var qrImageUrl = client.QrCode.BuildShowUrl(qr.Ticket!);

// 扫码打开小程序规则(服务号二维码)
await client.QrCode.AddOrUpdateJumpRuleAsync(new QrcodeJumpAddRequest
{
    Prefix = "http://weixin.qq.com/q/kZgfwMTm72Wxxxx",
    AppId = "wxxxxxx",
    Path = "pages/index/index",
    IsEdit = 0
});

// 长信息与短链
var shortResp = await client.QrCode.GenerateShortLinkAsync(new ShortLinkGenerateRequest
{
    LongData = "https://example.com/very/long/path",
    ExpireSeconds = 86400
});
var longResp = await client.QrCode.FetchShortLinkAsync(new ShortLinkFetchRequest
{
    ShortKey = shortResp.ShortKey!
});

// 微信发票(商户开票)—— 设置并查询联系方式
await client.Invoice.SetContactAsync(new InvoiceSetContactRequest
{
    Contact = new InvoiceContactInfo
    {
        Phone = "88888888",
        TimeOut = 12345
    }
});
var contact = await client.Invoice.GetContactAsync();

// 开票平台:获取识别码链接 / 创建卡券模板
var invoiceUrl = await client.Invoice.GetPlatformInvoiceUrlAsync();
var card = await client.Invoice.CreatePlatformCardAsync(new InvoicePlatformCreateCardRequest
{
    InvoiceInfo = new InvoicePlatformCardInfo
    {
        BaseInfo = new InvoicePlatformCardBaseInfo
        {
            Payee = "某某科技有限公司",
            LogoUrl = "https://example.com/logo.png"
        }
    }
});

// 极速开发票:获取商户专属抬头链接
var titleUrl = await client.Invoice.GetSelectTitleUrlAsync(new InvoiceGetSelectTitleUrlRequest
{
    BizName = "某某科技"
});

// 上传临时素材(ReadOnlyMemory 版本)
ReadOnlyMemory<byte> imageBytes = await File.ReadAllBytesAsync("demo.jpg");
var tempUpload = await client.Material.UploadTempMaterialAsync(imageBytes, "demo.jpg", "image");

// 下载临时素材(byte[] / ReadOnlyMemory 两种形式)
var tempBytes = await client.Material.DownloadTempMaterialBytesAsync(tempUpload.MediaId);
var tempReadOnly = await client.Material.DownloadTempMaterialReadOnlyAsync(tempUpload.MediaId);

// 新增永久素材(ReadOnlyMemory 版本)
var permanent = await client.Material.AddPermanentMaterialAsync(imageBytes, "demo.jpg", "image");

微信开放平台(网站扫码登录)

using GaoXinLibrary.TencentSDK.Wechat;
using GaoXinLibrary.TencentSDK.Wechat.Core;

var client = WechatOpenClient.Create(new WechatOpenOptions
{
    AppId     = "your_open_appid",
    AppSecret = "your_open_appsecret"
});

// 构造扫码登录 URL
var loginUrl = client.WebLogin.BuildAuthUrl("https://example.com/callback", state: "random_state");

// 用户扫码后,通过 code 换取 access_token 和用户信息
// var tokenInfo = await client.WebLogin.GetAccessTokenAsync("code_from_callback");
// var userInfo  = await client.WebLogin.GetUserInfoAsync(tokenInfo.AccessToken, tokenInfo.OpenId);

QQ 互联(网站 QQ 登录)

using GaoXinLibrary.TencentSDK.Wechat;
using GaoXinLibrary.TencentSDK.Wechat.Core;

var client = QQConnectClient.Create(new QQConnectOptions
{
    AppId     = "your_qq_appid",
    AppSecret = "your_qq_appkey"
});

// 构造 QQ 登录 URL
var loginUrl = client.Login.BuildAuthUrl("https://example.com/callback", state: "random_state");

// 用户授权后,通过 code 换取 access_token → openid → 用户信息
// var token    = await client.Login.GetAccessTokenAsync("code_from_callback");
// var openId   = await client.Login.GetOpenIdAsync(token.AccessToken);
// var userInfo = await client.Login.GetUserInfoAsync(token.AccessToken, openId);

企业微信

using GaoXinLibrary.TencentSDK.Wecom;
using GaoXinLibrary.TencentSDK.Wecom.Core;
using GaoXinLibrary.TencentSDK.Wecom.Models.User;
using GaoXinLibrary.TencentSDK.Wecom.Models.Message;
using GaoXinLibrary.TencentSDK.Wecom.Models.Meeting;
using GaoXinLibrary.TencentSDK.Wecom.Models.Document;
using GaoXinLibrary.TencentSDK.Wecom.Models.Calendar;
using GaoXinLibrary.TencentSDK.Wecom.Models.Invoice;

var client = WecomClient.Create(new WecomOptions
{
    CorpId     = "your_corpid",
    CorpSecret = "your_corpsecret",
    AgentId    = 1000001
});

// 发送文本消息(@all 发送给所有人)— 便捷方法
var resp = await client.Message.SendTextAsync("Hello, 企业微信!", toUser: "@all");
Console.WriteLine($"MsgId: {resp.MsgId}");

// 发送 Markdown 消息
await client.Message.SendMarkdownAsync("## 通知\n> 这是一条 **Markdown** 消息", toUser: "@all");

// 撤回消息 — 使用 Request Model
await client.Message.RecallMessageAsync(new RecallMessageRequest { MsgId = resp.MsgId });

// 获取成员信息
var user = await client.User.GetUserAsync("zhangsan");
Console.WriteLine($"姓名: {user.Name}, 手机: {user.Mobile}");

// userid 转 openid — 使用 Request Model
var openId = await client.User.ConvertUserIdToOpenIdAsync(new ConvertToOpenIdRequest
{
    UserId = "zhangsan"
});

// 手机号获取 userid
var uid = await client.User.GetUserIdByMobileAsync(new GetUserIdByMobileRequest
{
    Mobile = "13800000000"
});

// 批量删除成员
await client.User.BatchDeleteUsersAsync(new BatchDeleteUserRequest
{
    UserIdList = ["user1", "user2"]
});

// 获取部门列表
var depts = await client.Department.GetDepartmentListAsync();

// Webhook 群机器人
await client.Webhook.SendTextAsync("YOUR_WEBHOOK_KEY", "机器人消息");
await client.Webhook.SendMarkdownAsync("YOUR_WEBHOOK_KEY", "## 告警\n> 服务异常");

// 获取当前应用信息(AgentId 自动取自 WecomOptions,无需手动传入)
var agentInfo = await client.Agent.GetAgentAsync();
Console.WriteLine($"应用名称: {agentInfo.Name}");

// 获取 / 创建 / 删除应用自定义菜单(AgentId 自动注入)
var buttons = await client.Menu.GetMenuAsync();
await client.Menu.DeleteMenuAsync();

// OAuth 网页授权
var oauthUrl = client.OAuth.BuildAuthUrl(
    redirectUri: "https://your-domain.com/callback",
    agentId: 1000001);

// 创建预约会议
var meeting = await client.Meeting.CreateMeetingAsync(new CreateMeetingRequest
{
    Title        = "项目周会",
    AdminUserId  = "zhangsan",
    MeetingStart = DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeSeconds(),
    MeetingEnd   = DateTimeOffset.UtcNow.AddHours(2).ToUnixTimeSeconds()
});

// 新建文档
var doc = await client.Document.CreateDocAsync(new CreateDocRequest
{
    DocName = "会议纪要",
    DocType = 1 // 1-文档, 3-表格
});

// 创建日历
var calId = await client.Calendar.CreateCalendarAsync(new CreateCalendarRequest
{
    Calendar = new CalendarInfo
    {
        Summary     = "团队日程",
        Description = "技术团队共享日历"
    }
});

// 查询电子发票
var invoice = await client.Invoice.GetInvoiceInfoAsync(new GetInvoiceInfoRequest
{
    CardId       = "CARD_ID",
    EncryptCode  = "ENCRYPT_CODE"
});

💡 API 设计说明:所有 POST 接口的方法均接受强类型 Request Model 作为参数,每个 Model 均包含完整的 [JsonPropertyName] 和 XML 文档注释。部分高频接口(如消息发送)额外提供便捷方法(SendTextAsync / SendMarkdownAsync 等)。


💉 依赖注入

基本用法

using GaoXinLibrary.TencentSDK.Wechat.Extensions;
using GaoXinLibrary.TencentSDK.Wecom.Extensions;

var builder = WebApplication.CreateBuilder(args);

// 注册微信小程序
builder.Services.AddWechatMiniProgramService(options =>
{
    options.AppId     = "mini_appid";
    options.AppSecret = "mini_secret";
});

// 注册微信公众号
builder.Services.AddWechatOfficialService(options =>
{
    options.AppId                  = "official_appid";
    options.AppSecret              = "official_secret";
    options.CallbackToken          = "callback_token";
    options.CallbackEncodingAesKey = "encoding_aes_key";
});

// 注册微信开放平台
builder.Services.AddWechatOpenService(options =>
{
    options.AppId     = "open_appid";
    options.AppSecret = "open_secret";
});

// 注册 QQ 互联
builder.Services.AddQQConnectService(options =>
{
    options.AppId     = "qq_appid";
    options.AppSecret = "qq_appkey";
});

// 注册企业微信
builder.Services.AddWecomService(options =>
{
    options.CorpId     = "your_corpid";
    options.CorpSecret = "your_corpsecret";
    options.AgentId    = 1000001;
});

注册后可以通过构造函数注入门面客户端或子服务接口:

// 方式一:注入门面客户端
public class MyController(WecomClient wecom, WechatMiniProgramClient miniProgram)
{
    public async Task SendNotification()
    {
        await wecom.Message.SendTextAsync("通知内容", toUser: "@all");
    }

    public async Task<string> MiniProgramLogin(string code)
    {
        var session = await miniProgram.Auth.Code2SessionAsync(code);
        return session.OpenId;
    }
}

// 方式二:注入子服务接口(推荐,便于单元测试 Mock)
public class NotificationService(IMessageService messageService, IUserService userService)
{
    public async Task NotifyUserAsync(string userId, string content)
    {
        var user = await userService.GetUserAsync(userId);
        if (user != null)
        {
            await messageService.SendTextAsync(content, toUser: userId);
        }
    }

    public async Task<string> GetOpenIdAsync(string userId)
    {
        // POST 接口使用强类型 Request Model
        return await userService.ConvertUserIdToOpenIdAsync(
            new ConvertToOpenIdRequest { UserId = userId });
    }
}

多实例注册(Keyed Services)

当同一平台需要注册多套凭证时(例如企业微信有多个应用),使用带 name 参数的重载:

// 注册多个企业微信应用
builder.Services.AddWecomService("agent1", opt =>
{
    opt.CorpId = "corp1"; opt.CorpSecret = "secret1"; opt.AgentId = 1000001;
});
builder.Services.AddWecomService("agent2", opt =>
{
    opt.CorpId = "corp1"; opt.CorpSecret = "secret2"; opt.AgentId = 1000002;
});

// 注册多个小程序
builder.Services.AddWechatMiniProgramService("appA", opt =>
{
    opt.AppId = "appid_a"; opt.AppSecret = "secret_a";
});
builder.Services.AddWechatMiniProgramService("appB", opt =>
{
    opt.AppId = "appid_b"; opt.AppSecret = "secret_b";
});

通过 [FromKeyedServices] 注入指定实例:

public class MultiAgentService(
    [FromKeyedServices("agent1")] IMessageService msgAgent1,
    [FromKeyedServices("agent2")] IMessageService msgAgent2)
{
    public async Task NotifyBothAsync(string content)
    {
        await msgAgent1.SendTextAsync(content, toUser: "@all");
        await msgAgent2.SendTextAsync(content, toUser: "@all");
    }
}

从配置文件绑定(IConfiguration)

所有 DI 扩展方法均支持直接传入 IConfiguration(如 IConfigurationSection),自动绑定到对应的 Options 类,无需手动编写委托:

// appsettings.json
{
  "WechatMiniProgram": {
    "AppId": "mini_appid",
    "AppSecret": "mini_secret"
  },
  "WechatOfficial": {
    "AppId": "official_appid",
    "AppSecret": "official_secret",
    "CallbackToken": "callback_token",
    "CallbackEncodingAesKey": "encoding_aes_key"
  },
  "WechatOpen": {
    "AppId": "open_appid",
    "AppSecret": "open_secret"
  },
  "QQConnect": {
    "AppId": "qq_appid",
    "AppSecret": "qq_appkey"
  },
  "Wecom": {
    "CorpId": "your_corpid",
    "CorpSecret": "your_corpsecret",
    "AgentId": 1000001
  }
}
using GaoXinLibrary.TencentSDK.Wechat.Extensions;
using GaoXinLibrary.TencentSDK.Wecom.Extensions;

var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;

// 从配置节绑定(单实例)
builder.Services.AddWechatMiniProgramService(config.GetSection("WechatMiniProgram"));
builder.Services.AddWechatOfficialService(config.GetSection("WechatOfficial"));
builder.Services.AddWechatOpenService(config.GetSection("WechatOpen"));
builder.Services.AddQQConnectService(config.GetSection("QQConnect"));
builder.Services.AddWecomService(config.GetSection("Wecom"));

多实例同样支持 IConfiguration 绑定:

// appsettings.json
{
  "WecomAgent1": {
    "CorpId": "corp1",
    "CorpSecret": "secret1",
    "AgentId": 1000001
  },
  "WecomAgent2": {
    "CorpId": "corp1",
    "CorpSecret": "secret2",
    "AgentId": 1000002
  }
}
// 带 key 的多实例 + IConfiguration
builder.Services.AddWecomService("agent1", config.GetSection("WecomAgent1"));
builder.Services.AddWecomService("agent2", config.GetSection("WecomAgent2"));

builder.Services.AddWechatMiniProgramService("appA", config.GetSection("MiniProgramA"));
builder.Services.AddWechatMiniProgramService("appB", config.GetSection("MiniProgramB"));

💡 所有 Options 类的属性均支持 IConfiguration 绑定,包括 RetryOptionsHttpTimeout 等嵌套/复杂类型。


⚙️ 配置参数

微信配置 — WechatOptions(基类)

属性 类型 默认值 说明
AppId string "" 应用 ID(AppID)
AppSecret string "" 应用密钥(AppSecret)
BaseUrl string https://api.weixin.qq.com API 基础地址
HttpTimeout TimeSpan 30 秒 HTTP 请求超时时间
ShareSecret string? 共享 Token 密钥(ChaCha20-Poly1305,详见跨服务共享 Token
TokenShareUrl string? 远端共享 Token 地址;设置后从此地址拉取加密 Token,而非直接请求微信 API
SecretShareUrl string? 统一共享密钥远端地址;详见统一共享密钥
OnTokenChanged Func<string, CancellationToken, Task>? Token 刷新成功后的变更通知回调,参数为新的明文 access_token
RetryOptions TencentRetryOptions new() 瞬态故障重试配置(网络抖动、超时、5xx),详见瞬态故障自动重试
属性 类型 说明
CallbackToken string? 接收消息回调的 Token(签名校验)
CallbackEncodingAesKey string? 接收消息回调的 EncodingAESKey(43 位字符)
TicketShareSecret string? jsapi_ticket 共享密钥(ChaCha20-Poly1305)
TicketShareUrl string? jsapi_ticket 共享远端地址
OnTicketChanged Func<string, CancellationToken, Task>? jsapi_ticket 刷新成功后的变更通知回调
QQConnectOptions(继承 WechatOptions
属性 类型 默认值 说明
BaseUrl string https://graph.qq.com QQ 互联 API 基础地址

企业微信配置 — WecomOptions

属性 类型 默认值 说明
CorpId string "" 企业 ID(corpid)
CorpSecret string "" 应用凭证密钥(corpsecret)
AgentId int 0 自建应用 AgentId;Agent / Menu / Message 等服务均自动从此处读取,无需在调用时重复传入
BaseUrl string https://qyapi.weixin.qq.com API 基础地址
HttpTimeout TimeSpan 30 秒 HTTP 请求超时时间
CallbackToken string? 接收消息回调的 Token
CallbackEncodingAesKey string? 接收消息回调的 EncodingAESKey(43 位)
BotId string? 智能机器人 WebSocket 长连接的 BotId(从企业微信管理端获取)
BotSecret string? 智能机器人 WebSocket 长连接的 BotSecret(从企业微信管理端获取)
BotWsUrl string wss://openws.work.weixin.qq.com 智能机器人 WebSocket 长连接地址
MsgAuditSecret string? 会话内容存档密钥
MsgAuditPrivateKey string? 会话内容存档 RSA 私钥(PEM 格式)
ShareSecret string? 共享 Token 密钥(ChaCha20-Poly1305,详见跨服务共享 Token
TokenShareUrl string? 远端共享 Token 地址;设置后从此地址拉取加密 Token,而非直接请求企业微信 API
SecretShareUrl string? 统一共享密钥远端地址;详见统一共享密钥
OnTokenChanged Func<string, CancellationToken, Task>? Token 刷新成功后的变更通知回调,参数为新的明文 access_token
JsApiTicketShareSecret string? 企业级 jsapi_ticket 共享密钥(ChaCha20-Poly1305)
JsApiTicketShareUrl string? 企业级 jsapi_ticket 共享远端地址
OnJsApiTicketChanged Func<string, CancellationToken, Task>? 企业级 jsapi_ticket 刷新成功后的变更通知回调
AgentTicketShareSecret string? 应用级 jsapi_ticket 共享密钥(ChaCha20-Poly1305)
AgentTicketShareUrl string? 应用级 jsapi_ticket 共享远端地址
OnAgentTicketChanged Func<string, CancellationToken, Task>? 应用级 jsapi_ticket 刷新成功后的变更通知回调
RetryOptions TencentRetryOptions new() 瞬态故障重试配置(网络抖动、超时、5xx),详见瞬态故障自动重试

🔐 消息回调(企业微信示例)

在 ASP.NET Core 中接入企业微信消息回调:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWecomService(opt =>
{
    opt.CorpId                 = "your_corpid";
    opt.CorpSecret             = "your_corpsecret";
    opt.AgentId                = 1000001;
    opt.CallbackToken          = "your_callback_token";
    opt.CallbackEncodingAesKey = "your_43char_encoding_aes_key";
});

var app = builder.Build();

// GET — 验证回调 URL
app.MapGet("/wecom/callback", (
    string msg_signature, string timestamp, string nonce, string echostr,
    ICallbackService callback) =>
{
    var plain = callback.VerifyUrl(msg_signature, timestamp, nonce, echostr);
    return Results.Content(plain);
});

// POST — 接收消息与事件
app.MapPost("/wecom/callback", async (
    string msg_signature, string timestamp, string nonce,
    HttpRequest request, ICallbackService callback) =>
{
    using var reader = new StreamReader(request.Body);
    var body = await reader.ReadToEndAsync();

    var msg = callback.DecryptAndParse(msg_signature, timestamp, nonce, body);
    switch (msg)
    {
        case CallbackTextMessage text:
            var reply = CallbackReplyBuilder.BuildText(
                text.FromUserName, text.ToUserName, "收到你的消息了!");
            return Results.Content(callback.EncryptReply(reply), "application/xml");

        case CallbackClickEvent click:
            // 处理菜单点击事件
            break;

        case CallbackTemplateCardEvent cardEvent:
            // 处理模版卡片事件
            break;

        // ─── 通讯录变更回调 ─────────────────────────────────
        case CallbackUpdateUserEvent updateUser: // ⚠️ 必须在 CreateUserEvent 之前
            Console.WriteLine($"更新成员: {updateUser.UserID}, 新ID: {updateUser.NewUserID}");
            break;

        case CallbackCreateUserEvent createUser:
            Console.WriteLine($"新建成员: {createUser.UserID}, 姓名: {createUser.Name}, 部门: {createUser.Department}");
            break;

        case CallbackDeleteUserEvent deleteUser:
            Console.WriteLine($"删除成员: {deleteUser.UserID}");
            break;

        case CallbackUpdatePartyEvent updateParty: // ⚠️ 必须在 CreatePartyEvent 之前
            Console.WriteLine($"更新部门: Id={updateParty.Id}, Name={updateParty.Name}");
            break;

        case CallbackCreatePartyEvent createParty:
            Console.WriteLine($"新建部门: Id={createParty.Id}, Name={createParty.Name}, ParentId={createParty.ParentId}");
            break;

        case CallbackDeletePartyEvent deleteParty:
            Console.WriteLine($"删除部门: Id={deleteParty.Id}");
            break;

        case CallbackUpdateTagEvent updateTag:
            Console.WriteLine($"标签变更: TagId={updateTag.TagId}, 新增成员: {updateTag.AddUserItems}, 删除成员: {updateTag.DelUserItems}");
            break;

        // ─── 异步任务完成回调 ───────────────────────────────
        case CallbackBatchJobEvent batchJob:
            Console.WriteLine($"异步任务完成: JobId={batchJob.JobId}, Type={batchJob.JobType}, ErrCode={batchJob.ErrCode}");
            break;

        // ─── 审批状态变更回调 ───────────────────────────────
        case CallbackApprovalEvent approval:
            Console.WriteLine($"审批变更: SpNo={approval.SpNo}, Status={approval.SpStatus}, 申请人={approval.ApplyerUserId}");
            break;
    }
    return Results.Content("");
});

app.Run();

⚠️ 注意CallbackUpdateUserEvent 继承自 CallbackCreateUserEventCallbackUpdatePartyEvent 继承自 CallbackCreatePartyEvent,在 switch 中应将子类放在父类之前,以确保正确匹配。

通讯录变更回调

通讯录变更回调(Event = change_contact)支持以下变更类型,SDK 会自动根据 ChangeType 解析为对应的强类型模型:

参考文档:通讯录回调通知

ChangeType 模型类 说明 关键字段
create_user CallbackCreateUserEvent 新建成员 UserID / Name / Department / Mobile / Email / Status / ExtAttr 等 15+ 字段
update_user CallbackUpdateUserEvent 更新成员 继承 CallbackCreateUserEvent 全部字段 + NewUserID(仅 UserID 变更时有值)
delete_user CallbackDeleteUserEvent 删除成员 UserID
create_party CallbackCreatePartyEvent 新建部门 Id / Name / ParentId / Order
update_party CallbackUpdatePartyEvent 更新部门 Id / Name / ParentId / Order
delete_party CallbackDeletePartyEvent 删除部门 Id
update_tag CallbackUpdateTagEvent 标签成员变更 TagId / AddUserItems / DelUserItems / AddPartyItems / DelPartyItems

所有通讯录变更事件均继承自 CallbackChangeContactEvent,可通过 ChangeType 属性获取变更类型字符串。

扩展属性(ExtAttr)

新建/更新成员事件中的 ExtAttr 字段为 CallbackExtAttrItem[],每个元素包含:

属性 说明
Name 属性名称
Type 属性类型(0=文本, 1=网页)
Value 文本属性值(Type=0 时)
WebUrl 网页链接(Type=1 时)
WebTitle 网页标题(Type=1 时)
异步任务完成回调

异步任务完成事件(Event = batch_job_result)使用 CallbackBatchJobEvent 模型:

参考文档:异步任务完成事件推送

属性 说明
JobId 异步任务 ID(最大长度 64 字符)
JobType 操作类型:sync_user / replace_user / invite_user / replace_party
ErrCode 返回码(0 表示成功)
ErrMsg 错误信息

智能机器人(SmartRobot)

智能机器人开启 API 模式后,用户与机器人交互时企业微信会向回调 URL 推送消息和事件。SDK 提供完整的回调验证、消息解密、被动回复加密、主动回复以及智能表格自动化群聊管理能力。

参考文档:智能机器人概述 / 接收消息 / 接收事件 / 被动回复

支持的消息类型
消息类型 模型类 说明
text CallbackTextMessage 文本消息
image CallbackImageMessage 图片消息
voice CallbackVoiceMessage 语音消息
video CallbackVideoMessage 视频消息
location CallbackLocationMessage 位置消息
link CallbackLinkMessage 链接消息
attachment CallbackAttachmentMessage 附件/混合消息(含操作项 CallbackAttachmentAction
支持的事件类型
事件类型 模型类 说明
enter_chat CallbackEnterChatEvent 用户进入机器人会话
subscribe CallbackSubscribeEvent 关注事件
unsubscribe CallbackUnsubscribeEvent 取消关注事件
click CallbackClickEvent 菜单点击事件
template_card_event CallbackTemplateCardEvent 模版卡片事件
被动回复构建器(CallbackReplyBuilder)
方法 说明
BuildText 文本回复
BuildImage 图片回复
BuildVoice 语音回复
BuildVideo 视频回复
BuildNews 图文回复(最多 8 条)
BuildMarkdown Markdown 回复(智能机器人专用)
BuildTemplateCard 模版卡片回复(智能机器人专用)
智能表格自动化群聊
方法 说明
GetSmartSheetChatListAsync 获取智能表格自动化创建的群聊列表
GetSmartSheetChatAsync 获取群聊会话详情
UpdateSmartSheetChatAsync 修改群聊会话
using GaoXinLibrary.TencentSDK.Wecom;
using GaoXinLibrary.TencentSDK.Wecom.Models.Callback;
using GaoXinLibrary.TencentSDK.Wecom.Models.Message;
using GaoXinLibrary.TencentSDK.Wecom.Models.SmartRobot;

// ── 回调验证(GET 请求) ──────────────────────────────────────────
var plain = client.SmartRobot.VerifyUrl(msg_signature, timestamp, nonce, echostr);
// 将 plain 写入 HTTP 响应

// ── 接收消息/事件(POST 请求) ────────────────────────────────────
var msg = client.SmartRobot.DecryptAndParse(msg_signature, timestamp, nonce, postBody);
switch (msg)
{
    case CallbackTextMessage text:
        // 构建文本回复
        var replyXml = CallbackReplyBuilder.BuildText(text.FromUserName, text.ToUserName, "收到你的消息了!");
        var encrypted = client.SmartRobot.EncryptReply(replyXml);
        // 将 encrypted 写入 HTTP 响应
        break;

    case CallbackAttachmentMessage attachment:
        // 处理附件/混合消息
        Console.WriteLine($"附件操作: {attachment.Actions?.Length} 个操作项");
        break;

    case CallbackEnterChatEvent enterChat:
        // 用户进入机器人会话,构建 Markdown 欢迎消息
        var welcomeXml = CallbackReplyBuilder.BuildMarkdown(
            enterChat.FromUserName, enterChat.ToUserName, "## 欢迎使用智能机器人!");
        var welcomeEncrypted = client.SmartRobot.EncryptReply(welcomeXml);
        break;
}

// ── 主动发送消息 ──────────────────────────────────────────────────
var response = await client.SmartRobot.SendMessageAsync(new SendMessageRequest
{
    ToUser = "zhangsan",
    MsgType = "text",
    AgentId = client.Options.AgentId,
    Text = new TextContent { Content = "主动推送消息" }
});
Console.WriteLine($"MsgId: {response.MsgId}");

// ── 智能表格自动化群聊管理 ────────────────────────────────────────
var chatList = await client.SmartRobot.GetSmartSheetChatListAsync(new GetSmartSheetChatListRequest
{
    DocId = "DOC_ID",
    SheetId = "SHEET_ID"
});

var chatDetail = await client.SmartRobot.GetSmartSheetChatAsync("CHAT_ID");

await client.SmartRobot.UpdateSmartSheetChatAsync(new UpdateSmartSheetChatRequest
{
    ChatId = "CHAT_ID",
    Name = "新群聊名称"
});
WebSocket 长连接模式(SmartRobotWs)

通过 WebSocket 长连接与企业微信保持实时通信,无需公网 IP,无需消息加解密。适用于无法暴露公网地址的部署场景。

参考文档:WebSocket 长连接接口

接口方法一览
方法 说明
ConnectAsync 建立 WebSocket 连接并完成订阅(aibot_subscribe
RespondWelcomeMsgAsync 回复欢迎语(收到 enter_chat 事件后 5 秒内调用)
RespondMsgAsync 回复消息(支持流式,收到 aibot_msg_callback 后 24 小时内调用)
RespondUpdateMsgAsync 更新模板卡片(收到 template_card_event 后 5 秒内调用)
SendMsgAsync 主动推送消息(无需回调触发,限 30 条/分钟、1000 条/小时)
UploadMediaAsync 分片上传临时素材(file / image / voice / video)
PingAsync 发送心跳 ping(内置 30 秒自动心跳)
RespondToolResultAsync 回传文档工具调用结果(API 模式)
事件回调
事件 说明
OnMsgCallback 收到用户消息时触发,参数:(reqId, WsMsgCallbackBody)
OnEventCallback 收到事件时触发,参数:(reqId, WsEventCallbackBody)
OnToolCallCallback 收到文档工具调用时触发,参数:(reqId, DocToolCallInfo[])
OnDisconnected 连接断开时触发
using GaoXinLibrary.TencentSDK.Wecom;
using GaoXinLibrary.TencentSDK.Wecom.Core;
using GaoXinLibrary.TencentSDK.Wecom.Models.SmartRobot;

// ── 创建客户端(配置 BotId / BotSecret) ──────────────────────────
var client = WecomClient.Create(new WecomOptions
{
    CorpId     = "your_corpid",
    CorpSecret = "your_corpsecret",
    AgentId    = 1000001,
    BotId      = "your_bot_id",
    BotSecret  = "your_bot_secret"
});

// ── 建立 WebSocket 长连接 ─────────────────────────────────────────
await client.SmartRobotWs!.ConnectAsync();

// ── 注册消息回调 ──────────────────────────────────────────────────
client.SmartRobotWs.OnMsgCallback += async (reqId, msg) =>
{
    Console.WriteLine($"收到消息: {msg.Content}");

    // 回复文本消息
    await client.SmartRobotWs.RespondMsgAsync(reqId, new WsRespondMsgBody
    {
        MsgType = "text",
        Text = new WsTextContent { Content = "已收到你的消息!" }
    });
};

// ── 注册事件回调 ──────────────────────────────────────────────────
client.SmartRobotWs.OnEventCallback += async (reqId, evt) =>
{
    if (evt.EventType == "enter_chat")
    {
        // 用户进入聊天,5 秒内回复欢迎语
        await client.SmartRobotWs.RespondWelcomeMsgAsync(reqId, new WsRespondWelcomeMsgBody
        {
            MsgType = "text",
            Text = new WsTextContent { Content = "欢迎使用智能机器人!" }
        });
    }
};

// ── 主动推送消息 ──────────────────────────────────────────────────
await client.SmartRobotWs.SendMsgAsync(new WsSendMsgBody
{
    ChatId = "CHAT_ID",
    MsgType = "text",
    Text = new WsTextContent { Content = "主动推送的消息" }
});

// ── 分片上传素材 ──────────────────────────────────────────────────
ReadOnlyMemory<byte> fileData = await File.ReadAllBytesAsync("report.pdf");
var mediaId = await client.SmartRobotWs.UploadMediaAsync("file", "report.pdf", fileData);
Console.WriteLine($"素材 MediaId: {mediaId}");

// ── 断开连接时自动重连 ────────────────────────────────────────────
client.SmartRobotWs.OnDisconnected += async ex =>
{
    Console.WriteLine($"连接断开: {ex?.Message}");
    await Task.Delay(3000);
    await client.SmartRobotWs.ConnectAsync();
};
文档工具调用(API 模式)

API 模式下,智能机器人可以通过文档工具与企业微信文档/智能表格进行交互。SDK 提供 DocToolNames 常量类和 OnToolCallCallback 事件简化工具调用处理。

参考文档:API 模式机器人文档使用说明

支持的文档工具
工具名称 常量 说明
create_doc DocToolNames.CreateDoc 创建文档/收集表/智能表格
edit_doc_content DocToolNames.EditDocContent 编辑文档内容
get_doc_base_info DocToolNames.GetDocBaseInfo 获取文档基本信息
smartsheet_add_records DocToolNames.SmartSheetAddRecords 添加智能表格记录
smartsheet_get_records DocToolNames.SmartSheetGetRecords 获取智能表格记录
smartsheet_update_records DocToolNames.SmartSheetUpdateRecords 更新智能表格记录
smartsheet_delete_records DocToolNames.SmartSheetDeleteRecords 删除智能表格记录
smartsheet_add_fields DocToolNames.SmartSheetAddFields 添加智能表格字段
smartsheet_get_fields DocToolNames.SmartSheetGetFields 获取智能表格字段
smartsheet_update_fields DocToolNames.SmartSheetUpdateFields 更新智能表格字段
smartsheet_delete_fields DocToolNames.SmartSheetDeleteFields 删除智能表格字段
using GaoXinLibrary.TencentSDK.Wecom.Models.SmartRobot;
using System.Text.Json;

// ── 注册文档工具调用回调 ──────────────────────────────────────────
client.SmartRobotWs!.OnToolCallCallback += async (reqId, toolCalls) =>
{
    var results = new List<DocToolResultInfo>();

    foreach (var call in toolCalls)
    {
        Console.WriteLine($"工具调用: {call.ToolName}, ID: {call.ToolCallId}");

        // 根据工具名称执行对应操作
        var content = call.ToolName switch
        {
            DocToolNames.GetDocBaseInfo => await GetDocBaseInfoAsync(call.Arguments),
            DocToolNames.SmartSheetGetRecords => await GetRecordsAsync(call.Arguments),
            DocToolNames.SmartSheetAddRecords => await AddRecordsAsync(call.Arguments),
            _ => JsonSerializer.Serialize(new { error = $"未知工具: {call.ToolName}" })
        };

        results.Add(new DocToolResultInfo
        {
            ToolCallId = call.ToolCallId,
            Content = content
        });
    }

    // 回传工具调用结果
    await client.SmartRobotWs.RespondToolResultAsync(reqId, new WsRespondToolResultBody
    {
        ToolResults = results.ToArray()
    });
};
依赖注入方式使用 WebSocket 客户端
// Program.cs — 注册时配置 BotId / BotSecret
builder.Services.AddWecomService(opt =>
{
    opt.CorpId     = "your_corpid";
    opt.CorpSecret = "your_corpsecret";
    opt.AgentId    = 1000001;
    opt.BotId      = "your_bot_id";
    opt.BotSecret  = "your_bot_secret";
});

// 注入 ISmartRobotWsClient 使用
public class BotHostedService(ISmartRobotWsClient wsClient) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        wsClient.OnMsgCallback += async (reqId, msg) =>
        {
            await wsClient.RespondMsgAsync(reqId, new WsRespondMsgBody
            {
                MsgType = "text",
                Text = new WsTextContent { Content = $"Echo: {msg.Content}" }
            });
        };

        await wsClient.ConnectAsync(ct);

        // 保持运行直到取消
        await Task.Delay(Timeout.Infinite, ct);
    }
}
实现文件清单
文件 类型 说明
CallbackEnterChatEvent.cs 新增模型 进入机器人聊天事件模型(enter_chat
CallbackAttachmentMessage.cs 新增模型 附件/混合消息模型(attachment
CallbackAttachmentAction.cs 新增模型 附件消息中的操作项模型
GetSmartSheetChatListRequest.cs 新增模型 获取智能表格群聊列表请求
GetSmartSheetChatListResponse.cs 新增模型 获取智能表格群聊列表响应
GetSmartSheetChatResponse.cs 新增模型 获取智能表格群聊详情响应
UpdateSmartSheetChatRequest.cs 新增模型 修改智能表格群聊请求
WsHeaders.cs 新增模型 WebSocket 请求头(req_id)
WsRequest.cs 新增模型 WebSocket 请求帧(cmd / headers / body)
WsResponse.cs 新增模型 WebSocket 响应帧(errcode / errmsg)
WsSubscribeBody.cs 新增模型 订阅请求体(bot_id / secret)
WsMsgCallbackBody.cs 新增/修改模型 消息回调体(含 ToolCalls 文档工具调用)
WsEventCallbackBody.cs 新增模型 事件回调体
WsTextContent.cs 新增模型 文本消息内容
WsRespondWelcomeMsgBody.cs 新增模型 回复欢迎语消息体
WsRespondMsgBody.cs 新增模型 回复消息体
WsRespondUpdateMsgBody.cs 新增模型 更新模板卡片消息体
WsSendMsgBody.cs 新增模型 主动推送消息体
WsUploadMediaInitBody.cs 新增模型 分片上传初始化请求
WsUploadMediaInitResponseBody.cs 新增模型 分片上传初始化响应
WsUploadMediaChunkBody.cs 新增模型 分片上传块请求
WsUploadMediaFinishBody.cs 新增模型 分片上传完成请求
WsUploadMediaFinishResponseBody.cs 新增模型 分片上传完成响应
WsCommands.cs 新增/修改模型 WebSocket 指令常量(含 RespondToolResult
DocToolNames.cs 新增模型 文档工具名称常量(12 种工具)
DocToolCallInfo.cs 新增模型 文档工具调用信息(tool_call_id / tool_name / arguments)
DocToolResultInfo.cs 新增模型 文档工具调用结果(tool_call_id / content)
WsRespondToolResultBody.cs 新增模型 回传工具调用结果消息体
ISmartRobotWsClient.cs 新增接口 WebSocket 客户端接口
SmartRobotWsClient.cs 新增实现 WebSocket 客户端完整实现
CallbackMessageBase.cs 修改 新增 attachment 消息类型解析和 enter_chat 事件解析
CallbackReplyBuilder.cs 修改 新增 BuildMarkdownBuildTemplateCard 被动回复构建方法
ISmartRobotService.cs 修改 接口升级:强类型 SendMessageRequest/SendMessageResponse;新增智能表格群聊 API
SmartRobotService.cs 修改 实现所有新接口方法
WecomOptions.cs 修改 新增 BotId / BotSecret / BotWsUrl 配置属性
WecomClient.cs 修改 新增 SmartRobotWs 属性(条件实例化)
WecomServiceCollectionExtensions.cs 修改 注册 ISmartRobotWsClient DI 服务

审批申请(ApplyEventBuilder)

通过链式构建器快速提交审批申请,无需手动拼装嵌套数据结构。支持官方文档全部 16 种控件类型

控件 构建器方法 说明
Text AddText 单行文本
Textarea AddTextarea 多行文本
Number AddNumber 数字
Money AddMoney 金额
Date AddDate 日期
DateRange AddDateRange 日期范围(可选时长)
Selector AddSelector 选择器(单选/多选)
Contact - 成员 AddMembers 联系人-成员
Contact - 部门 AddDepartments 联系人-部门
File AddFiles 附件
Table AddTable 明细表格
Location AddLocation 位置(可选打卡时间)
Vacation AddVacation 请假
Attendance AddAttendance 假勤(出差/外出/加班)
RelatedApproval AddRelatedApproval 关联审批单
Formula 公式(后台自动计算,无需提交)
// 使用构建器提交审批申请
var spNo = await client.Approval.ApplyEventAsync(b => b
    .SetCreator("zhangsan")
    .SetTemplate("3TkZjxugodbqpEMk5bRCFTHEHidgwegDnhVj4")
    .UseTemplateApprover()
    .AddText("Text-1", "出差事由:拜访客户")
    .AddNumber("Number-1", "2")
    .AddMoney("Money-1", "5000")
    .AddDate("Date-1", "day", DateTimeOffset.Now)
    .AddDateRange("DateRange-1", "day",
        DateTimeOffset.Now,
        DateTimeOffset.Now.AddDays(2),
        duration: 172800)
    .AddSelector("Selector-1", "single", "option-1")
    .AddMembers("Contact-1", "zhangsan", "lisi")
    .AddDepartments("Contact-2", "1", "2")
    .AddLocation("Location-1", "40.0", "116.0", "北京市", "朝阳区")
    .AddVacation("Vacation-1", "single", "1",
        "day", DateTimeOffset.Now, DateTimeOffset.Now.AddDays(3))
    .AddAttendance("Attendance-1", 3,
        "day", DateTimeOffset.Now, DateTimeOffset.Now.AddDays(2))
    .AddRelatedApproval("RelatedApproval-1", "202503140001")
    .AddSummary("出差申请", "张三", "2天"));

Console.WriteLine($"审批单号: {spNo}");

// 自动分页获取所有审批单号
var allSpNos = await client.Approval.GetAllApprovalNoAsync(
    startTime: DateTimeOffset.Now.AddDays(-30).ToUnixTimeSeconds(),
    endTime: DateTimeOffset.Now.ToUnixTimeSeconds());

Console.WriteLine($"共 {allSpNos.Count} 个审批单");

📂 项目结构

GaoXinLibrary.TencentSDK/
├── Core/                                  # 核心基础设施(共享基类 + 平台子类)
│   ├── TencentConstants.cs                #   统一常量定义(HttpClient 名称、OAuth URL)
│   ├── TencentBaseResponse.cs             #   响应基类(ErrCode / ErrMsg)
│   ├── TencentException.cs                #   异常基类
│   ├── TencentAccessTokenProvider.cs      #   access_token 管理基类(缓存 / 刷新 / 手动设置 / 共享 Token)
│   ├── TencentTokenCrypto.cs              #   共享 Token 加解密工具(ChaCha20-Poly1305)
│   ├── SharedSecretPayload.cs             #   统一共享密钥载荷(access_token + tickets + 凭证信息)
│   ├── TencentHttpClient.cs               #   HTTP 客户端基类(Get / Post / 反序列化 / 瞬态重试)
│   ├── TencentRetryOptions.cs             #   瞬态故障重试配置(指数退避)
│   ├── TencentCryptoHelper.cs             #   消息加解密基类(AES-256-CBC / SHA1 签名)
│   ├── WechatOptions.cs                   #   微信配置基类
│   ├── WechatMiniProgramOptions.cs        #   小程序配置
│   ├── WechatOfficialOptions.cs           #   公众号配置
│   ├── WechatOpenOptions.cs               #   开放平台配置
│   ├── QQConnectOptions.cs                #   QQ 互联配置
│   ├── WechatHttpClient.cs                #   微信 HTTP 客户端
│   ├── WechatAccessTokenProvider.cs       #   微信 access_token 管理
│   ├── WechatBaseResponse.cs              #   微信响应类
│   ├── WechatCryptoHelper.cs              #   微信消息加解密
│   ├── JsApiTicketProvider.cs             #   公众号 JS-SDK Ticket 缓存与共享
│   ├── WecomOptions.cs                    #   企业微信配置类
│   ├── WecomHttpClient.cs                 #   企业微信 HTTP 客户端
│   ├── WecomAccessTokenProvider.cs        #   企业微信 access_token 管理
│   ├── WecomBaseResponse.cs               #   企业微信响应类
│   ├── WecomCryptoHelper.cs               #   企业微信消息加解密
│   ├── WecomTicketProvider.cs             #   企业微信 JS-SDK Ticket 缓存与共享
│   ├── HexHelper.cs                       #   十六进制工具
│   └── Finance/                           #   会话内容存档原生 SDK
│       ├── FinanceSdk.cs                  #     Finance SDK 封装
│       └── FinanceNativeMethods.cs        #     P/Invoke 声明
├── Models/                                # 数据模型(按产品 × 模块划分,每个类独立文件)
│   ├── MiniProgram/                       #   小程序(104 个模型类)
│   ├── OfficialAccount/                   #   公众号(187 个模型类,含回调消息)
│   ├── OpenPlatform/                      #   开放平台
│   ├── QQConnect/                         #   QQ 互联
│   └── Wecom/                             #   企业微信
│       ├── User/                          #     成员
│       ├── Department/                    #     部门
│       ├── Tag/                           #     标签
│       ├── Message/                       #     消息(含模版卡片)
│       ├── Webhook/                       #     群机器人
│       ├── Agent/                         #     应用
│       ├── Menu/                          #     菜单
│       ├── Media/                         #     素材
│       ├── GroupChat/                      #     群聊
│       ├── OAuth/                         #     OAuth
│       ├── JsSdk/                         #     JS-SDK
│       ├── Callback/                      #     回调消息
│       ├── SmartRobot/                    #     智能机器人
│       ├── Kf/                            #     客服
│       ├── Checkin/                       #     打卡
│       ├── Approval/                      #     审批
│       ├── MsgAudit/                      #     会话存档
│       ├── CorpGroup/                     #     企业互联
│       ├── LinkedCorp/                    #     互联企业
│       ├── Export/                        #     异步导出
│       ├── AsyncImport/                   #     异步导入
│       ├── SecondVerify/                  #     二次验证
│       ├── Security/                      #     安全管理
│       ├── AdvancedAccount/               #     高级功能账号
│       ├── OperationLog/                  #     操作日志
│       ├── AccountId/                     #     账号 ID 管理
│       ├── IpRange/                       #     IP 段查询
│       ├── ExternalContact/               #     客户联系
│       ├── CorpPay/                       #     企业支付
│       ├── Email/                         #     邮件
│       ├── Document/                      #     文档
│       ├── Calendar/                      #     日程
│       ├── Meeting/                       #     会议
│       ├── Wedrive/                       #     微盘
│       ├── Living/                        #     直播
│       ├── Dial/                          #     公费电话
│       ├── Report/                        #     汇报
│       ├── Hr/                            #     人事助手
│       ├── MeetingRoom/                   #     会议室
│       ├── Invoice/                       #     电子发票
│       ├── SmartSheet/                    #     智能表格
│       └── CollectForm/                   #     收集表
├── Services/                              # 服务层(按产品 × 模块划分,每个接口 / 实现独立文件)
│   ├── MiniProgram/                       #   小程序(13 对 I*Service / *Service)
│   ├── OfficialAccount/                   #   公众号(17 对 I*Service / *Service)
│   ├── OpenPlatform/                      #   开放平台
│   ├── QQConnect/                         #   QQ 互联
│   └── Wecom/                             #   企业微信
│       ├── User/                          #     成员管理
│       ├── Department/                    #     部门管理
│       ├── Tag/                           #     标签管理
│       ├── Message/                       #     应用消息
│       ├── Webhook/                       #     群机器人
│       ├── Agent/                         #     应用管理
│       ├── Menu/                          #     菜单接口
│       ├── Media/                         #     素材管理
│       ├── GroupChat/                      #     群聊会话
│       ├── OAuth/                         #     OAuth
│       ├── JsSdk/                         #     JS-SDK
│       ├── Callback/                      #     消息回调
│       ├── SmartRobot/                    #     智能机器人
│       ├── Kf/                            #     微信客服
│       ├── Checkin/                       #     打卡
│       ├── Approval/                      #     审批
│       ├── MsgAudit/                      #     会话存档
│       ├── CorpGroup/                     #     企业互联
│       ├── LinkedCorp/                    #     互联企业
│       ├── Export/                        #     异步导出
│       ├── AsyncImport/                   #     异步导入
│       ├── SecondVerify/                  #     二次验证
│       ├── Security/                      #     安全管理
│       ├── AdvancedAccount/               #     高级功能账号
│       ├── OperationLog/                  #     操作日志
│       ├── AccountId/                     #     账号 ID 管理
│       ├── IpRange/                       #     IP 段查询
│       ├── ExternalContact/               #     客户联系
│       ├── CorpPay/                       #     企业支付
│       ├── Email/                         #     邮件
│       ├── Document/                      #     文档
│       ├── Calendar/                      #     日程
│       ├── Meeting/                       #     会议
│       ├── Wedrive/                       #     微盘
│       ├── Living/                        #     直播
│       ├── Dial/                          #     公费电话
│       ├── Report/                        #     汇报
│       ├── Hr/                            #     人事助手
│       ├── MeetingRoom/                   #     会议室
│       ├── Invoice/                       #     电子发票
│       ├── SmartSheet/                    #     智能表格
│       └── CollectForm/                   #     收集表
├── Extensions/                            # DI 扩展
│   ├── WechatServiceCollectionExtensions.cs
│   └── WecomServiceCollectionExtensions.cs
├── WechatMiniProgramClient.cs             # 小程序主客户端
├── WechatOfficialClient.cs                # 公众号主客户端
├── WechatOpenClient.cs                    # 开放平台主客户端
├── QQConnectClient.cs                     # QQ 互联主客户端
├── WecomClient.cs                         # 企业微信主客户端
└── GaoXinLibrary.TencentSDK.csproj        # 项目文件(多目标 net8.0;net9.0;net10.0)

🔧 进阶用法

跨服务共享 Token

多台服务器部署时,只需一台主服务器持有真实的 AppSecret 向腾讯 API 获取 token,其他备服务器通过主服务器的接口获取加密后的 token,无需存储 AppSecret

加密算法使用 ChaCha20-Poly1305,密钥由 ShareSecret 经 SHA-256 派生,格式为 Base64( nonce[12] + ciphertext[N] + tag[16] )

主服务器(持有 AppSecret,对外暴露加密 Token 接口)
// Program.cs
builder.Services.AddWecomService(opt =>
{
    opt.CorpId     = "your_corpid";
    opt.CorpSecret = "your_corpsecret"; // 仅主服务器配置
    opt.AgentId    = 1000001;
    opt.ShareSecret = "any-strong-shared-secret"; // 与备服务器约定

    // 可选:Token 刷新时推送到 Redis / 消息队列等
    opt.OnTokenChanged = async (newToken, ct) =>
    {
        await redis.StringSetAsync("wecom:token", newToken);
    };
});

// Controller — 对外暴露加密 Token 接口(建议加鉴权)
[HttpGet("/internal/wecom/token")]
public async Task<IActionResult> GetSharedToken([FromServices] WecomClient client)
{
    var result = await client.GetSharedAccessTokenAsync();
    // result.Token     — ChaCha20-Poly1305 加密后的 token(Base64)
    // result.ExpiresIn — 主服务器侧 token 的剩余有效秒数
    return Ok(new { token = result.Token, expires_in = result.ExpiresIn });
}
备服务器(无 AppSecret,从主服务器拉取加密 Token)
// Program.cs
builder.Services.AddWecomService(opt =>
{
    opt.CorpId      = "your_corpid";
    opt.AgentId     = 1000001;
    opt.ShareSecret  = "any-strong-shared-secret"; // 与主服务器一致
    opt.TokenShareUrl = "https://main-server/internal/wecom/token"; // 主服务器接口
    // 不需要配置 CorpSecret
});

// 注入后正常使用,SDK 自动在 token 过期时请求主服务器接口并解密
public class MyService(WecomClient client)
{
    public async Task NotifyAsync()
        => await client.Message.SendTextAsync("Hello!", toUser: "@all");
}
也可直接使用加解密工具类
using GaoXinLibrary.TencentSDK.Core;

// 加密(主服务器侧)
string encrypted = TencentTokenCrypto.Encrypt(plainToken, "shared-secret");

// 解密(备服务器侧)
string plainToken = TencentTokenCrypto.Decrypt(encrypted, "shared-secret");

备服务器响应的 expires_in 会被 SDK 原样用于设置本地缓存过期时间,确保备服务器的缓存节奏与主服务器保持一致,避免过早或过晚失效。

跨服务共享 jsapi_ticket

jsapi_ticket 同样有调用频率限制(企业级每小时 400 次,应用级每小时 100 次),SDK 内置了与 access_token 相同的缓存与共享机制。

公众号 jsapi_ticket 共享
// 主服务器
builder.Services.AddWechatOfficialService(opt =>
{
    opt.AppId     = "official_appid";
    opt.AppSecret = "official_secret"; // 仅主服务器配置
    opt.ShareSecret       = "any-strong-shared-secret"; // access_token 共享密钥,与备服务器约定
    opt.TicketShareSecret = "ticket-shared-secret";      // jsapi_ticket 共享密钥,与备服务器约定

    // 可选:Token / Ticket 刷新时推送到 Redis 等
    opt.OnTokenChanged = async (newToken, ct) =>
    {
        await redis.StringSetAsync("official:token", newToken);
    };
    opt.OnTicketChanged = async (newTicket, ct) =>
    {
        await redis.StringSetAsync("official:ticket", newTicket);
    };
});

// Controller — 对外暴露加密 Token / Ticket 接口(建议加鉴权)
[HttpGet("/internal/official/token")]
public async Task<IActionResult> GetSharedToken([FromServices] WechatOfficialClient client)
{
    var result = await client.GetSharedAccessTokenAsync();
    return Ok(new { token = result.Token, expires_in = result.ExpiresIn });
}

[HttpGet("/internal/official/ticket")]
public async Task<IActionResult> GetSharedTicket([FromServices] WechatOfficialClient client)
{
    var result = await client.GetSharedTicketAsync();
    return Ok(new { token = result.Token, expires_in = result.ExpiresIn });
}

// 备服务器(无 AppSecret,access_token 和 jsapi_ticket 均从主服务器获取)
builder.Services.AddWechatOfficialService(opt =>
{
    opt.AppId     = "official_appid";
    // 不需要配置 AppSecret
    opt.ShareSecret   = "any-strong-shared-secret";                       // access_token 共享密钥
    opt.TokenShareUrl = "https://main-server/internal/official/token";    // access_token 共享地址
    opt.TicketShareSecret = "ticket-shared-secret";                       // jsapi_ticket 共享密钥
    opt.TicketShareUrl    = "https://main-server/internal/official/ticket"; // jsapi_ticket 共享地址
});
企业微信 jsapi_ticket 共享

企业微信有 两种 jsapi_ticket:

  • 企业级 jsapi_ticket(用于 wx.config
  • 应用级 jsapi_ticket(用于 wx.agentConfig

两者均支持独立的缓存、共享、手动设置和刷新。

// 主服务器
builder.Services.AddWecomService(opt =>
{
    opt.CorpId     = "your_corpid";
    opt.CorpSecret = "your_corpsecret"; // 仅主服务器配置
    opt.AgentId    = 1000001;
    opt.ShareSecret = "any-strong-shared-secret"; // access_token 共享密钥,与备服务器约定

    // 企业级 jsapi_ticket 共享
    opt.JsApiTicketShareSecret = "jsapi-ticket-secret";
    opt.OnJsApiTicketChanged = async (ticket, ct) =>
    {
        await redis.StringSetAsync("wecom:jsapi_ticket", ticket);
    };

    // 应用级 jsapi_ticket 共享
    opt.AgentTicketShareSecret = "agent-ticket-secret";
    opt.OnAgentTicketChanged = async (ticket, ct) =>
    {
        await redis.StringSetAsync("wecom:agent_ticket", ticket);
    };

    // 可选:Token 刷新时推送到 Redis 等
    opt.OnTokenChanged = async (newToken, ct) =>
    {
        await redis.StringSetAsync("wecom:token", newToken);
    };
});

// Controller — 对外暴露加密 Token / Ticket 接口(建议加鉴权)
[HttpGet("/internal/wecom/token")]
public async Task<IActionResult> GetSharedToken([FromServices] WecomClient client)
{
    var result = await client.GetSharedAccessTokenAsync();
    return Ok(new { token = result.Token, expires_in = result.ExpiresIn });
}

[HttpGet("/internal/wecom/jsapi-ticket")]
public async Task<IActionResult> GetSharedJsApiTicket([FromServices] WecomClient client)
{
    var result = await client.GetSharedJsApiTicketAsync();
    return Ok(new { token = result.Token, expires_in = result.ExpiresIn });
}

[HttpGet("/internal/wecom/agent-ticket")]
public async Task<IActionResult> GetSharedAgentTicket([FromServices] WecomClient client)
{
    var result = await client.GetSharedAgentTicketAsync();
    return Ok(new { token = result.Token, expires_in = result.ExpiresIn });
}

// 备服务器(无 CorpSecret,access_token 和 jsapi_ticket 均从主服务器获取)
builder.Services.AddWecomService(opt =>
{
    opt.CorpId  = "your_corpid";
    opt.AgentId = 1000001;
    // 不需要配置 CorpSecret
    opt.ShareSecret   = "any-strong-shared-secret";                            // access_token 共享密钥
    opt.TokenShareUrl = "https://main-server/internal/wecom/token";            // access_token 共享地址

    // 企业级 jsapi_ticket 从主服务器获取
    opt.JsApiTicketShareSecret = "jsapi-ticket-secret";
    opt.JsApiTicketShareUrl    = "https://main-server/internal/wecom/jsapi-ticket";

    // 应用级 jsapi_ticket 从主服务器获取
    opt.AgentTicketShareSecret = "agent-ticket-secret";
    opt.AgentTicketShareUrl    = "https://main-server/internal/wecom/agent-ticket";
});

统一共享密钥(Unified SharedSecret)

🆕 推荐方案 — 相比逐个共享 Token / Ticket 接口,统一共享密钥仅需一个接口即可同步所有敏感信息。

多台服务器部署时,备服务器无需配置 AppSecret / CorpSecret,只需一个 SecretShareUrl 即可从主服务器拉取加密的完整密钥载荷,自动获得 access_token、jsapi_ticket、AppId / CorpId 等所有敏感信息。

载荷格式:{"data":"BASE64加密数据"},密文解密后为 SharedSecretPayload JSON,包含:

字段 说明 微信 企业微信
access_token 访问令牌
token_expires_in Token 剩余有效秒数
jsapi_ticket JS-SDK Ticket ✅(企业级)
ticket_expires_in Ticket 剩余有效秒数
app_id 应用 ID
app_secret 应用密钥
corp_id 企业 ID
corp_secret 应用凭证密钥
agent_id 应用 AgentId
agent_ticket 应用级 jsapi_ticket
agent_ticket_expires_in 应用级 Ticket 剩余秒数
微信公众号 — 统一共享密钥
// ─── 主服务器(持有 AppSecret) ──────────────────────────────────────
builder.Services.AddWechatOfficialService(opt =>
{
    opt.AppId     = "official_appid";
    opt.AppSecret = "official_secret";
    opt.ShareSecret = "any-strong-shared-secret"; // 与备服务器约定
});

// Controller — 对外暴露统一共享密钥接口(建议加鉴权)
[HttpGet("/internal/official/secret")]
public async Task<IActionResult> GetSharedSecret([FromServices] WechatOfficialClient client)
{
    var result = await client.GetSharedSecretAsync();
    // result.Data — 加密后的完整载荷(含 Token、Ticket、AppId、AppSecret)
    return Ok(new { data = result.Data });
}

// ─── 备服务器(无 AppId/AppSecret) ──────────────────────────────────
builder.Services.AddWechatOfficialService(opt =>
{
    // 不需要配置 AppId、AppSecret
    opt.ShareSecret   = "any-strong-shared-secret";                          // 与主服务器一致
    opt.SecretShareUrl = "https://main-server/internal/official/secret";     // 主服务器统一密钥接口
});
// SDK 自动从主服务器获取并解密,AppId/AppSecret/Token/Ticket 全部自动分发
企业微信 — 统一共享密钥
// ─── 主服务器(持有 CorpSecret) ──────────────────────────────────────
builder.Services.AddWecomService(opt =>
{
    opt.CorpId     = "your_corpid";
    opt.CorpSecret = "your_corpsecret";
    opt.AgentId    = 1000001;
    opt.ShareSecret = "any-strong-shared-secret"; // 与备服务器约定
});

// Controller — 对外暴露统一共享密钥接口(建议加鉴权)
[HttpGet("/internal/wecom/secret")]
public async Task<IActionResult> GetSharedSecret([FromServices] WecomClient client)
{
    var result = await client.GetSharedSecretAsync();
    // result.Data — 加密后的完整载荷(含 Token、企业级 Ticket、应用级 Ticket、CorpId、CorpSecret、AgentId)
    return Ok(new { data = result.Data });
}

// ─── 备服务器(无 CorpId/CorpSecret) ──────────────────────────────────
builder.Services.AddWecomService(opt =>
{
    // 不需要配置 CorpId、CorpSecret、AgentId
    opt.ShareSecret   = "any-strong-shared-secret";                       // 与主服务器一致
    opt.SecretShareUrl = "https://main-server/internal/wecom/secret";     // 主服务器统一密钥接口
});
// SDK 自动从主服务器获取并解密:
// - access_token 自动缓存
// - 企业级/应用级 jsapi_ticket 自动分发给 TicketProvider
// - CorpId / CorpSecret / AgentId 自动回写到 Options,OAuth / JsSdk 等服务动态读取

💡 统一共享密钥 vs 逐项共享:统一共享密钥(SecretShareUrl)将所有敏感信息打包在一个请求中返回,备服务器只需调用一个接口;而逐项共享(TokenShareUrl + TicketShareUrl + AgentTicketShareUrl)需要分别配置和调用多个接口。当 SecretShareUrlTokenShareUrl 同时设置时,SecretShareUrl 优先

手动管理 jsapi_ticket
// ── 公众号 ──
var ticket = await officialClient.GetTicketAsync();       // 自动缓存
await officialClient.RefreshTicketAsync();                 // 强制刷新
officialClient.InvalidateTicketCache();                    // 使缓存失效
officialClient.SetTicket("external_ticket");               // 手动设置

// ── 企业微信(企业级) ──
var jsTicket = await wecomClient.GetJsApiTicketAsync();    // 自动缓存
await wecomClient.RefreshJsApiTicketAsync();               // 强制刷新
wecomClient.InvalidateJsApiTicketCache();                  // 使缓存失效
wecomClient.SetJsApiTicket("external_ticket");             // 手动设置

// ── 企业微信(应用级) ──
var agentTicket = await wecomClient.GetAgentTicketAsync(); // 自动缓存
await wecomClient.RefreshAgentTicketAsync();               // 强制刷新
wecomClient.InvalidateAgentTicketCache();                  // 使缓存失效
wecomClient.SetAgentTicket("external_ticket");             // 手动设置

🔄 瞬态故障自动重试

SDK 内置了瞬态故障自动重试机制,当遇到网络抖动、连接超时、服务端 5xx 等临时性故障时,会按指数退避策略自动重试。此机制与 Token 失效重试独立,两者可叠加工作。

可重试的故障类型:

  • 网络层错误(连接失败、DNS 解析失败等 HttpRequestException
  • HTTP 请求超时(TaskCanceledException,非用户主动取消)
  • 服务端错误(HTTP 5xx 状态码)

配置参数 — TencentRetryOptions

属性 类型 默认值 说明
MaxRetries int 2 最大重试次数(不含首次请求),设为 0 则不重试
InitialDelay TimeSpan 500ms 首次重试前的等待时间,后续按指数退避递增
MaxDelay TimeSpan 5s 单次重试等待时间上限
// 使用默认重试配置(2 次重试,500ms 起始延迟,指数退避)
var client = WecomClient.Create(new WecomOptions
{
    CorpId     = "your_corpid",
    CorpSecret = "your_corpsecret",
    AgentId    = 1000001
    // RetryOptions 默认已启用,无需额外配置
});

// 自定义重试策略
var client2 = WecomClient.Create(new WecomOptions
{
    CorpId     = "your_corpid",
    CorpSecret = "your_corpsecret",
    AgentId    = 1000001,
    RetryOptions = new TencentRetryOptions
    {
        MaxRetries   = 3,                              // 最多重试 3 次
        InitialDelay = TimeSpan.FromMilliseconds(200),  // 首次重试等待 200ms
        MaxDelay     = TimeSpan.FromSeconds(10)          // 单次最多等待 10s
    }
});

// 禁用重试
var client3 = WecomClient.Create(new WecomOptions
{
    CorpId     = "your_corpid",
    CorpSecret = "your_corpsecret",
    AgentId    = 1000001,
    RetryOptions = new TencentRetryOptions { MaxRetries = 0 }
});

💡 设计说明:瞬态重试工作在 Token 重试的内层,即每次使用某个 Token 发起请求时,先尝试瞬态重试;若所有重试均失败且错误为 Token 失效,再触发 Token 刷新。这避免了网络问题被误判为 Token 失效。


自定义 HttpClient

传入自定义的 HttpClient 实例(例如添加代理、自定义 Handler):

var handler = new HttpClientHandler
{
    Proxy = new WebProxy("http://proxy.example.com:8080"),
    UseProxy = true
};
var httpClient = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(60) };

var client = WecomClient.Create(new WecomOptions
{
    CorpId     = "your_corpid",
    CorpSecret = "your_corpsecret",
    AgentId    = 1000001
}, httpClient);

手动管理 access_token

// 获取当前有效的 access_token(自动缓存,未过期时直接返回)
var token = await client.GetAccessTokenAsync();

// 强制刷新并获取新的 access_token(异步,遇到 token 失效错误时推荐使用)
var newToken = await client.RefreshAccessTokenAsync();

// 仅使缓存失效(下次调用 GetAccessTokenAsync 时重新获取)
client.InvalidateAccessTokenCache();

// 手动设置 access_token(适用于外部统一管理 Token 的场景)
client.SetAccessToken("your_external_token");

// 手动设置 access_token 并指定有效期
client.SetAccessToken("your_external_token", TimeSpan.FromSeconds(3600));

异常处理

SDK 在 API 调用失败时会抛出 TencentException,包含错误码和错误信息:

using GaoXinLibrary.TencentSDK.Core;

try
{
    await client.Message.SendTextAsync("Hello!", toUser: "@all");
}
catch (TencentException ex)
{
    Console.WriteLine($"API 错误 [{ex.ErrCode}]: {ex.Message}");
    // ex.ErrCode — 平台官方错误码
    // ex.Message — 错误描述
}

📋 API 参考

所有公开类型均附带完整的 XML 文档注释。在 Visual Studio / VS Code / Rider 中,悬停即可查看方法签名、参数说明和使用示例。

构建时自动生成 XML 文档文件(GenerateDocumentationFile = true),也可集成 DocFX 等工具生成在线文档。


许可证

MIT

Product Compatible and additional computed target framework versions.
.NET 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 is compatible.  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.2.0 106 5/27/2026
1.1.1-beta5 101 5/27/2026
1.1.1-beta4 94 5/26/2026
1.1.1-beta3 86 5/26/2026
1.1.1-beta2 90 5/5/2026
1.1.1-beta1 84 5/5/2026
1.1.0 109 4/15/2026
1.1.0-beta5 103 4/15/2026
1.1.0-beta4 108 4/15/2026
1.1.0-beta3 99 4/14/2026
1.1.0-beta2 99 4/10/2026
1.1.0-beta 101 4/10/2026
1.0.20 123 3/16/2026
1.0.19 115 3/16/2026
1.0.18 102 3/14/2026
1.0.17 105 3/13/2026
1.0.16 104 3/13/2026
1.0.15 106 3/13/2026
1.0.14 111 3/13/2026
1.0.13 108 3/13/2026
Loading failed