Java企业微敬佩务商代开辟获取AccessToken示例

打印 上一主题 下一主题

主题 1782|帖子 1782|积分 5348

这里主要针对的是企业微敬佩务商代开辟模式 文档地点

可以看到内里大致有三种token,一个是服务商的token,一个是企业授权token,另有一个是应用的token
这内里主要有下面几个参数
首先是服务商的 corpid 和 provider_secret ,这个可以在 应用管理-通用开辟参数 内里查察

然后是企业的 corpid 和企业的永久授权码 permanent_code ,这两个是必要在企业授权的的时候通过回调获取的,具体请参考官方文档 获取永久授权码
最后就是应用的 suite_id 和 suite_secret 还必要一个 suite_ticket ,前面两个在应用信息内里就可以看到,suite_ticket 这个也是必要通过回调获取 ,具体参考官方文档 推送suite_ticket

拿到这些参数后就好说了,剩下的都是调接口
直接上代码
  1. import com.alibaba.fastjson.JSON;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.qyzj.common.base.exception.BusinessException;
  4. import com.qyzj.common.base.util.HttpsRequestUtil;
  5. import com.qyzj.common.redis.constant.CacheKey;
  6. import com.qyzj.common.redis.util.RedisUtil;
  7. import com.qyzj.service.task.constant.WeiXinProviderConst;
  8. import com.qyzj.service.task.constant.WeixinCorpKeyConst;
  9. import com.qyzj.service.task.constant.WeixinCorpUrlConst;
  10. import lombok.extern.java.Log;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.stereotype.Component;
  13. /**
  14. * @author Sakura
  15. * @date 2024/7/2 11:48
  16. */
  17. @Component
  18. @Log
  19. public class WxTokenUtil {
  20.     @Autowired
  21.     private RedisUtil redisUtil;
  22.     // 获取服务商token
  23.     // 这里有一个问题,企业微信本身可能会使token提前失效,所以有时需要强制重新获取token,详情见官方文档
  24.     // https://developer.work.weixin.qq.com/document/path/91200
  25.     // 所以此处加了一个cache用来判断是否需要走缓存拿token,正常情况默认走缓存即可
  26.     public String getProviderAccessToken(Boolean cache) {
  27.         try {
  28.             // 如果Redis里面有则直接取Redis里面的
  29.             if (cache &&redisUtil.hasKey(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN)) {
  30.                 return redisUtil.get(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN).toString();
  31.             }
  32.             // 封装请求参数
  33.             JSONObject json = new JSONObject();
  34.             json.put("corpid", WeiXinProviderConst.corpId);
  35.             json.put("provider_secret", WeiXinProviderConst.providerSecret);
  36.             // 请求微信接口
  37.             String accessTokenStr = HttpsRequestUtil.sendPostRequest(WeixinCorpUrlConst.PROVIDER_ACCESS_TOKEN, json.toJSONString());
  38.             log.info("get provider access token return :" + accessTokenStr);
  39.             JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);
  40.             // 获取 access_token
  41.             String accessToken = accessTokenJson.getString(WeixinCorpKeyConst.providerAccessToken);
  42.             //官方 expires_in 为 2个小时, 这里设置100分钟
  43.             redisUtil.set(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN, accessToken, CacheKey.expireTime100);
  44.             return accessToken;
  45.         } catch (Exception e) {
  46.             log.info("get provider access token error");
  47.             e.printStackTrace();
  48.             throw new BusinessException("get provider access token error");
  49.         }
  50.     }
  51.     // 获取企业授权token
  52.     public String getCorpAccessToken(String corpId, String permanentCode) {
  53.         try {
  54.             // 如果Redis里面有则直接取Redis里面的
  55.             if (redisUtil.hasKey(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId)) {
  56.                 return redisUtil.get(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId).toString();
  57.             }
  58.             String accessTokenUrl = WeixinCorpUrlConst.CORP_ACCESS_TOKEN
  59.                     .replace("#{CORP_ID}", corpId)
  60.                     .replace("#{CORP_SECRET}", permanentCode);
  61.             String accessTokenStr = HttpsRequestUtil.sendGetRequest(accessTokenUrl);
  62.             log.info("get corp access token return :" + accessTokenStr);
  63.             JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);
  64.             // 获取 access_token
  65.             String accessToken = accessTokenJson.getString(WeixinCorpKeyConst.accessToken);
  66.             //官方 expires_in 为 2个小时, 这里设置 100 分钟
  67.             redisUtil.set(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId, accessToken, CacheKey.expireTime100);
  68.             return accessToken;
  69.         } catch (Exception e) {
  70.             log.info("get corp access token error");
  71.             e.printStackTrace();
  72.             throw new BusinessException("get corp access token error");
  73.         }
  74.     }
  75.     // SuiteTicket是通过回调获取的,企微每10分钟会推送一次
  76.     // 如果没有可手动在服务商企业微信后台刷新
  77.     public String getSuiteTicket() {
  78.         // 如果Redis里面有则直接取Redis里面的
  79.         if (redisUtil.hasKey(CacheKey.KEY_CORP_SUITE_TICKET)) {
  80.             return redisUtil.get(CacheKey.KEY_CORP_SUITE_TICKET).toString();
  81.         } else {
  82.             log.info("get suite ticket error");
  83.             throw new BusinessException("get suite ticket error");
  84.         }
  85.     }
  86.     // 获取应用token
  87.     // 注意suiteTicket是从回调接口获取的
  88.     // 注意该token需要配置ip白名单
  89.     public String getSuiteAccessToken() {
  90.         try {
  91.             // 如果Redis里面有则直接取Redis里面的
  92.             if (redisUtil.hasKey(CacheKey.KEY_SUITE_ACCESS_TOKEN)) {
  93.                 return redisUtil.get(CacheKey.KEY_SUITE_ACCESS_TOKEN).toString();
  94.             }
  95.             // 封装请求参数
  96.             JSONObject json = new JSONObject();
  97.             json.put(WeixinCorpKeyConst.suiteId, WeiXinProviderConst.suiteId);
  98.             json.put(WeixinCorpKeyConst.suiteSecret, WeiXinProviderConst.suiteSecret);
  99.             json.put(WeixinCorpKeyConst.suiteTicket, getSuiteTicket());
  100.             String accessTokenStr = HttpsRequestUtil.sendPostRequest(WeixinCorpUrlConst.SUITE_ACCESS_TOKEN, json.toJSONString());
  101.             log.info("get suite access token return :" + accessTokenStr);
  102.             JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);
  103.             //获取 accessToken
  104.             String accessToken = accessTokenJson.getString(WeixinCorpKeyConst.suiteAccessToken);
  105.             //官方 expires_in 为 2个小时, 这里设置 100分钟
  106.             redisUtil.set(CacheKey.KEY_SUITE_ACCESS_TOKEN, accessToken, CacheKey.expireTime100);
  107.             return accessToken;
  108.         } catch (Exception e) {
  109.             log.info("get suite access token error");
  110.             e.printStackTrace();
  111.             throw new BusinessException("get suite access token error");
  112.         }
  113.     }
  114. }
