企业微信第三方服务商应用开发及上架教程

之前一直没有写这篇文章,是觉得企微的服务商应用相对简单。第二个原因是最近在弄钉钉的ISV上架,所以时间不是很充足。正题开始……

 

第一章 服务商入驻

1、使用管理员登录服务商管理后台

企业微信-服务商后台-登录地址https://open.work.weixin.qq.com/wwopen/login2、输入基本信息及认证

企业微信第三方服务商应用开发及上架教程_第1张图片

企业微信第三方服务商应用开发及上架教程_第2张图片

 

第二章 应用配置

1、登录后,直接创建创建网页应用,如下图。

企业微信第三方服务商应用开发及上架教程_第3张图片

 2、应用详情-使用配置-参照下面的教程。主页地址是固定的,只需要写入自己的appid和redirect_uri的地址就行。这里需要注意,可信域名必须配置一下,需要注意的是这个一级域名一旦使用的服务商应用,那么自建应用是无法在使用这个域名的,即便是不同的二级域名也不可以。这个还是比较坑,导致我们重新申请了一个一级域名来服务自建应用。

企业微信第三方服务商应用开发及上架教程_第4张图片

 3、可信域名配置,使用配置-点击【编辑】,然后点击【校验可信域名归属】,然后下载这个文件到nginx配置的域名文件夹下,只要通过步骤2的地址可以访问到就算验证通过。nginx的配置参照下面的这个文章。

nginx配置websocket或https的转发教程_renkai721的博客-CSDN博客_nginx websocket转发nginx配置http,https,ssl,websocket转发https://blog.csdn.net/renkai721/article/details/125991270

企业微信第三方服务商应用开发及上架教程_第5张图片

 4、数据回调的配置

企业微信第三方服务商应用开发及上架教程_第6张图片

 

第三章 应用开发

1、pom.xml中添加解析XML格式内容


		
		
			org.jdom
			jdom2
			2.0.6
		
		
			commons-codec
			commons-codec
			1.15
		

2、properties文件,不需要那么多,命名更具自己的喜好,这一看就是参照了gitee的binarywang/weixin-java-cp-demo,这个demo如果初学者可以看看,然后自己封装。

企业微信第三方服务商应用开发及上架教程_第7张图片

 3、核心解密controller.java

package cn.renkai721.controller;

import cn.renkai721.bean.*;
import cn.renkai721.configuration.QywxProperties;
import cn.renkai721.service.*;
import cn.renkai721.util.HttpUtil;
import cn.renkai721.util.MsgUtil;
import cn.renkai721.util.WxUtil;
import cn.renkai721.wechataes.WXBizMsgCrypt;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Map;


@EnableAsync
@RestController
@RequestMapping("/d3f")
@Slf4j
public class D3f2Controller {
    @Resource
    private RedissonClient redissonClient;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private D3fService d3fService;


    @GetMapping(produces = "text/plain;charset=utf-8")
    public void d3fGet(@RequestParam(name = "msg_signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr,
                          HttpServletResponse response) throws Exception  {
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(
                MsgUtil.val("wechat.cp.appConfigs[0].token"),
                MsgUtil.val("wechat.cp.appConfigs[0].aesKey"),
                MsgUtil.val("wechat.cp.corpId"));
        // 需要返回的明文
        String sEchoStr = "";
        try {
            sEchoStr = wxcpt.VerifyURL(signature, timestamp, nonce, echostr);
            log.info("resp sEchoStr={}",sEchoStr);
            response.getWriter().print(sEchoStr);
            return;
        } catch (Exception e) {
            // 验证URL失败,错误原因请查看异常
            e.printStackTrace();
        }
        response.getWriter().print("非法请求");
        return;
    }

    @PostMapping(produces = "application/xml; charset=UTF-8")
    public void d3fPost(@RequestParam("msg_signature") String signature,
                     @RequestParam("timestamp") String timestamp,
                     @RequestParam("nonce") String nonce,
                     HttpServletResponse response,
                     HttpServletRequest request) throws Exception {
        String success = "success";
        String type = request.getParameter("type");
        String corpid = request.getParameter("corpid");
        log.info("接收d3f post请求:[signature=[{}], timestamp=[{}], nonce=[{}], type=[{}], corpid=[{}] ]",
                signature, timestamp, nonce, type, corpid);
        try{
            response.setContentType("text/html;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_OK);
            String id = "";
            // 访问应用和企业回调传不同的ID
            if("data".equals(type)){
                // 企微后台设置【数据回调URL】的链接为https://wx.naturobot.com/qywx/d3f?type=data&corpid=$CORPID$
                id = corpid;
            } else {
                id = MsgUtil.val("suite_id");
            }
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(MsgUtil.val(
                    "wechat.cp.appConfigs[0].token"),
                    MsgUtil.val("wechat.cp.appConfigs[0].aesKey"),
                    id);
            // 密文,对应POST请求的数据
            String postData = "";
            // 获取加密的请求消息:使用输入流获得加密请求消息postData
            ServletInputStream in = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            // 作为输出字符串的临时串,用于判断是否读取完毕
            String tempStr = "";
            while(null != (tempStr=reader.readLine())){
                postData += tempStr;
            }
            String suiteXml = wxcpt.DecryptMsg(signature, timestamp, nonce, postData);
            Map suiteMap = WxUtil.transferXmlToMap(suiteXml);
            log.info("\n req map={}", suiteMap);
            if("suite_ticket".equals(suiteMap.get("InfoType"))){
                // https://developer.work.weixin.qq.com/document/10975#%E8%8E%B7%E5%8F%96%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E5%87%AD%E8%AF%81
                // 主动推送SuiteTicket直接写入
                // 每十分钟更新一次
       

你可能感兴趣的:(JAVA,企微服务商应用,企业微信,服务商上架,对接企微,企微发送消息)