企业微信自建应用审批接口开发

您所在的位置:网站首页 企业签名接口 企业微信自建应用审批接口开发

企业微信自建应用审批接口开发

2024-07-15 11:39| 来源: 网络整理| 查看: 265

再说一次,企业微信开发文档很坑,特别坑,坑成鬼了。

有时候浪费很长时间改bug,查来查去,都没有发现到底哪里错了,查资料,搜资料,询问大神,都没有发现bug。改到最后都抑郁了,才发现用浏览器访问根本就不会报出具体的错误,pc端的企业微信客户端也不行,只有用手机上的企业微信客户端访问才会有具体的错误信息,在这方面浪费了很长时间,感觉自己有点傻,但是内心不承认。

总之,要想一帆风顺开发,听起来像是开玩笑,总会遇到让自己怀疑人生的bug。

文档对于很多细节描述不具体,而且也有很多东西没有demo可以参观,有demo的还是PHP,怎么说呢,有些东西想在网上查查,都查不到,所有,在开始之前,请让我先好好吐槽一下,以解我这几天的心头之火。

好吧,废话不多说,总不能转行吧!所以还是好好学习吧!!

企业微信自建应用审批接口开发:企业微信自带有审批接口,最主要是,使用企业微信审批能力,在非审批应用内设置流程、发起审批。还能订阅通知消息,接收审批状态变化情况。

现在很多企业都使用企业微信审批接口,使用企业微信审批接口,审批发生变化,会自动发送消息给审批人以及抄送人,比较方便。微信自带的审批接口适用于小企业,简单的业务。一般大公司都会开发适用于自己企业的OA系统。

企业微信自建应用审批接口开发:

1.首先在企业微信后端,创建应用,进入审批接口,添加模板

2.自建应用发起审批

      通过JS-SDK,可在自建应用中发起审批,需要设置可信域名,花生壳免费域名,我试了,不行!

3.设置工作台应用主页,在主页内发起审批

注意:

      1.测试时一定要用手机企业微信客户端,会显示详细错误信息,用浏览器或者pc端, 比较坑爹。              2.善于利用签名工具,验证自己各数据是否正确生成 

1.首先在企业微信后端,创建应用,进入审批接口,添加模板

 

2.自建应用发起审批

点击接入流程说明,进入开发API

 

 开发逻辑为上图所示

2.1

     通过JS-SDK,可在自建应用中发起审批。查看JS-SDK调用详细说明                具体步骤:                   1.通过config接口注入权限验证配置                   2.通过agentConfig注入应用的权限                   3.调用审批流程引擎JS-API