复制代码
这内里用到的 HttpsRequestUtil 工具类
  1. import java.io.*;
  2. import java.net.HttpURLConnection;
  3. import java.net.URL;
  4. /**
  5. * @author Sakura
  6. * @date 2024/6/24 17:07
  7. */
  8. public class HttpsRequestUtil {
  9.     public static String sendPostRequest(String urlString, String jsonInputString) throws IOException {
  10.         URL url = new URL(urlString);
  11.         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  12.         // 设置请求方法为POST
  13.         connection.setRequestMethod("POST");
  14.         // 设置请求头
  15.         connection.setRequestProperty("Content-Type", "application/json");
  16.         connection.setRequestProperty("Accept", "application/json");
  17.         // 启用输出流,用于发送请求数据
  18.         connection.setDoOutput(true);
  19.         try (OutputStream os = connection.getOutputStream()) {
  20.             byte[] input = jsonInputString.getBytes("utf-8");
  21.             os.write(input, 0, input.length);
  22.         }
  23.         // 获取响应
  24.         try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {
  25.             StringBuilder response = new StringBuilder();
  26.             String responseLine;
  27.             while ((responseLine = br.readLine()) != null) {
  28.                 response.append(responseLine.trim());
  29.             }
  30.             return response.toString();
  31.         } finally {
  32.             // 关闭连接
  33.             connection.disconnect();
  34.         }
  35.     }
  36.     public static String sendGetRequest(String urlString) throws IOException {
  37.         URL url = new URL(urlString);
  38.         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  39.         // 设置请求方法为GET
  40.         connection.setRequestMethod("GET");
  41.         // 设置请求头
  42.         connection.setRequestProperty("Accept", "application/json");
  43.         // 获取响应
  44.         try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {
  45.             StringBuilder response = new StringBuilder();
  46.             String responseLine;
  47.             while ((responseLine = br.readLine()) != null) {
  48.                 response.append(responseLine.trim());
  49.             }
  50.             return response.toString();
  51.         } finally {
  52.             // 关闭连接
  53.             connection.disconnect();
  54.         }
  55.     }
  56. }
