本文同步自我的CSDN博客: https://blog.csdn.net/qq_43270074/article/details/105692163
一、前言
前提:第三方服务商已注册并安装第三方应用,并且在第三方应用已经配置回调,且第三方的回调服务地址可用。本节介绍应用授权安装后回调逻辑,变更应用可见性回调逻辑,外部联系人回调逻辑,
二、授权回调
在企业在企业微信后台安装我们的应用时,会有授权回调,首先需要获取永久授权码并保存在自己的应用数据库。
1、获取永久授权码
获取永久授权码
将安装了我们应用的企业放在本地数据库
permanent_code和corpid等相关信息做保存
这里需要将应用可见人、可见部门、可见标签都存起来,方便日后成员变更时用
相关代码如下:
//调用企业微信接口
String url = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=" + wx2CpThirdService.getSuiteAccessToken();
//传递参数
Map<String, Object> paramMap = new HashMap<>(2);
paramMap.put("auth_code", tempCode);
//调用
String postData = HttpUtil.sendPost(url, JSONObject.toJSONString(paramMap));
log.info("接口调用成功返回postData==" + postData);
JSONObject jsonObject = JSONObject.parseObject(postData);
//获取相关信息并存取
String corpId = jsonObject.getJSONObject("auth_corp_info").getString("corpid");
if (StringUtils.isBlank(corpId)) {
log.error("corpId不存在");
return false;
}
Integer count = lambdaQuery().eq(CpThirdConfig::getCorpId, corpId).eq(CpThirdConfig::getSuiteId, wx2CpThirdProperties.getSuiteId2()).count();
//先删除相同的corpId
if (count > 0) {
return false;
}
String permanentCode = jsonObject.getString("permanent_code");
String corpName = jsonObject.getJSONObject("auth_corp_info").getString("corp_name");
//文档说,对新的单应用授权,永远只返回一个agent
JSONObject agentJson = jsonObject.getJSONObject("auth_info").getJSONArray("agent").getJSONObject(0);
//存取企业的agentId
String agentId = agentJson.getString("agentid");
//存取应用可见的人员
JSONArray allowUserArray = agentJson.getJSONObject("privilege").getJSONArray("allow_user");
//应用可见部门
JSONArray allowPartyArray = agentJson.getJSONObject("privilege").getJSONArray("allow_party");
//应用可见标签
JSONArray allowTagArray = agentJson.getJSONObject("privilege").getJSONArray("allow_tag");
//保存第三方应用信息im_cp_third_config表
CpThirdConfig cpThirdConfig = new CpThirdConfig();
cpThirdConfig.setCorpId(corpId)
.setPermanentCode(permanentCode)
.setSuiteId(wx2CpThirdProperties.getSuiteId2())
.setCorpName(corpName)
.setAgentId(agentId)
.setAllowUser(ObjectUtils.allNotNull(allowUserArray) ? allowUserArray.toJSONString() : null)
.setAuthUserInfo(authUserInfo)
.setReturnData(postData)
.setAllowParty(ObjectUtils.allNotNull(allowPartyArray) ? allowPartyArray.toJSONString() : null)
.setAllowTag(ObjectUtils.allNotNull(allowTagArray) ? allowTagArray.toJSONString() : null);
this.save(cpThirdConfig);
2、生成可见人员角色、管理员角色
根据corid为每一个企业生成三个管理员角色,分别是超级管理员、管理员、可见人员,并且为对应的角色分配不同的菜单权限
涉及到菜单表、菜单角色表
3、保存管理员信息(可见人员不设为管理员,将应用的管理员作为管理员)
将第三方应用到管理员作为我们应用后台管理到管理员,这里很容易混淆。
第三方应用管理员可以在企业微信管理后台设置,理论上,企业微信超级管理员是所有应用的管理员,可以为用户设置单独的应用管理员
可以在管理组设置管理范围和通讯录权限
4、保存可见人员信息
将可见人员单独设一张表,方便以后业务需要
这个地方有个坑
企业微信在获取永久授权吗的时候,返回的可见人员不包含部门内和标签内的可见人员,即当可见范围里面既有可见人员又有可见部门还有可见标签时,返回的会是可见人员、可见部门id、可见标签id,需要再根据可见部门id、可见标签id去查询该部门或者标签内所有的可见人员,这里做的是一个并集的操作。
根据部门id获取部门内成员的userid
根据标签id获取标签内成员的userid
/**
* 保存可见人员数据到im_cp_allow_user表
*
* @param
* @return
*/
private Set<String> addAllowUser(String corpId, JSONArray allowUserArray, JSONArray allowPartyArray, JSONArray allowTagArray) {
//1、可见人员集合(非部门和标签内的可见人员)
Set<String> allowUserSet = new HashSet<>();
if (allowUserArray.size() > 0) {
log.info("应用可见的人员allowUserArray==" + allowUserArray);
Object[] allowUserObject = allowUserArray.toArray();
for (int i = 0; i < allowUserObject.length; i++) {
String allowUser = (String) allowUserObject[i];
log.info("可见人员allowUser==" + allowUser);
allowUserSet.add(allowUser);
}
}
log.info("非部门和标签内的可见人员allowUserSet==" + allowUserSet);
//2、可见人员集合(部门内的可见人员)
Set<String> partysUserIdSet = new HashSet<>();
//遍历可见部门,获取可见部门成员
if (allowPartyArray.size() > 0) {
log.info("应用可见部门allowPartyArray==" + allowPartyArray);
Object[] allowPartyObject = allowPartyArray.toArray();
for (int i = 0; i < allowPartyObject.length; i++) {
//可见部门id
int allowPartyId = (int) allowPartyObject[i];
log.info("可见部门id,allowPartyId==" + allowPartyId);
//根据部门id获取该部门成员的userid的set集合
Set<String> partyUserIdSet = getPartyUserIdSet(corpId, allowPartyId);
log.info("partyUserIdSet==" + partyUserIdSet);
partysUserIdSet.addAll(partyUserIdSet);
}
}
log.info("部门内的可见人员集合partysUserIdSet==" + partysUserIdSet);
//3、可见人员集合(标签内的可见人员)
Set<String> tagsUserIdSet = new HashSet<>();
//遍历可见标签,获取可见标签成员
if (allowTagArray.size() > 0) {
log.info("应用可见标签allowTagArray==" + allowTagArray);
Object[] allowTagObject = allowTagArray.toArray();
for (int i = 0; i < allowTagObject.length; i++) {
//可见标签id
int allowTagId = (int) allowTagObject[i];
log.info("可见标签id,allowPartyId==" + allowTagId);
//根据标签id获取该标签内成员的userid的set集合
Set<String> tagUserIdSet = getTagUserIdSet(corpId, allowTagId);
log.info("tagUserIdSet==" + tagUserIdSet);
tagsUserIdSet.addAll(tagUserIdSet);
}
}
log.info("标签内的可见人员集合tagsUserIdSet==" + tagsUserIdSet);
//总的可见人员集合,包含allow_user、allow_tag、allow_party的可见人员
Set<String> allowUsersSet = new HashSet<>();
allowUsersSet.addAll(allowUserSet);
allowUsersSet.addAll(partysUserIdSet);
allowUsersSet.addAll(tagsUserIdSet);
log.info("总的可见人员集合allowUsersSet==" + allowUsersSet);
//CpAllowUser集合
List<CpAllowUser> cpAllowUserList = new ArrayList<>();
//遍历
for (String allowUserId : allowUsersSet) {
CpAllowUser cpAllowUser = new CpAllowUser()
.setCorpId(corpId).setAllowUserId(allowUserId);
cpAllowUserList.add(cpAllowUser);
}
log.info("CpAllowUser集合cpAllowUserList==" + cpAllowUserList);
//批量插入数据
cpAllowUserService.saveBatch(cpAllowUserList);
log.info("批量插入cpAllowUserList数据成功!");
return allowUsersSet;
}
5、添加默认的物料信息
文章、活动、微沙盘、默认项目
6、保存外部联系人信息
说明:1、外部联系人信息仅针对应用可见人员而言
2、可见人员必须拥有外部联系人权限,建议企业需要将所有置业顾问添加客户联系权限
可见人员必须拥有外部联系人权限在企业微信后台配置:
public Boolean savaExternalUserid(String corpId) {
log.info("开始添加外部联系人了!");
//1、获取配置了客户联系功能的成员列表
List<String> followUserList = getFollwUserList(corpId);
log.info("成员列表followUserList==" + followUserList);
if (followUserList == null) {
return false;
}
//2、遍历成员列表,获取客户列表
String extUserUrl = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list";
for (String userid : followUserList) {
List<CpExternalConcatUser> cpExternalConcatUserList = new ArrayList<>();
String extUserParam = "access_token=" + getAccessToken(corpId) + "&userid=" + userid;
String extUseGetData = HttpUtil.sendGet(extUserUrl, extUserParam);
log.error("extUseGetData===" + extUseGetData);
JSONObject jsonObject2 = JSONObject.parseObject(extUseGetData);
List<String> extUserList = JSONObject.parseArray(jsonObject2.getString("external_userid"), String.class);
log.error("extUserList===" + extUserList + "\tuserid===" + userid);
//如果该用户没有外部联系人,continue
if (extUserList.size() == 0 || extUserList == null) {
continue;
}
//3、遍历客户列表,获取客户详情
itratorExUserList(corpId, cpExternalConcatUserList, userid, extUserList);
log.info("外部联系人客户列表cpExternalConcatUserList==" + cpExternalConcatUserList);
//4、批量添加外部联系人客户
boolean addExternalUser = cpExternalConcatUserService.saveBatch(cpExternalConcatUserList);
log.info("批量添加外部联系人成功!");
if (!addExternalUser) {
log.error("添加cpExternalConcatUserList入库失败", new BusinessException("添加cpExternalConcatUserList入库失败"));
return false;
}
}
return true;
}
自此,企业授权回调结束。