diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxTpCustomizedAuthUrl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxTpCustomizedAuthUrl.java
new file mode 100644
index 000000000..5edf2b736
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxTpCustomizedAuthUrl.java
@@ -0,0 +1,40 @@
+package me.chanjar.weixin.cp.bean;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * @author freedom
+ * @date 2022/10/20 16:36
+ */
+@Data
+public class WxTpCustomizedAuthUrl extends WxCpBaseResp {
+
+ /**
+ * 可用来生成二维码的授权url,需要开发者自行生成为二维码
+ */
+ @SerializedName("qrcode_url")
+ private String qrCodeURL;
+
+ /**
+ * 有效期(秒)。10天过期。
+ */
+ @SerializedName("expires_in")
+ private Integer expiresIn;
+
+ /**
+ * From json wx cp tp customized auth url.
+ *
+ * @param json the json
+ * @return the wx cp tp customized auth url
+ */
+ public static WxTpCustomizedAuthUrl fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxTpCustomizedAuthUrl.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
index 1c549e2b4..1ee843c66 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
@@ -781,6 +781,11 @@ public interface WxCpApiPathConsts {
*/
String GET_LOGIN_INFO = "/cgi-bin/service/get_login_info";
+ /**
+ * The constant GET_CUSTOMIZED_AUTH_URL.
+ */
+ String GET_CUSTOMIZED_AUTH_URL = "/cgi-bin/service/get_customized_auth_url";
+
/**
* The constant CONTACT_SEARCH.
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java
index 838e5e43d..ecb7084c7 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java
@@ -10,6 +10,10 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.cp.bean.*;
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
/**
* 企业微信第三方应用API的Service.
*
@@ -389,6 +393,18 @@ public interface WxCpTpService {
*/
WxTpLoginInfo getLoginInfo(String authCode) throws WxErrorException;
+ /**
+ * 获取带参授权链接
+ *
+ * 文档地址:https://developer.work.weixin.qq.com/document/path/95436
+ *
+ * @param state state
+ * @param templateIdList 代开发自建应用模版ID列表,数量不能超过9个
+ * @return customized auth url
+ * @throws WxErrorException the wx error exception
+ */
+ WxTpCustomizedAuthUrl getCustomizedAuthUrl(@NotBlank String state, @NotEmpty List templateIdList) throws WxErrorException;
+
/**
* 获取服务商providerToken
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java
index e3e95a3e8..c089cb3e2 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java
@@ -22,15 +22,19 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.common.util.json.GsonParser;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.cp.bean.*;
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
import me.chanjar.weixin.cp.tp.service.*;
import org.apache.commons.lang3.StringUtils;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tp.*;
@@ -534,6 +538,16 @@ public abstract class BaseWxCpTpServiceImpl implements WxCpTpService, Requ
return WxTpLoginInfo.fromJson(responseText);
}
+ @Override
+ public WxTpCustomizedAuthUrl getCustomizedAuthUrl(@NotBlank String state, @NotEmpty List templateIdList) throws WxErrorException {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("state", state);
+ jsonObject.add("templateid_list", WxGsonBuilder.create().toJsonTree(templateIdList).getAsJsonArray());
+
+ String responseText = post(configStorage.getApiUrl(GET_CUSTOMIZED_AUTH_URL) + "?provider_access_token=" + getWxCpProviderToken(), jsonObject.toString(), true);
+ return WxTpCustomizedAuthUrl.fromJson(responseText);
+ }
+
@Override
public String getWxCpProviderToken() throws WxErrorException {
if (this.configStorage.isProviderTokenExpired()) {
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImplTest.java
index edb284f25..8235e48f9 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImplTest.java
@@ -2,16 +2,27 @@ package me.chanjar.weixin.cp.tp.service.impl;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
import me.chanjar.weixin.cp.bean.WxCpTpAuthInfo;
import me.chanjar.weixin.cp.bean.WxCpTpCorp;
import me.chanjar.weixin.cp.bean.WxCpTpPermanentCodeInfo;
+import me.chanjar.weixin.cp.bean.WxTpCustomizedAuthUrl;
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.cp.config.impl.WxCpTpDefaultConfigImpl;
+import me.chanjar.weixin.cp.config.impl.WxCpTpRedissonConfigImpl;
import me.chanjar.weixin.cp.tp.service.WxCpTpService;
+import org.apache.http.util.Asserts;
import org.mockito.Mockito;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -27,6 +38,55 @@ import static org.assertj.core.api.Assertions.assertThat;
public class BaseWxCpTpServiceImplTest {
private final WxCpTpService tpService = Mockito.spy(new WxCpTpServiceApacheHttpClientImpl());
+ /**
+ * The constant PROVIDER_CORP_ID.
+ */
+ public static final String PROVIDER_CORP_ID = "xxxxxx";
+ /**
+ * The constant PROVIDER_SECRET.
+ */
+ public static final String PROVIDER_SECRET = "xxxxxx";
+ /**
+ * The constant REDIS_ADDR.
+ */
+ public static final String REDIS_ADDR = "redis://xxx.xxx.xxx.xxx:6379";
+ /**
+ * The constant REDIS_PASSWD.
+ */
+ public static final String REDIS_PASSWD = "xxxxxx";
+
+ private WxCpTpService wxCpTpService;
+
+ /**
+ * Sets up.
+ */
+ @BeforeMethod
+ public void setUp() {
+ wxCpTpService = new WxCpTpServiceApacheHttpClientImpl();
+ wxCpTpService.setWxCpTpConfigStorage(wxCpTpConfigStorage());
+ }
+
+ /**
+ * Wx cp tp config storage wx cp tp config storage.
+ *
+ * @return the wx cp tp config storage
+ */
+ public WxCpTpConfigStorage wxCpTpConfigStorage() {
+ return WxCpTpRedissonConfigImpl.builder().corpId(PROVIDER_CORP_ID).providerSecret(PROVIDER_SECRET).wxRedisOps(new RedissonWxRedisOps(redissonClient())).build();
+ }
+
+ /**
+ * Redisson client redisson client.
+ *
+ * @return the redisson client
+ */
+ public RedissonClient redissonClient() {
+ Config config = new Config();
+ config.useSingleServer().setAddress(REDIS_ADDR).setConnectTimeout(10 * 1000).setDatabase(6)
+ .setPassword(REDIS_PASSWD).setConnectionMinimumIdleSize(2).setConnectionPoolSize(2);
+ return Redisson.create(config);
+ }
+
/**
* Test check signature.
*/
@@ -444,4 +504,14 @@ public class BaseWxCpTpServiceImplTest {
@Test
public void testGetRequestHttp() {
}
+
+ @Test
+ public void testGetCustomizedAuthUrl() throws WxErrorException {
+ String state = "test";
+ List templateIdList = Arrays.asList("");
+
+ final WxTpCustomizedAuthUrl customizedAuthUrl = wxCpTpService.getCustomizedAuthUrl(state, templateIdList);
+ Assert.assertNotNull(customizedAuthUrl);
+ Assert.assertEquals((long) customizedAuthUrl.getErrcode(), 0);
+ }
}