企业微信开发,嵌入自定义项目,及JS-SDK的引用

目标:

         基于H5开发项目,嵌入到企业微信中,并接入js-sdk 并运用企业微信接口。

开发环境:

        腾讯企业微信最新版本。后端环境不做要求,能跑通即可(这里我选用的是eclipse的maven项目,之前也出了一篇搭建后台项目的博客,可以了解一下)

需要工具:

        企业微信注册。花生壳开通内网穿透(花费6元)

一、创建项目  能运行即可

        随便一个能运行的项目即可。

二、花生壳配置

        参考另一篇文章:https://blog.csdn.net/zh5220909/article/details/81188185

三、申请企业微信

        (1)安卓手机上下载  企业微信APP

        (2)直接使用微信登录即可,需要新建一个公司,直接根据提示申请一个测试的即可

       (3)完成新建公司,则可以去登录管理端了。管理端网址:https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome

        (4)使用企业微信扫一扫登录即可

        (5)创建一个应用

       

设置网页授权JS-SDK

设置成功后

四、前端集成js-sdk

直接上页面代码,页面上的注释注意看看

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport"
	content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta charset="utf-8" />
<meta content="telephone=no" name="format-detection" />
<meta name="viewport"
	content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>企业微信</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<!-- 企业微信的JS-SDK -->
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

<style type="text/css">
.daiban {
	width: 60%;
	height: 40px;
	text-align: center;
	line-height: 2.5;
	border: 0px solid #ddd;
	background-color: yellow;
	margin: 20px 20% 0px 20%;
	border-radius: 5px;
}

.genzong {
	width: 60%;
	height: 40px;
	text-align: center;
	line-height: 2.5;
	border: 0px solid #ddd;
	background-color: pink;
	margin: 20px 20% 0px 20%;
	border-radius: 5px;
}
</style>
</head>
<body>
	<div id="a1" class="daiban">待办</div>
	<div id="a2" class="genzong">交换跟踪</div>
	<script type="text/javascript">
	
		//初始化方法
		function init() {
			getToken();
			bindClick();
		}

		//从后台获取wx.config中所需要的参数
		function getToken() {
			$.ajax({
				url : "/zboxService/zwwx/getSignature",
				type : "get",
				dataType : "json",
				success : function(data) {
					console.log(data)
					var json = data;
					wx.config({
						beta : true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
						debug : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
						appId : 'ww01c11527d43106b5', // 必填,企业微信的corpID
						timestamp : json.timestamp, // 必填,生成签名的时间戳
						nonceStr : json.noncestr, // 必填,生成签名的随机串
						signature : json.signature,// 必填,签名,见附录1
						jsApiList : [ 'checkJsApi', 'chooseImage',
								'openEnterpriseChat' ]
					// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
					});
					wx.ready(function() {
						wx.checkJsApi({
							jsApiList : [ 'chooseImage' ], // 需要检测的JS接口列表,所有JS接口列表见附录2,
							success : function(ress) {
								alert(2)
								// 以键值对的形式返回,可用的api值true,不可用为false
								// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
							}
						});
					});
				}
			})

		}
		
		//绑定两个按钮的点击事件
		function bindClick() {
			
			//这个接口是打开userIds对话框,运行则微信端直接跳到聊天框
			$("#a1").click(function() {
				wx.openEnterpriseChat({
					// 注意:userIds和externalUserIds至少选填一个,且userIds+openIds总数不能超过2000。
					userIds : 'DingSaiSai02;ZhuHao', //参与会话的企业成员列表,格式为userid1;userid2;...,用分号隔开。
					externalUserIds : '', // 参与会话的外部联系人列表,格式为userId1;userId2;…,用分号隔开。
					groupName : '讨论组', // 必填,会话名称。单聊时该参数传入空字符串""即可。
					success : function(res) {
						// 回调
					},
					fail : function(res) {
						if (res.errMsg.indexOf('function not exist') > -1) {
							alert('版本过低请升级')
						}
					}
				});
			});
			
			//这是选择本地图片的接口
			$("#a2").click(function() {
				wx.chooseImage({
					count : 1, // 默认9
					sizeType : [ 'original', 'compressed' ], // 可以指定是原图还是压缩图,默认二者都有
					sourceType : [ 'album', 'camera' ], // 可以指定来源是相册还是相机,默认二者都有
					defaultCameraMode : "batch", //表示进入拍照界面的默认模式,目前有normal与batch两种选择,normal表示普通单拍模式,batch表示连拍模式,不传该参数则为normal模式。(注:用户进入拍照界面仍然可自由切换两种模式)
					success : function(res) {
						var localIds = res.localIds; // 返回选定照片的本地ID列表,
						// andriod中localId可以作为img标签的src属性显示图片;
						// 而在IOS中需通过上面的接口getLocalImgData获取图片base64数据,从而用于img标签的显示
					}
				});
			});

		}
		init();
	</script>