1.通过config接口注入权限验证配置 wx.config({        beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。        appId: '', // 必填,企业微信的corpID        timestamp:'' , // 必填,生成签名的时间戳        nonceStr: '', // 必填,生成签名的随机串        signature: '',// 必填,签名,见 附录-JS-SDK使用权限签名算法        jsApiList: ['agentConfig','thirdPartyOpenPage','selectExternalContact'] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来    });    wx.ready(function(){            2.通过agentConfig注入应用的权限。        wx.agentConfig({            corpid: '', // 必填,企业微信的corpid,必须与当前登录的企业一致            agentid: '', // 必填,企业微信的应用id            timestamp: , // 必填,生成签名的时间戳            nonceStr: '', // 必填,生成签名的随机串            signature: '',// 必填,签名,见附录1            jsApiList: ['thirdPartyOpenPage','selectExternalContact'], //必填            success: function(res) {                            3.调用审批流程引擎JS-API                wx.invoke('thirdPartyOpenPage', {                    "oaType": "10001",// String                    "templateId": "46af67a118a6ebf000002",// String                    "thirdNo": "thirdNo",// String                    "extData": {                        'fieldList': [{                            'title': '采购类型',                            'type': 'text',                            'value': '市场活动',                        },                        {                            'title': '订单链接',                            'type': 'link',                            'value': 'https://work.weixin.qq.com',                        }],                    }                },                function(res) {                    // 输出接口的回调信息                    console.log(res);                });                            },            fail: function(res) {                if(res.errMsg.indexOf('function not exist') > -1){                    alert('版本过低请升级')                }            }        });    });

各个接口都调用成功的话,那么离成功就不远了;

2.1.jsp页面主要代码

function approval() { //动态获取当前页面url var link = window.location.href;

$.ajax({ type:"GET", data:{"url":link}, url:"/approval/send_approval.do", dataType:"json", success:function (data) {

console.log(data); wx.config({ beta: true, debug: true, appId: data.appId, timestamp: data.config_timestamp, nonceStr: data.config_nonceStr, signature: data.config_signature, jsApiList: ['agentConfig','openUserProfile','thirdPartyOpenPage','selectExternalContact'] });

wx.ready(function () { alert("config"); wx.agentConfig({ corpid: data.appId, agentid: data.agentid, timestamp: data.agent_timestamp, nonceStr: data.agent_nonceStr, signature: data.agent_signature, jsApiList: ['thirdPartyOpenPage','selectExternalContact'], success: function(res) { //审批流程js调用 alert("agentConfig"); wx.invoke('thirdPartyOpenPage', { "oaType": data.oaType, "templateId": data.templateId, "thirdNo": data.thirdNo, "extData": { 'fieldList': [{ 'title': '采购类型', 'type': 'text', 'value': '市场活动', }, { 'title': '订单链接', 'type': 'link', 'value': 'https://work.weixin.qq.com', }], } }, function(res) { // 输出接口的回调信息 alert("thirdPartyOpenPage"); alert(res); } ); }, fail: function(res) { alert("approval提交不通过"); alert("agentConfig:"+res.errMsg); if(res.errMsg.indexOf('function not exist') > -1){ alert('版本过低请升级') } } });

});

wx.error(function(res){

}); } }) }

2.2后端主要代码

@RequestMapping(value = "send_approval.do") public void sendApproval(HttpServletRequest request, HttpServletResponse response,String url)throws Exception{ request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");

JSONObject jsonObject = iApprovalService.approvalCreate(url).getData(); //返回数据到jsp页面 response.getWriter().print(jsonObject); } public JSONObject approvalCreate(String url){

JSONObject object = new JSONObject();

//agentConfig接口下主要数据 String approval_ticket = JS_Util.getApprovalTicket(); JSONObject appJSONObject = JS_Util.getSignature(url,approval_ticket); object.put("agent_nonceStr",appJSONObject.get("nonceStr").toString()); object.put("agent_timestamp",appJSONObject.get("timestamp").toString()); object.put("agent_signature",appJSONObject.get("signature").toString()); System.out.println("==============================="); System.out.println(appJSONObject.toString());

//config接口下主要数据 String ticket = JS_Util.getJsApiTicket(); JSONObject jsonObject = JS_Util.getSignature(url,ticket); object.put("config_nonceStr",jsonObject.get("nonceStr").toString()); object.put("config_timestamp",jsonObject.get("timestamp").toString()); object.put("config_signature",jsonObject.get("signature").toString()); System.out.println("==========================="); System.out.println(jsonObject.toString());

//invoke接口下主要数据 object.put("thirdNo",String.valueOf(generateOrderNo())); object.put("appId",PropertiesUtil.getProperty("corpid")); object.put("agentid",PropertiesUtil.getProperty("mycreateapp_agentid")); object.put("templateId",PropertiesUtil.getProperty("approval_id")); object.put("oaType","10001");

return object; } 

 

signatrue的生成

  

可以使用签名工具,查看生成的signatrue是否正确,可以快速的排除自己代码的错误

 

signature生成

    

签名算法签名生成规则如下:参与签名的参数有四个: noncestr(随机字符串), jsapi_ticket, timestamp(时间戳), url(当前网页的URL, 不包含#及其后面部分)

将这些参数使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成字符串string1。有两个注意点:1. 字段值采用原始值,不要进行URL转义;2. 必须严格按照如下格式拼接,不可变动字段顺序。

    jsapi_ticket=JSAPITICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL

然后对string1作sha1加密即可。

 

注意事项

签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。签名用的url必须是调用JS接口页面的完整URL。出于安全考虑,开发者必须在服务器端实现签名的逻辑。 

 public class JS_Util {

private static Logger logger = LoggerFactory.getLogger(JS_Util.class);

//获取企业的jsapi_ticket private final static String GET_WX_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN";

//应用jsapi_tictet private final static String GET_APP_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=ACCESS_TOKEN&type=agent_config";

//获取企业的ticket public static String getJsApiTicket(){ String access_token = WeiXinUtil.getAccessToken(PropertiesUtil.getProperty("corpid"),PropertiesUtil.getProperty("mycreateapp_secret")).getAccess_token(); String url = GET_WX_TICKET.replace("ACCESS_TOKEN",access_token); JSONObject jsonObject = WeiXinUtil.httpRequest(url,"GET",null); String ticket = jsonObject.get("ticket").toString(); return ticket; }

//获取审批流程ticket public static String getApprovalTicket(){ String access_token = WeiXinUtil.getAccessToken(PropertiesUtil.getProperty("corpid"),PropertiesUtil.getProperty("mycreateapp_secret")).getAccess_token(); String url = GET_APP_TICKET.replace("ACCESS_TOKEN",access_token); JSONObject jsonObject = WeiXinUtil.httpRequest(url,"GET",null); String ticket = jsonObject.get("ticket").toString(); return ticket; }

/** * 参与签名的参数有四个: noncestr(随机字符串), jsapi_ticket, timestamp(时间戳), url(当前网页的URL, 不包含#及其后面部分) * 将这些参数使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成字符串string1。 * 然后对string1作sha1加密即可。 * @return */ public static JSONObject getSignature(String url,String ticket){

JSONObject jsonObject = new JSONObject();

String noncestr = getRandomString(16); String timestamp = Long.toString(System.currentTimeMillis()).substring(0,10);

// jsapi_ticket=JSAPITICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL 顺序不能更改 String str = "jsapi_ticket="+ticket+ "&noncestr="+noncestr+ "×tamp="+timestamp+ "&url="+url;

String signature = SHA1(str); jsonObject.put("nonceStr",noncestr); jsonObject.put("timestamp",timestamp); jsonObject.put("signature",signature); jsonObject.put("ticket",ticket); return jsonObject; }

private static String SHA1(String decript){ try{ MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(decript.getBytes()); byte[] digest = md.digest();

StringBuffer hexstr = new StringBuffer(); for (int i = 0; i < digest.length; i++) { String shaHex = Integer.toHexString(digest[i] & 0xFF); if (shaHex.length() < 2) { hexstr.append(0); } hexstr.append(shaHex); } return hexstr.toString(); }catch (Exception e){ logger.error("sha1加密错误",e); } return ""; }

private static String getRandomString(int length){ String keyString = "ergrfewfwdgggcvv;uihefujsncjdvngrjegeuirgverggvbergbvuigverug"; int len = keyString.length(); StringBuffer str = new StringBuffer(); for(int i=0;i



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3