WeComHelper(WeComHelper)
WeComHelper 提供获取企业微信(WeCom / 企微)AccessToken 的能力,由平台统一获取并维护 token 缓存,供插件脚本直接调用企业微信开放 API 使用。
概述
企业微信的大部分开放能力(发送应用消息、查询通讯录、管理审批等)都需要携带 access_token 调用企业微信 API。WeComHelper 解决的核心问题是 token 的统一维护:
- 平台统一缓存:AccessToken 由服务端代理统一向企业微信申请并缓存(提前 5 分钟过期留出缓冲),多个调用方共享同一份缓存,避免每个插件各自频繁请求企业微信 token(企业微信对 token 获取有频率限制,重复获取会使旧 token 失效)
- 配置统一校验:获取 token 前会校验当前租户是否已配置企业微信所需的租户设置项,配置缺失时给出明确错误提示
常见别名:企业微信 token / 企微 token / WeCom access token / 企业微信凭证。
与相邻能力的边界:
- OpenApiHelper — 调用平台自身的开放 API,与企业微信无关
HttpClientFactory— 通用 HTTP 调用能力,使用WeComHelper拿到 token 后调用企业微信 API 时使用它
API 方法
GetWeComInternalTokenAsync — 获取企业微信 AccessToken
获取平台维护缓存的企业微信 AccessToken,token 类型决定了使用哪个企业微信应用的 secret。
Task<string> GetWeComInternalTokenAsync(WeComTokenTypeEnum tokenType);
参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
| tokenType | WeComTokenTypeEnum | token 类型,见下方取值 |
WeComTokenTypeEnum 取值
| 界面/语义名称 | 枚举值 | 对应企业微信 secret | 所需租户设置 |
|---|---|---|---|
| Auth(应用消息/登录) | 1 | 企业自建应用 secret(AuthSecret) | WeComCorpAppId、WeComCorpAgentId、WeComAuthSecret |
| Contact(通讯录) | 2 | 通讯录 secret(ContactSecret) | WeComCorpAppId、WeComContactSecret |
枚举数值与服务端 SecretTypeEnum(Chameleon.Model.ValueObjects.WeCom)保持对齐。
GetWeComCorpAppId — 获取企业微信企业 Id(corpid)
读取当前租户设置中的企业 AppId(设置项 WeComCorpAppId),未配置时返回空字符串。
string GetWeComCorpAppId();
GetWeComCorpAgentId — 获取企业微信应用 AgentId(agentid)
读取当前租户设置中的应用 AgentId(设置项 WeComCorpAgentId),发送应用消息时作为 agentid 参数使用,未配置时返回空字符串。
string GetWeComCorpAgentId();
示例:
// 获取企业自建应用的 AccessToken(用于发送应用消息等)
var token = await sdk.WeComHelper.GetWeComInternalTokenAsync(WeComTokenTypeEnum.Auth);
// 获取通讯录应用 的 AccessToken(用于读写企业微信通讯录)
var token = await sdk.WeComHelper.GetWeComInternalTokenAsync(WeComTokenTypeEnum.Contact);
// 获取企业 Id 与应用 AgentId(内部读取租户设置,无需手动拼设置项键名)
var corpId = sdk.WeComHelper.GetWeComCorpAppId();
var agentId = sdk.WeComHelper.GetWeComCorpAgentId();
使用场景
在插件中调用企业微信 API
典型场景是自定义通知渠道插件:插件收到通知发送请求后,先用 WeComHelper 取 token,再携带 token 调用企业微信「发送应用消息」API。
using Chameleon.Common.Models;
using Chameleon.SDK;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
public class ChameleonCSharpScript
{
public async Task<object> ExecuteAsync(ComponentContext context, ChameleonSDK sdk)
{
// 1. 获取平台缓存的企业微信 token
var token = await sdk.WeComHelper.GetWeComInternalTokenAsync(WeComTokenTypeEnum.Auth);
// 2. 组装企业微信应用消息(agentid 由 helper 内部从租户设置读取)
var agentId = int.Parse(sdk.WeComHelper.GetWeComCorpAgentId());
var touser = context.DicParam["Receiver"]; // 接收人的企业微信 userid,由插件自行维护映射
var content = context.DicParam["Content"];
// 3. 创建 HTTP 客户端并携带 token 调用企业微信 API
var client = sdk.HttpClientFactory.CreateClient("wecom");
// 4. 组装消息体(匿名对象,序列化交给 JsonConvert)
var payload = new
{
touser,
msgtype = "text",
agentid,
text = new { content }
};
var json = JsonConvert.SerializeObject(payload);
// 5. 用不带 BOM 的 UTF-8 编码,否则企业微信可能报 invalid json
var requestBody = new StringContent(json, new UTF8Encoding(false), "application/json");
var response = await client.PostAsync($"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={token}", requestBody);
var body = await response.Content.ReadAsStringAsync();
// 6. 解析 errcode 判断是否发送成功
var result = JsonConvert.DeserializeAnonymousType(body, new { errcode = 0, errmsg = "" });
if (result is not null && result.errcode != 0)
throw new System.Exception($"WeCom send failed: {result.errcode} {result.errmsg}");
return null;
}
}
平台不维护「系统用户 ↔ 企业微信 userid」的映射。企业微信的 touser 是什么、如何从系统用户推导出来,完全由插件脚本自行决定(例如查询映射表、使用工号、使用邮箱等)。
注意事项
- token 由平台缓存共享,不要在插件中自行请求
/cgi-bin/gettoken,重复获取会导致其他调用方的 token 失效 - token 有有效期(企业微信默认 7200 秒,平台提前 5 分钟过期刷新),每次调用企业微信 API 前都应重新获取,不要在插件中长期缓存
- 使用前需确保当前租户已配置企业微信设置项,见上方「所需租户设置」列;
GetWeComCorpAppId/GetWeComCorpAgentId未配置时返回空字符串,发送应用消息前建议判空 WeComTokenTypeEnum.Auth对应企业微信自建应用的 secret,发送应用消息时agentid通过GetWeComCorpAgentId获取
属性明细
以下内容面向技术实现与 AI 检索。
WeComTokenTypeEnum 属性表
| 属性名 | 类型 | 含义 | 取值/存储值 |
|---|---|---|---|
Auth | WeComTokenTypeEnum | 自建应用 token(应用消息/登录) | 1,对应服务端 SecretTypeEnum.Auth |
Contact | WeComTokenTypeEnum | 通讯录 token | 2,对应服务端 SecretTypeEnum.Contact |
OpenAPI 请求/响应
SDK 通过平台开放 API 获取 token:
| 项目 | 值 |
|---|---|
| 端点 | POST api/OpenApi/WeCom/GetInternalToken |
| 鉴权 | PolicyConst.System |
| 请求体 | { "tokenType": "1" },TokenType 为 string,接受枚举数值或名称字符串(如 "1" / "Auth",不区分大小写) |
| 响应 | ResponseResult<string>.Success(token),data 为 token 字符串 |
请求体定义:WeComInternalTokenRequest(Chameleon.Model.ValueObjects.WeCom),仅一个 TokenType(string)属性。
服务端执行逻辑
调用链:WeComHelper → WeComOpenApiController(POST api/OpenApi/WeCom/GetInternalToken)→ WeComInternalProxy.GetAccessTokenAsync:
- 解析
TokenType为SecretTypeEnum,解析失败或未定义时抛出ChameleonException(WeComTokenTypeInvalid) - 校验该 token 类型所需的租户设置(Auth:
WeComCorpAppId/WeComCorpAgentId/WeComAuthSecret;Contact:WeComCorpAppId/WeComContactSecret),缺失时抛出WeComConfigurationMissing,MoreMessage中列出缺失的设置项键名 - 以
WeCom_AccessToken_Cache_{corpId}_{tokenType}为键查询缓存(CacheHelper.StringGetAsync),命中直接返回 - 未命中则调用企业微信
/cgi-bin/gettoken(corpid+ 对应 secret)获取 token,缓存expires_in - 300秒后返回
异常与校验
| 场景 | 行为 |
|---|---|
TokenType 为空、非数字/名称或未定义的枚举值 | 抛出 ChameleonException(locale 常量 WeComTokenTypeInvalid) |
| 租户未配置对应 token 类型的设置项 | 抛出 ChameleonException(locale 常量 WeComConfigurationMissing),MoreMessage 为缺失的设置项键名列表 |
企业微信 API 返回 errcode != 0 | 抛出 ChameleonException,MoreMessage 携带企业微信 errmsg |