</body>
</html>

后台代码,本人直接封装成了工具类

constens文件,里面写了几个对接企业微信的远程接口URL及参数格式

package com.hao.qywx.web;

public class ZwwxPostTencentConstants {

	/**
	 * 获取企业微信token地址及对应参数
	 */
	public static final String QYWX_GET_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
	public static final String QYWX_GET_TOKEN_URL_PARAM_CORPID = "corpid";
	public static final String QYWX_GET_TOKEN_URL_PARAM_CORPSECRET = "corpsecret";

	/**
	 * 获取企业微信token返回成功对应errcode值
	 */
	public static final String QYWX_GET_TOKEN_RETURN_SUCCESS_CODE = "0";
	public static final String QYWX_GET_TOKEN_RETURN_ERRCODE = "errcode";
	public static final String QYWX_GET_TOKEN_RETURN_ERRMSG = "errmsg";
	public static final String QYWX_GET_TOKEN_RETURN_TOKEN = "access_token";

	/**
	 * 获取企业微信引入JS-SDK的ticket地址及对应参数
	 */
	public static final String QYWX_GET_JSAPITICKET_URL = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
	public static final String QYWX_GET_JSAPITICKET_URL_PARAM_TOKEN = "access_token";

	public static final String QYWX_GET_JSAPITICKET_URL_PARAM_TICKET = "jsapi_ticket";
	public static final String QYWX_GET_JSAPITICKET_URL_PARAM_NONCESTR = "noncestr";
	public static final String QYWX_GET_JSAPITICKET_URL_PARAM_TIMESTAMP = "timestamp";
	public static final String QYWX_GET_JSAPITICKET_URL_PARAM_URL = "url";

	public static final String QYWX_GET_JSAPITICKET_RETURN_SIGNATURE = "signature";

	/**
	 * 获取用户ticket参数
	 */
	public static final String QYWX_GET_JSAPITICKET_RETURN_SUCCESS_CODE = "0";
	public static final String QYWX_GET_JSAPITICKET_RETURN_ERRCODE = "errcode";
	public static final String QYWX_GET_JSAPITICKET_RETURN_ERRMSG = "errmsg";
	public static final String QYWX_GET_JSAPITICKET_RETURN_TICKET = "ticket";

	/**
	 * 通过code获取用户信息url及其对应参数
	 */
	public static final String QYWX_GET_USERINFO_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
	public static final String QYWX_GET_USERINFO_URL_PARAM_TOKEN = "access_token";
	public static final String QYWX_GET_USERINFO_URL_PARAM_CODE = "code";

	/**
	 * 通过code获取用户信息返回参数
	 */
	public static final String QYWX_GET_USERINFO_RETURN_SUCCESS_CODE = "0";
	public static final String QYWX_GET_USERINFO_RETURN_ERRCODE = "errcode";
	public static final String QYWX_GET_USERINFO_RETURN_ERRMSG = "errmsg";
	public static final String QYWX_GET_USERINFO_RETURN_USERID = "UserId";

	/**
	 * 企业微信的CorpID,在企业微信管理端查看
	 */
	public static final String QYWX_CORPID = "";

	/**
	 * 授权方的网页应用ID,在具体的网页应用中查看
	 */
	public static final String QYWX_AGENTID = "";

	/**
	 * 应用的凭证密钥,在具体的网页应用中查看
	 */
	public static final String QYWX_CORPSECRET = "";

	/**
	 * 参数连接符
	 */
	public static final String QYWX_AND = "&";
	public static final String QYWX_EQUAL = "=";
	public static final String QYWX_QUERY = "?";
}

工具类,

package com.hao.qywx.web;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.alibaba.fastjson.JSONObject;

public class ZwwxPostTencentUtil {