复制代码
另有企业微信的两个基本配置类
  1. public class WeixinCorpUrlConst {
  2.     /**
  3.      * 获取 provider_access_token 的 url
  4.      */
  5.     public static final String PROVIDER_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token";
  6.     /**
  7.      * 获取 suite_access_token 的 url
  8.      */
  9.     public static final String SUITE_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";
  10.     /**
  11.      * 获取 pre_auth_code 的 url
  12.      */
  13.     public static final String PRE_AUTH_CODE = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=";
  14.     /**
  15.      * 前端授权页面 的 url
  16.      */
  17.     public static final String URL_AUTH_PAGE = "https://open.work.weixin.qq.com/3rdapp/install";
  18.     /**
  19.      * 前端登录页面 的 url
  20.      */
  21.     public static final String URL_LOGIN_PAGE = "https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect";
  22.     /**
  23.      * 获取 permanent_code 的 url
  24.      */
  25.     public static final String PERMANENT_CODE = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=";
  26.     /**
  27.      * 获取 企业授权 access_token 的 url
  28.      */
  29.     public static final String CORP_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=#{CORP_ID}&corpsecret=#{CORP_SECRET}";
  30.     /**
  31.      * 获取 企业应用 access_token 的 url
  32.      */
  33.     public static final String ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
  34.     /**
  35.      * 获取 应用信息 的 url
  36.      */
  37.     public static final String AGENT_INFO = "https://qyapi.weixin.qq.com/cgi-bin/agent/get?access_token=#{ACCESS_TOKEN}&agentid=#{AGENT_ID}";
  38.     /**
  39.      * 获取 部门列表 的 url
  40.      */
  41.     public static final String DEPARTMENT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=#{ACCESS_TOKEN}";
  42.     /**
  43.      * 获取 部门成员列表 的 url
  44.      */
  45.     public static final String USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=#{ACCESS_TOKEN}&department_id=#{DEPARTMENT_ID}&fetch_child=1";
  46.     /**
  47.      * 获取 成员信息 的 url
  48.      */
  49.     public static final String USER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=#{ACCESS_TOKEN}&userid=#{USER_ID}";
  50.     /**
  51.      * 获取 企业管理员 的 url
  52.      */
  53.     public static final String ADMIN_USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/service/get_admin_list?suite_access_token=";
  54.     /**
  55.      * 第三方应用:获取 企业成员登录信息 的 url
  56.      */
  57.     public static final String PROVIDER_LOGIN_INFO = "https://qyapi.weixin.qq.com/cgi-bin/service/get_login_info?access_token=";
  58.     /**
  59.      * 自建应用:获取 企业成员登录信息 的 url
  60.      */
  61.     public static final String LOCAL_LOGIN_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=#{ACCESS_TOKEN}&code=#{CODE}";
  62.     public static final String LOGIN_DETAIL_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=#{ACCESS_TOKEN}";
  63.     /**
  64.      * 批量获取 客户列表 的 url
  65.      */
  66.     public static final String BATCH_CUSTOMER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=#{ACCESS_TOKEN}";
  67.     /**
  68.      * 获取 客户详情 的 url
  69.      */
  70.     public static final String CUSTOMER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=#{ACCESS_TOKEN}&external_userid=#{EXTERNAL_USERID}";
  71.     /**
  72.      * 修改 客户备注信息 的url
  73.      */
  74.     public static final String UPDATE_CUSTOMER_REMARK = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark?access_token=#{ACCESS_TOKEN}";
  75.     /**
  76.      * 编辑 客户标签 的url
  77.      */
  78.     public static final String MARK_CUSTOMER_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=#{ACCESS_TOKEN}";
  79.     /**
  80.      * 获取 企业标签 的 url
  81.      */
  82.     public static final String TAG_GROUP_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=";
  83.     /**
  84.      * 添加 企业标签 的 url
  85.      */
  86.     public static final String ADD_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token=";
  87.     /**
  88.      * 修改 企业标签 的 url
  89.      */
  90.     public static final String UPDATE_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?access_token=";
  91.     /**
  92.      * 删除 企业标签 的 url
  93.      */
  94.     public static final String DELETE_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token=";
  95.     /**
  96.      * 获取 客户群列表 的 url
  97.      */
  98.     public static final String GROUP_CHAT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=#{ACCESS_TOKEN}";
  99.     /**
  100.      * 获取 客户群详情 的 url
  101.      */
  102.     public static final String GROUP_CHAT_INFO = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=#{ACCESS_TOKEN}";
  103.     /**
  104.      * 查询 联系我 的 url
  105.      */
  106.     public static final String GET_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=#{ACCESS_TOKEN}";
  107.     /**
  108.      * 添加 联系我 的 url
  109.      */
  110.     public static final String ADD_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=#{ACCESS_TOKEN}";
  111.     /**
  112.      * 更新 联系我 的 url
  113.      */
  114.     public static final String UPDATE_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=#{ACCESS_TOKEN}";
  115.     /**
  116.      * 删除 联系我 的 url
  117.      */
  118.     public static final String DEL_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=#{ACCESS_TOKEN}";
  119.     /**
  120.      * 发送 欢迎语  的 url
  121.      */
  122.     public static final String SEND_WELCOME_MSG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=#{ACCESS_TOKEN}";
  123.     /**
  124.      * 上传 临时素材 的 url
  125.      */
  126.     public static final String UPLOAD_MEDIA = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=";
  127.     /**
  128.      * 添加 入群欢迎语素材  的 url
  129.      */
  130.     public static final String ADD_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=#{ACCESS_TOKEN}";
  131.     /**
  132.      * 更新 入群欢迎语素材  的 url
  133.      */
  134.     public static final String UPDATE_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=#{ACCESS_TOKEN}";
  135.     /**
  136.      * 删除 入群欢迎语素材  的 url
  137.      */
  138.     public static final String DEL_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=#{ACCESS_TOKEN}";
  139.     /**
  140.      * 发送 应用消息  的 url
  141.      */
  142.     public static final String SEND_APPLICATION_MESSAGE = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=#{ACCESS_TOKEN}";
  143.     /**
  144.      * 获取待分配的离职成员列表 的url
  145.      */
  146.     public static final String DIMISSION_WAIT_ALLOT_CLIENT = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_unassigned_list?access_token=#{ACCESS_TOKEN}";
  147.     /**
  148.      * 分配离职成员的客户
  149.      */
  150.     public static final String DIMISSION_ALLOT_Client = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_customer?access_token=#{ACCESS_TOKEN}";
  151.     /**
  152.      *  分配离职成员的客户群
  153.      */
  154.     public static final String DIMISSION_ALLOT_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/transfer?access_token=#{ACCESS_TOKEN}";
  155.     /**
  156.      * 创建企业群发
  157.      */
  158.     public static final String ADD_CORP_MASS_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=#{ACCESS_TOKEN}";
  159.     /**
  160.      * 编辑客户企业标签
  161.      */
  162.     public static final String EDIT_CUSTOMER_CORP_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=#{ACCESS_TOKEN}";
  163.     /**
  164.      * 获取企业的jsapi_ticket
  165.      */
  166.     public static final String CORP_JS_API_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=";
  167.     /**
  168.      * 获取应用的jsapi_ticket
  169.      */
  170.     public static final String AGENT_JS_API_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?type=agent_config&access_token=";
  171.     /**
  172.      * 获取 开通了会话存档的员工
  173.      */
  174.     public static final String MSG_AUDIT_EMPLOYEE = "https://qyapi.weixin.qq.com/cgi-bin/msgaudit/get_permit_user_list?access_token=#{ACCESS_TOKEN}";
  175.     /**
  176.      * corpid转换 的 url
  177.      */
  178.     public static final String CORPID_TO_OPENCORPID = "https://qyapi.weixin.qq.com/cgi-bin/service/corpid_to_opencorpid?provider_access_token=";
  179.     /**
  180.      * userid转换 的 url
  181.      */
  182.     public static final String USERID_TO_OPENUSERID = "https://qyapi.weixin.qq.com/cgi-bin/batch/userid_to_openuserid?access_token=";
  183.     public static final String GET_NEW_EXTERNAL_USERID = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_new_external_userid?access_token=";
  184.     public static final String UNIONID_TO_EXTERNAL_USERID = "https://qyapi.weixin.qq.com/cgi-bin/idconvert/unionid_to_external_userid?access_token=";
  185.     public static final String EXTERNAL_USERID_TO_PENDING_ID = "https://qyapi.weixin.qq.com/cgi-bin/idconvert/batch/external_userid_to_pending_id?access_token=";
  186.     public static final String FINISH_OPENID_MIGRATION = "https://qyapi.weixin.qq.com/cgi-bin/service/finish_openid_migration?provider_access_token=";
  187. }
