企业微信开发(2)——授权安装应用回调

简介: 前提:第三方服务商已注册并安装第三方应用,并且在第三方应用已经配置回调,且第三方的回调服务地址可用。本节介绍应用授权安装后回调逻辑,变更应用可见性回调逻辑,外部联系人回调逻辑,

本文同步自我的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;

    }

自此,企业授权回调结束。

目录
相关文章
|
2月前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
3月前
|
小程序 JavaScript API
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
这篇文章介绍了使用uni-halo框架进行微信小程序开发的过程,包括选择该框架的原因、开发目标以及项目配置和部署的步骤。
127 0
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
|
9月前
|
自然语言处理 搜索推荐 小程序
微信公众号接口:解锁公众号开发的无限可能
微信公众号接口是微信官方提供的API,支持开发者通过编程与公众号交互,实现自动回复、消息管理、用户管理和数据分析等功能。本文深入探讨接口的定义、类型、优势及应用场景,如智能客服、内容分发、电商闭环等,并介绍开发流程和工具,帮助运营者提升用户体验和效率。未来,随着微信生态的发展,公众号接口将带来更多机遇,如小程序融合、AI应用等。
|
6月前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
1255 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
|
5月前
|
监控 数据可视化 数据处理
微信养号脚本,全自动插件,AUTOJS开发版
这是一套自动化微信养号工具,包含主脚本`wechat_auto.js`与配置文件`config.json`。主脚本实现自动浏览朋友圈、随机阅读订阅号文章及搜索指定公众号三大功能,支持自定义滚动次数、阅读时长等参数。代码通过随机化操作间隔模拟真实用户行为,具备完善的错误处理和日志记录功能。配套UI模块提供可视化操作界面,可实时监控任务状态与运行日志,便于调整参数设置。控制器部分扩展了批量数据处理能力,如学生信息的增删改查操作,适用于多场景应用。下载地址:https://www.pan38.com/share.php?code=n6cPZ 提取码:8888(仅供学习参考)。
|
8月前
|
人工智能 自然语言处理 小程序
技术小白如何利用DeepSeek半小时开发微信小程序?
通过通义灵码的“AI程序员”功能,即使没有编程基础也能轻松创建小程序或网页。借助DeepSeek V3和R1满血版模型,用户只需用自然语言描述需求,就能自动生成代码并优化程序。例如,一个文科生仅通过描述需求就成功开发了一款记录日常活动的微信小程序。此外,通义灵码还提供智能问答模式,帮助用户解决开发中的各种问题,极大简化了开发流程,让普通人的开发体验更加顺畅。
2181 11
技术小白如何利用DeepSeek半小时开发微信小程序?
|
7月前
|
小程序 Java 关系型数据库
weixin163基于微信小程序的校园二手交易平台系统设计与开发ssm(文档+源码)_kaic
本文介绍了一款基于微信小程序的校园二手物品交易平台的开发与实现。该平台采用Java语言开发服务端,使用MySQL数据库进行数据存储,前端以微信小程序为载体,支持管理员和学生两种角色操作。管理员可管理用户、商品分类及信息、交易记录等,而学生则能注册登录、发布购买商品、参与交流论坛等。系统设计注重交互性和安全性,通过SSM框架优化开发流程,确保高效稳定运行,满足用户便捷交易的需求,推动校园资源共享与循环利用。
|
7月前
|
小程序 关系型数据库 Java
weixin168“返家乡”高校暑期社会实践微信小程序设计与开发ssm(文档+源码)_kaic
本文探讨高校暑期社会实践微信小程序的开发与应用,旨在通过信息化手段提升活动管理效率。借助微信小程序技术、SSM框架及MySQL数据库,实现信息共享、流程规范和操作便捷。系统涵盖需求分析、可行性研究、设计实现等环节,确保技术可行、操作简便且经济合理。最终,该小程序可优化活动发布、学生信息管理和心得交流等功能,降低管理成本并提高工作效率。
|
8月前
|
小程序 JavaScript 前端开发
微信小程序开发全流程:从注册到上线的完整指南
这篇文章详细记录了微信小程序的完整开发到最终上线的每一个步骤。适合对小程序开发感兴趣的个人开发者或希望了解完整流程的学习者,涵盖了云开发、事件绑定、生命周期管理、组件使用等关键内容。
2704 11
|
9月前
|
JSON 缓存 小程序
微信小程序组件封装与复用:提升开发效率
本文深入探讨了微信小程序的组件封装与复用,涵盖组件的意义、创建步骤、属性与事件处理,并通过自定义弹窗组件的案例详细说明。组件封装能提高代码复用性、开发效率和可维护性,确保UI一致性。掌握这些技能有助于构建更高质量的小程序。

热门文章

最新文章

下一篇
开通oss服务