	/**
	 * @name 中文名称
	 * @description 根据页面URL和页面ticket生成接入JS-SDK接入码
	 * @time 创建时间:2018年7月23日19:58:05
	 * @param url:接入js-sdk的页面地址
	 * 			ticket:通过token生成的接入js-sdk的ticket
	 * @return 请求返回接入js-sdk所需json对象
	 * @author 朱浩
	 * @history 修订历史(历次修订内容、修订人、修订时间等)
	 */
	public static JSONObject getSignature(String url, String ticket) {
		JSONObject rul = new JSONObject();

		String noncestr = getRandomString(16);
		String timestamp = (int)(System.currentTimeMillis()/1000)+"";
		String sign = "";
		sign += ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_TICKET
				+ ZwwxPostTencentConstants.QYWX_EQUAL
				+ ticket
				+ ZwwxPostTencentConstants.QYWX_AND
				+ ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_NONCESTR
				+ ZwwxPostTencentConstants.QYWX_EQUAL
				+ noncestr
				+ ZwwxPostTencentConstants.QYWX_AND
				+ ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_TIMESTAMP
				+ ZwwxPostTencentConstants.QYWX_EQUAL + timestamp
				+ ZwwxPostTencentConstants.QYWX_AND
				+ ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_URL
				+ ZwwxPostTencentConstants.QYWX_EQUAL + url;
		String signature = "";
		try {
			// 指定sha1算法
			MessageDigest digest = MessageDigest.getInstance("SHA-1");
			digest.update(sign.getBytes());
			// 获取字节数组
			byte messageDigest[] = digest.digest();
			// Create Hex String
			StringBuffer hexString = new StringBuffer();
			// 字节数组转换为 十六进制 数
			for (int i = 0; i < messageDigest.length; i++) {
				String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexString.append(0);
				}
				hexString.append(shaHex);
			}
			signature = hexString.toString();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		rul.put(ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_RETURN_SIGNATURE,
				signature);
		rul.put(ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_NONCESTR,
				noncestr);
		rul.put(ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_TIMESTAMP,
				timestamp);
		return rul;
	}

	/**
	 * @name 中文名称
	 * @description 根据扫码登录返回的code值和应用token值获取扫码登录人用户id(注:id为企业微信扫码人id)
	 * @time 创建时间:2018年7月23日14:07:28
	 * @param code
	 *            :前台扫码登录后微信js插件会自动跳转链接,且附带该code。 accessToken: 应用调用接口凭证,
	 *            该类下getTencentToken()方法可直接获取。
	 * @return 请求返回userid
	 * @author 朱浩
	 * @history 修订历史(历次修订内容、修订人、修订时间等)
	 */
	public static String getTencentUserInfo(String code, String accessToken) {
		String url = "";
		url += ZwwxPostTencentConstants.QYWX_GET_USERINFO_URL
				+ ZwwxPostTencentConstants.QYWX_QUERY;
		url += ZwwxPostTencentConstants.QYWX_GET_USERINFO_URL_PARAM_TOKEN
				+ ZwwxPostTencentConstants.QYWX_EQUAL + accessToken;
		url += ZwwxPostTencentConstants.QYWX_AND;
		url += ZwwxPostTencentConstants.QYWX_GET_USERINFO_URL_PARAM_CODE
				+ ZwwxPostTencentConstants.QYWX_EQUAL + code;
		JSONObject userInfoJson = sendPostRequest(url);
		String errcode = userInfoJson
				.getString(ZwwxPostTencentConstants.QYWX_GET_USERINFO_RETURN_ERRCODE);
		if (ZwwxPostTencentConstants.QYWX_GET_USERINFO_RETURN_SUCCESS_CODE
				.equals(errcode)) {
			return userInfoJson
					.getString(ZwwxPostTencentConstants.QYWX_GET_USERINFO_RETURN_USERID);
		} else {
		}
		return null;
	}

	/**
	 * @name 中文名称
	 * @description 获取企业微信Token(应用调用接口凭证) 该值具有以下特性: 1、通用性:该企业微信应用下通用, 2、
	 *              有效性:该值有效时长为7200秒, 3、微信端不可长期无限制请求,推荐使用缓存保存改值
	 * @time 创建时间:2018年7月23日14:07:28
	 * @param 请求URL地址
	 *            ,参数需自行拼接
	 * @return 请求返回token值
	 * @author 朱浩
	 * @history 修订历史(历次修订内容、修订人、修订时间等)
	 */
	public static String getTencentToken() {
		String url = "";
		url += ZwwxPostTencentConstants.QYWX_GET_TOKEN_URL
				+ ZwwxPostTencentConstants.QYWX_QUERY;
		url += ZwwxPostTencentConstants.QYWX_GET_TOKEN_URL_PARAM_CORPID
				+ ZwwxPostTencentConstants.QYWX_EQUAL
				+ ZwwxPostTencentConstants.QYWX_CORPID;
		url += ZwwxPostTencentConstants.QYWX_AND
				+ ZwwxPostTencentConstants.QYWX_GET_TOKEN_URL_PARAM_CORPSECRET
				+ ZwwxPostTencentConstants.QYWX_EQUAL;
		url += ZwwxPostTencentConstants.QYWX_CORPSECRET;
		JSONObject tokenJson = sendPostRequest(url);
		String errcode = tokenJson
				.getString(ZwwxPostTencentConstants.QYWX_GET_TOKEN_RETURN_ERRCODE);
		if (ZwwxPostTencentConstants.QYWX_GET_TOKEN_RETURN_SUCCESS_CODE
				.equals(errcode)) {
			return tokenJson
					.getString(ZwwxPostTencentConstants.QYWX_GET_TOKEN_RETURN_TOKEN);
		} else {
		}
		return null;
	}

