企业微信二次开发实战:第一次调用API需要准备哪些参数

昨晚在整理 星云API www.xingyapi.com 的底层对接实战笔记,准备往各大技术社区同步连载的时候,有个做私域代运营的后端兄弟找我排错。

他们组一个新人刚接手企微中台,写第一个“发送应用消息”接口,结果发出去的消息不是报 81013(找不到接收人),就是报 40008(消息类型不合法)。我让他把组装好的 JSON 报文发过来一看,这兄弟把企微内部的 userid 和外部微信的 openid 搞混了,而且业务载荷里连发送方都没指定。

在真实的工业级开发中,哪怕是第一次调用 API,也绝不能抱着“盲猜乱试”的心态。企微的接口参数校验极其严苛,类型传错直接报错,漏传关键参数可能导致消息路由彻底瘫痪。很多兄弟拿到需求,连 Apifox 里的环境参数都没调通,就开始在业务代码里硬怼。今天咱们直接把企微 API 调用的参数体系彻底拆解,手撕这三层参数结构。

第一层:鉴权与基础环境参数(基石)

你要调用任何一个主动 API,最先要准备的绝对不是业务数据,而是“你是谁”的证明。

如果你去仔细查阅 开发文档,你会发现企微所有的 API 请求 URL 中,有且仅有一个查询参数是必填的:access_token

为了拿到这把钥匙,你的系统环境变量(或配置中心)里必须备齐两个静态参数:

  1. corpid(企业ID):代表你的租户,是整个企业的唯一标识。

  2. corpsecret(应用密钥):代表你当前调用的具体应用(如自建的客服助手)。千万记住,不同应用的 Secret 换出来的 Token 权限是完全隔离的。

防坑指南:在本地用 Apifox 调试时,必须确保你的外网出口 IP 已经加到了该应用的“企业可信 IP”白名单中,否则哪怕参数全对,也会被网关无情拦截。

第二层:路由寻址参数(定向狙击)

有了 Token,请求发到了企微网关,接下来你需要告诉网关:“这条消息是谁发的,要发给谁?”。在发送消息的 JSON Body 中,这组路由参数是决定生死的核心。

  1. agentid(发送方应用ID): 必填参数(整型)。很多新手会漏掉这个参数,认为 Token 已经代表了应用。错!在企微的网关路由树里,必须显式声明 agentid,消息才能带上正确的小程序或应用卡片尾巴。

  2. touser / toparty / totag(接收方矩阵)

    • touser:接收消息的用户 userid这是重灾区! 这里绝对不能传手机号,也不能传外部客户的 external_userid(除非是特定的外部群发接口)。多个接收者用 | 分隔,最多支持 1000 个。如果你想全员发送,可以传 @all(极度危险,测试环境慎用)。

    • toparty:部门 ID。发给整个技术部或销售部。

    • totag:标签 ID。发给打上了特定内部标签的员工。 (注:这三者不能同时为空,至少得填一个。)

第三层:业务载荷参数(数据骨架)

确定了收发双方,最后一步才是填充真正的“血肉”。企微支持文本、图片、图文、Markdown 等十几种消息类型。

  1. msgtype(消息类型): 字符串强校验。传 text,后面的载荷对象就必须叫 text;传 markdown,后面就必须叫 markdown。拼写错一个字母直接报 40008。

  2. 具体的载荷对象(如 textmarkdown: 里面包含具体的 content。对于 Markdown,还要严格遵守企微阉割版的 Markdown 语法规范(比如不支持某些复杂的表格样式,字体颜色只支持特定的 info, comment, warning)。

  3. safe(保密开关)工业级隐藏彩蛋。这是一个选填的整型参数(0 表示否,1 表示是)。如果你在开发财务报表推送、高管薪资通知的机器人,必须传入 "safe": 1。这样发出去的消息会加上水印,且在企微客户端内绝对无法转发。这是 SaaS 级系统体现专业度的一个关键细节。

终局:在代码中优雅拼装

把这三层参数理顺,在真正的业务代码中,我们绝不会用字符串拼接来构建请求,而是通过标准的对象序列化来确保参数结构的严谨性:

Java

public void sendFirstMessage(String targetUserId) {
    // 1. 从你的 Token 引擎中获取鉴权参数
    String token = tokenManager.getToken(TenantContextHolder.getCorpId());
    String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + token;

    // 2. 构建 JSON 报文
    JSONObject payload = new JSONObject();
    
    // 路由寻址参数
    payload.put("touser", targetUserId); // 发给谁
    payload.put("agentid", 1000005);     // 谁发的
    
    // 业务载荷参数
    payload.put("msgtype", "markdown");
    payload.put("safe", 0);              // 允许转发
    
    // 具体的 Markdown 骨架
    JSONObject markdown = new JSONObject();
    markdown.put("content", "### 🚀 接口联调成功\n" +
                            "> **环境**:<font color=\"info\">测试环境</font>\n" +
                            "> **参数校验**:全部通过,网关已放行。");
    payload.put("markdown", markdown);

    // 3. 执行调用
    String response = HttpUtils.postJson(url, payload.toJSONString());
    log.info("企微网关响应: {}", response);
}

任何一次企微 API 的成功调用,本质上都是这三大类参数的完美契合。不要嫌这些结构繁琐,在多租户的复杂生态里,正是这些严苛的参数规范,保证了千万级消息的精准投递。

你们团队在对接这类包含各种复杂结构的企微 API 时,为了防止新人拼错 JSON 结构,是喜欢在后端工程里维护一套庞大的强类型 DTO(数据传输对象)类库,还是更倾向于直接将 Apifox 里调试好的 JSON Schema 导出来作为模版动态渲染?

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值