复制代码
  1. public class WeixinCorpKeyConst {
  2.     public static String errcode = "errcode";
  3.     public static String errmsg = "errmsg";
  4.     // 服务商相关
  5.     public static String corpId = "corpid";
  6.     public static String authCorpId = "auth_corpid";
  7.     public static String corpName = "corp_name";
  8.     public static String suiteId = "suite_id";
  9.     public static String suiteSecret = "suite_secret";
  10.     public static String providerSecret = "provider_secret";
  11.     public static String corpSecret = "corpsecret";
  12.     public static String suiteTicket = "suite_ticket";
  13.     public static String suiteAccessToken = "suite_access_token";
  14.     public static String providerAccessToken = "provider_access_token";
  15.     public static String preAuthCode = "pre_auth_code";
  16.     public static String authCode = "auth_code";
  17.     public static String permanentCode = "permanent_code";
  18.     public static String authCorpInfo = "auth_corp_info";
  19.     public static String authInfo = "auth_info";
  20.     public static String agent = "agent";
  21.     public static String agentId = "agentid";
  22.     public static String accessToken = "access_token";
  23. }
复制代码
WeiXinProviderConst 就不贴了,内里就是记载上面那几个参数的
到这里可以发现,其实对接企业微信并不难,麻烦的地方就在于各种配置各种参数,然后就是回调,回调这个反面有空我也会整理出来

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

祗疼妳一个

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表