	/**
	 * @name 中文名称
	 * @description 根据token获取接入js-sdk的ticket
	 * @time 创建时间:2018年7月23日19:33:47
	 * @param accessToken
	 *            : 应用调用接口凭证, 该类下getTencentToken()方法可直接获取。
	 * @return 请求返回ticket值。
	 * @author 朱浩
	 * @history 修订历史(历次修订内容、修订人、修订时间等)
	 */
	public static String getTencentJSSDKTicket(String token) {
		String url = "";
		url += ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL
				+ ZwwxPostTencentConstants.QYWX_QUERY;
		url += ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_URL_PARAM_TOKEN
				+ ZwwxPostTencentConstants.QYWX_EQUAL + token;
		JSONObject ticketJson = sendPostRequest(url);
		String errcode = ticketJson
				.getString(ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_RETURN_ERRCODE);
		if (ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_RETURN_SUCCESS_CODE
				.equals(errcode)) {
			return ticketJson
					.getString(ZwwxPostTencentConstants.QYWX_GET_JSAPITICKET_RETURN_TICKET);
		} else {
		}
		return null;
	}

	/**
	 * @name 中文名称
	 * @description 相关说明
	 * @time 创建时间:2018年7月23日11:48:33
	 * @param 请求URL地址
	 *            ,参数需自行拼接
	 * @return 请求返回json对象
	 * @author 朱浩
	 * @history 修订历史(历次修订内容、修订人、修订时间等)
	 */
	private static JSONObject sendPostRequest(String url) {
		StringBuffer stringBuffer = new StringBuffer("");
		try {
			URL postUrl = new URL(url);
			HttpURLConnection connection = (HttpURLConnection) postUrl
					.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.setInstanceFollowRedirects(true);
			connection.setRequestProperty("Content-Type", "application/json");
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					connection.getInputStream()));
			String line;
			while ((line = reader.readLine()) != null) {
				stringBuffer.append(line);
			}
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return JSONObject.parseObject(stringBuffer.toString());
	}

	/**
	 * @name 中文名称
	 * @description 获取指定位数的随机字符串(包含小写字母、大写字母、数字,0<length)
	 * @time 创建时间:2018年7月23日14:17:21
	 * @param 获取字符串长度
	 * @return 对应长度的随机字符串
	 * @author 朱浩
	 * @history 修订历史(历次修订内容、修订人、修订时间等)
	 */
	private static String getRandomString(int length) {
		// 随机字符串的随机字符库
		String KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		StringBuffer sb = new StringBuffer();
		int len = KeyString.length();
		for (int i = 0; i < length; i++) {
			sb.append(KeyString.charAt((int) Math.round(Math.random()
					* (len - 1))));
		}
		return sb.toString();
	}
}

实现接口

        JSONObject rul = new JSONObject();
		String token = ZwwxPostTencentUtil.getTencentToken();
		String ticket = ZwwxPostTencentUtil.getTencentJSSDKTicket(token);
		rul = ZwwxPostTencentUtil.getSignature(url, ticket);

五、踩坑记录

(1)必须有可以外网访问的项目,推荐花生壳内网穿透直接搞定。

(2)在企业微信后台配置js-sdk可信域名的时候需要根据提示下载一个文件放在项目根目录下

(3)网页端是无法调试JS-SDK接口的,包括微信开发工具其实也不是很好用,最好是用手机测试

(4)我在用手机测试的时候一直没有反应,但是在微信开发工具中测试又是有反应的(这里的反应指的是alert),最终在大神的指导下,写在APP从新安装(好吧,这个确实是个坑,当你在微信开发工具中测试有反应,但手机上没反应的话可以试试)

(5)注意一下我获取Signature这段代码,其中的timestamp 单位是秒  秒 秒

(6)还有各种坑,可能想不起来了,欢迎各位留言,有可能我就遇到过!

六、各种文献链接

企业微信后台登录链接:https://work.weixin.qq.com/

企业微信开发文档API:https://work.weixin.qq.com/api/doc

花生壳官网:https://hsk.oray.com/

花生壳管理端:https://login.oray.com/login/?tplname=qrcode&s_url=https%3A%2F%2Fhsk.oray.com%2Fconsole%2Fmanage%2F

项目文件 github:https://github.com/zhuhao18/Zbox-qywx

猜你喜欢

转载自blog.csdn.net/zh5220909/article/details/81188857