主要新增了企业号的第三方应用API
This commit is contained in:
@@ -8,7 +8,6 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.model.Button;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.api.AgentApi;
|
||||
import com.foxinmy.weixin4j.qy.api.BatchApi;
|
||||
import com.foxinmy.weixin4j.qy.api.HelperApi;
|
||||
@@ -16,6 +15,7 @@ import com.foxinmy.weixin4j.qy.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.qy.api.MenuApi;
|
||||
import com.foxinmy.weixin4j.qy.api.NotifyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.PartyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.QyApi;
|
||||
import com.foxinmy.weixin4j.qy.api.TagApi;
|
||||
import com.foxinmy.weixin4j.qy.api.UserApi;
|
||||
import com.foxinmy.weixin4j.qy.message.NotifyMessage;
|
||||
@@ -31,11 +31,9 @@ import com.foxinmy.weixin4j.qy.model.User;
|
||||
import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
|
||||
import com.foxinmy.weixin4j.qy.type.InviteType;
|
||||
import com.foxinmy.weixin4j.qy.type.UserStatus;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信企业号接口实现
|
||||
@@ -47,6 +45,7 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php">api文档</a>
|
||||
*/
|
||||
public class WeixinProxy {
|
||||
|
||||
private final MediaApi mediaApi;
|
||||
private final MenuApi menuApi;
|
||||
private final NotifyApi notifyApi;
|
||||
@@ -57,20 +56,24 @@ public class WeixinProxy {
|
||||
private final AgentApi agentApi;
|
||||
private final BatchApi batchApi;
|
||||
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
/**
|
||||
* 默认使用文件方式保存token、使用weixin4j.properties配置的账号信息
|
||||
*/
|
||||
public WeixinProxy() {
|
||||
this(new FileTokenStorager());
|
||||
this(QyApi.DEFAULT_TOKEN_STORAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置的账号信息
|
||||
*
|
||||
* @param tokenStorager token存储策略
|
||||
* @param tokenStorager
|
||||
* token存储策略
|
||||
*/
|
||||
public WeixinProxy(TokenStorager tokenStorager) {
|
||||
this(tokenStorager, ConfigUtil.getWeixinAccount());
|
||||
this(QyApi.DEFAULT_WEIXIN_ACCOUNT.getId(), QyApi.DEFAULT_WEIXIN_ACCOUNT
|
||||
.getSecret(), tokenStorager);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,19 +83,22 @@ public class WeixinProxy {
|
||||
* @param corpsecret
|
||||
*/
|
||||
public WeixinProxy(String corpid, String corpsecret) {
|
||||
this(new FileTokenStorager(), new WeixinAccount(corpid, corpsecret));
|
||||
this(corpid, corpsecret, QyApi.DEFAULT_TOKEN_STORAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param corpid
|
||||
* 企业号ID
|
||||
* @param corpsecret
|
||||
* 企业号secret
|
||||
* @param tokenStorager
|
||||
* token存储策略
|
||||
* @param weixinAccount
|
||||
* 企业号账号信息
|
||||
* 企业号token存储器
|
||||
*/
|
||||
public WeixinProxy(TokenStorager tokenStorager, WeixinAccount weixinAccount) {
|
||||
TokenHolder tokenHolder = new TokenHolder(new WeixinTokenCreator(
|
||||
weixinAccount), tokenStorager);
|
||||
public WeixinProxy(String corpid, String corpsecret,
|
||||
TokenStorager tokenStorager) {
|
||||
this.tokenHolder = new TokenHolder(new WeixinTokenCreator(corpid,
|
||||
corpsecret), tokenStorager);
|
||||
this.partyApi = new PartyApi(tokenHolder);
|
||||
this.userApi = new UserApi(tokenHolder);
|
||||
this.tagApi = new TagApi(tokenHolder);
|
||||
@@ -104,6 +110,10 @@ public class WeixinProxy {
|
||||
this.mediaApi = new MediaApi(tokenHolder);
|
||||
}
|
||||
|
||||
public TokenHolder getTokenHolder() {
|
||||
return this.tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息(需要管理员对应用有使用权限,对收件人touser、toparty、totag有查看权限,否则本次调用失败)
|
||||
* <p>
|
||||
|
||||
@@ -10,11 +10,6 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.qy.model.Corpinfo;
|
||||
import com.foxinmy.weixin4j.qy.model.OUserInfo;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.qy.token.WeixinProviderTokenCreator;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
@@ -26,63 +21,26 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">企业号登录授权说明</a>
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%88%E6%9D%83">第三方应用授权说明</a>
|
||||
*/
|
||||
public class OauthApi extends QyApi {
|
||||
|
||||
private final TokenHolder providerTokenHolder;
|
||||
|
||||
/**
|
||||
* 默认使用文件方式保存token、使用weixin4j.properties配置的账号信息
|
||||
*/
|
||||
public OauthApi() {
|
||||
this(new FileTokenStorager());
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认使用weixin4j.properties配置的账号信息
|
||||
* 企业号登陆授权
|
||||
*
|
||||
* @param tokenStorager
|
||||
*/
|
||||
public OauthApi(TokenStorager tokenStorager) {
|
||||
this(tokenStorager, JSON.parseObject(ConfigUtil.getValue("account"),
|
||||
WeixinQyAccount.class));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param appid
|
||||
* @param appsecret
|
||||
*/
|
||||
public OauthApi(String corpid, String providerSecret) {
|
||||
providerTokenHolder = new TokenHolder(new WeixinProviderTokenCreator(
|
||||
corpid, providerSecret), new FileTokenStorager());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tokenStorager
|
||||
* token存储策略
|
||||
* @param weixinAccount
|
||||
* 公众号账号信息
|
||||
*/
|
||||
public OauthApi(TokenStorager tokenStorager, WeixinQyAccount qyAccount) {
|
||||
providerTokenHolder = new TokenHolder(new WeixinProviderTokenCreator(
|
||||
qyAccount), tokenStorager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link com.foxinmy.weixin4j.qy.api.OauthApi#getAuthorizeURL(String, String,String)}
|
||||
*
|
||||
* @return 请求授权的URL
|
||||
*/
|
||||
public String getAuthorizeURL() {
|
||||
String corpId = ConfigUtil.getWeixinAccount().getId();
|
||||
String corpId = DEFAULT_WEIXIN_ACCOUNT.getId();
|
||||
String redirectUri = ConfigUtil.getValue("redirect_uri");
|
||||
return getAuthorizeURL(corpId, redirectUri, "state");
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth授权
|
||||
* 企业号登陆授权
|
||||
*
|
||||
* @param corpId
|
||||
* 企业号(提供商)的corpid
|
||||
@@ -91,6 +49,8 @@ public class OauthApi extends QyApi {
|
||||
* @param state
|
||||
* 用于保持请求和回调的状态,授权请求后原样带回给第三方
|
||||
* @return 请求授权的URL
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">企业号登陆授权</a>
|
||||
*/
|
||||
public String getAuthorizeURL(String corpId, String redirectUri,
|
||||
String state) {
|
||||
@@ -107,6 +67,8 @@ public class OauthApi extends QyApi {
|
||||
/**
|
||||
* 获取企业号管理员登录信息
|
||||
*
|
||||
* @param providerToken
|
||||
* 提供商的token
|
||||
* @param authCode
|
||||
* oauth2.0授权企业号管理员登录产生的code
|
||||
* @return 登陆信息
|
||||
@@ -115,12 +77,12 @@ public class OauthApi extends QyApi {
|
||||
* @see com.foxinmy.weixin4j.qy.model.OUserInfo
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public OUserInfo getOUserInfo(String authCode) throws WeixinException {
|
||||
public OUserInfo getOUserInfo(String providerToken, String authCode)
|
||||
throws WeixinException {
|
||||
String oauth_logininfo_uri = getRequestUri("oauth_logininfo_uri");
|
||||
WeixinResponse response = weixinClient.post(String.format(
|
||||
oauth_logininfo_uri, providerTokenHolder.getToken()
|
||||
.getAccessToken()), String.format(
|
||||
"{\"auth_code\":\"%s\"}", authCode));
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(oauth_logininfo_uri, providerToken),
|
||||
String.format("{\"auth_code\":\"%s\"}", authCode));
|
||||
return JSON.parseObject(response.getAsString(), OUserInfo.class,
|
||||
new ExtraProcessor() {
|
||||
|
||||
@@ -142,4 +104,44 @@ public class OauthApi extends QyApi {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link com.foxinmy.weixin4j.qy.api.OauthApi#getSuiteAuthorizeURL(String,String, String,String)}
|
||||
* @param preAuthCode
|
||||
* 预授权码
|
||||
* @return
|
||||
*/
|
||||
public String getSuiteAuthorizeURL(String preAuthCode) {
|
||||
String suiteId = DEFAULT_WEIXIN_ACCOUNT.getSuiteId();
|
||||
String redirectUri = ConfigUtil.getValue("suite_redirect_uri");
|
||||
return getSuiteAuthorizeURL(suiteId, preAuthCode, redirectUri, "state");
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用套件授权
|
||||
*
|
||||
* @param suiteId
|
||||
* 套件ID
|
||||
* @param preAuthCode
|
||||
* 预授权码
|
||||
* @param redirectUri
|
||||
* 授权后重定向url
|
||||
* @param state
|
||||
* 回调后原样返回
|
||||
* @return 请求授权的URL <a
|
||||
* href=""http://qydev.weixin.qq.com/wiki/index.php?title
|
||||
* =%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%AE%A1%E7%90%86%E5%91%98%E6%
|
||||
* 8E%88%E6%9D%83%E5%BA%94%E7%94%A8>应用套件授权</a>
|
||||
*/
|
||||
public String getSuiteAuthorizeURL(String suiteId, String preAuthCode,
|
||||
String redirectUri, String state) {
|
||||
String suite_oauth_uri = getRequestUri("suite_oauth_uri");
|
||||
try {
|
||||
return String.format(suite_oauth_uri, suiteId, preAuthCode,
|
||||
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,12 @@ package com.foxinmy.weixin4j.qy.api;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.api.BaseApi;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.qy.suite.FileTicketProcessor;
|
||||
import com.foxinmy.weixin4j.qy.suite.SuiteTicketProcessor;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信企业号API
|
||||
@@ -15,14 +20,27 @@ import com.foxinmy.weixin4j.api.BaseApi;
|
||||
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php">api文档</a>
|
||||
*/
|
||||
public class QyApi extends BaseApi {
|
||||
private final static ResourceBundle weixinBundle;
|
||||
|
||||
private final static ResourceBundle WEIXIN_BUNDLE;
|
||||
/**
|
||||
* 默认使用weixin4j.properties文件中的企业号信息
|
||||
*/
|
||||
public final static WeixinQyAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||
/**
|
||||
* 默认使用File的方法读取套件ticket
|
||||
*/
|
||||
public final static SuiteTicketProcessor DEFAULT_TICKET_PROCESSOR;
|
||||
|
||||
static {
|
||||
weixinBundle = ResourceBundle
|
||||
WEIXIN_BUNDLE = ResourceBundle
|
||||
.getBundle("com/foxinmy/weixin4j/qy/api/weixin");
|
||||
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
|
||||
ConfigUtil.getValue("account"), WeixinQyAccount.class);
|
||||
DEFAULT_TICKET_PROCESSOR = new FileTicketProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getWeixinBundle() {
|
||||
return weixinBundle;
|
||||
protected String getConfigValue(String key) {
|
||||
return WEIXIN_BUNDLE.getString(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.foxinmy.weixin4j.qy.api;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.qy.suite.SuiteTicketProcessor;
|
||||
import com.foxinmy.weixin4j.qy.suite.WeixinSuitePreCodeCreator;
|
||||
import com.foxinmy.weixin4j.qy.suite.WeixinSuiteTokenCreator;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
|
||||
/**
|
||||
* 第三方应用套件
|
||||
*
|
||||
* @className SuiteApi
|
||||
* @author jy
|
||||
* @date 2015年6月17日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%88%E6%9D%83">第三方应用授权</a>
|
||||
*/
|
||||
public class SuiteApi extends QyApi {
|
||||
|
||||
/**
|
||||
* 应用套件token
|
||||
*/
|
||||
private final TokenHolder suiteTokenHolder;
|
||||
private final TokenHolder suiteTicketHolder;
|
||||
|
||||
public SuiteApi() throws WeixinException {
|
||||
this(DEFAULT_WEIXIN_ACCOUNT.getSuiteId(), DEFAULT_WEIXIN_ACCOUNT
|
||||
.getSuiteSecret());
|
||||
}
|
||||
|
||||
public SuiteApi(String suiteId, String suiteSecret) throws WeixinException {
|
||||
this(suiteId, suiteSecret, DEFAULT_TICKET_PROCESSOR,
|
||||
DEFAULT_TOKEN_STORAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param suiteId
|
||||
* 应用ID
|
||||
* @param suiteSecret
|
||||
* 应用secret
|
||||
* @param ticketReader
|
||||
* 应用ticket读取器
|
||||
* @param tokenStorager
|
||||
* 应用token存储器
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public SuiteApi(String suiteId, String suiteSecret,
|
||||
SuiteTicketProcessor ticketReader, TokenStorager tokenStorager)
|
||||
throws WeixinException {
|
||||
this.suiteTokenHolder = new TokenHolder(new WeixinSuiteTokenCreator(
|
||||
suiteId, suiteSecret, ticketReader), tokenStorager);
|
||||
this.suiteTicketHolder = new TokenHolder(new WeixinSuitePreCodeCreator(
|
||||
suiteTokenHolder, suiteId), tokenStorager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用套件token
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TokenHolder getTokenHolder() {
|
||||
return this.suiteTokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用套件ticket
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TokenHolder getTicketHolder() {
|
||||
return this.suiteTicketHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置套件授权配置:如果需要对某次授权进行配置,则调用本接口,目前仅可以设置哪些应用可以授权,不调用则默认允许所有应用进行授权。
|
||||
*
|
||||
* @param appids
|
||||
* 允许进行授权的应用id,如1、2、3
|
||||
* @return 处理结果
|
||||
* @throws WeixinException
|
||||
* <a href=
|
||||
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.AE.BE.E7.BD.AE.E6.8E.88.E6.9D.83.E9.85.8D.E7.BD.AE"
|
||||
* >设置套件授权配置</a>
|
||||
*/
|
||||
public JsonResult setSuiteSession(int... appids) throws WeixinException {
|
||||
String suite_set_session_uri = getRequestUri("suite_set_session_uri");
|
||||
JSONObject para = new JSONObject();
|
||||
para.put("pre_auth_code", suiteTicketHolder.getAccessToken());
|
||||
para.put("session_info", appids);
|
||||
WeixinResponse response = weixinClient
|
||||
.post(String.format(suite_set_session_uri,
|
||||
suiteTokenHolder.getAccessToken()), para.toJSONString());
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
@@ -83,4 +83,10 @@ batch_getresult_uri={api_base_url}/batch/getresult?access_token=%s&jobid=%s
|
||||
# \u63d0\u4f9b\u5546oauth\u6388\u6743
|
||||
provider_oauth_uri=https://qy.weixin.qq.com/cgi-bin/loginpage?corp_id=%s&redirect_uri=%s&state=%s
|
||||
# \u4f01\u4e1a\u53f7\u7ba1\u7406\u5458\u767b\u5f55\u4fe1\u606f
|
||||
oauth_logininfo_uri={api_base_url}/service/get_login_info?provider_access_token=%s
|
||||
oauth_logininfo_uri={api_base_url}/service/get_login_info?provider_access_token=%s
|
||||
# \u5e94\u7528\u5957\u4ef6oauth\u6388\u6743
|
||||
suite_oauth_uri=https://qy.weixin.qq.com/cgi-bin/loginpage?suite_id=%s&pre_auth_code=%s&redirect_uri=%s&state=%s
|
||||
# \u5e94\u7528\u5957\u4ef6\u8bbe\u7f6e\u6388\u6743\u914d\u7f6e
|
||||
suite_set_session_uri={api_base_url}/service/set_session_info?suite_access_token=%s
|
||||
# \u83b7\u53d6\u4f01\u4e1a\u53f7\u7684\u6c38\u4e45\u6388\u6743\u7801
|
||||
suite_get_permanent_uri={api_base_url}/service/get_permanent_code?suite_access_token=%s
|
||||
@@ -34,6 +34,11 @@ public class Corpinfo extends AgentOverview {
|
||||
*/
|
||||
@JSONField(name = "corp_agent_max")
|
||||
private int corpAgentMax;
|
||||
/**
|
||||
* 授权方企业号二维码
|
||||
*/
|
||||
@JSONField(name = "corp_wxqrcode")
|
||||
private String corpWxqrcode;
|
||||
|
||||
public String getCorpid() {
|
||||
return corpid;
|
||||
@@ -67,10 +72,19 @@ public class Corpinfo extends AgentOverview {
|
||||
this.corpAgentMax = corpAgentMax;
|
||||
}
|
||||
|
||||
public String getCorpWxqrcode() {
|
||||
return corpWxqrcode;
|
||||
}
|
||||
|
||||
public void setCorpWxqrcode(String corpWxqrcode) {
|
||||
this.corpWxqrcode = corpWxqrcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Corpinfo [corpid=" + corpid + ", corpType=" + corpType
|
||||
+ ", corpUserMax=" + corpUserMax + ", corpAgentMax="
|
||||
+ corpAgentMax + ", " + super.toString() + "]";
|
||||
+ corpAgentMax + ", corpWxqrcode=" + corpWxqrcode + ", "
|
||||
+ super.toString() + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,61 @@ public class WeixinQyAccount extends WeixinAccount {
|
||||
super(corpid, corpsecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用套件id
|
||||
*/
|
||||
private String suiteId;
|
||||
/**
|
||||
* 应用套件secret
|
||||
*/
|
||||
private String suiteSecret;
|
||||
/**
|
||||
* 应用套件token,用于生成签名,校验回调请求的合法性。后续所有托管的企业产生的回调消息都使用该值来解密。
|
||||
*/
|
||||
private String suiteToken;
|
||||
/**
|
||||
* 应用套件encodingAesKey,回调消息加解密参数,是AES密钥的Base64编码,用于解密回调消息内容对应的密文。
|
||||
* 后续所有托管的企业产生的回调消息都使用该值来解密。
|
||||
*/
|
||||
private String suiteEncodingAesKey;
|
||||
|
||||
/**
|
||||
* 提供商的secret
|
||||
*/
|
||||
private String providerSecret;
|
||||
|
||||
public String getSuiteId() {
|
||||
return suiteId;
|
||||
}
|
||||
|
||||
public void setSuiteId(String suiteId) {
|
||||
this.suiteId = suiteId;
|
||||
}
|
||||
|
||||
public String getSuiteSecret() {
|
||||
return suiteSecret;
|
||||
}
|
||||
|
||||
public void setSuiteSecret(String suiteSecret) {
|
||||
this.suiteSecret = suiteSecret;
|
||||
}
|
||||
|
||||
public String getSuiteToken() {
|
||||
return suiteToken;
|
||||
}
|
||||
|
||||
public void setSuiteToken(String suiteToken) {
|
||||
this.suiteToken = suiteToken;
|
||||
}
|
||||
|
||||
public String getSuiteEncodingAesKey() {
|
||||
return suiteEncodingAesKey;
|
||||
}
|
||||
|
||||
public void setSuiteEncodingAesKey(String suiteEncodingAesKey) {
|
||||
this.suiteEncodingAesKey = suiteEncodingAesKey;
|
||||
}
|
||||
|
||||
public String getProviderSecret() {
|
||||
return providerSecret;
|
||||
}
|
||||
@@ -45,7 +95,9 @@ public class WeixinQyAccount extends WeixinAccount {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinQyAccount [" + super.toString() + ", providerSecret="
|
||||
+ providerSecret + "]";
|
||||
return "WeixinQyAccount [" + super.toString() + ", suiteId=" + suiteId
|
||||
+ ", suiteSecret=" + suiteSecret + ", suiteToken=" + suiteToken
|
||||
+ ", suiteEncodingAesKey=" + suiteEncodingAesKey
|
||||
+ ", providerSecret=" + providerSecret + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
* 用file存储ticket
|
||||
*
|
||||
* @className FileTicketProcessor
|
||||
* @author jy
|
||||
* @date 2015年6月21日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class FileTicketProcessor implements SuiteTicketProcessor {
|
||||
|
||||
private final String ticketPath;
|
||||
|
||||
public FileTicketProcessor() {
|
||||
this.ticketPath = ConfigUtil.getValue("ticket_path");
|
||||
}
|
||||
|
||||
public FileTicketProcessor(String ticketPath) {
|
||||
this.ticketPath = ticketPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(SuiteTicketMessage suiteTicket) throws WeixinException {
|
||||
try {
|
||||
XmlStream
|
||||
.toXML(suiteTicket,
|
||||
new FileOutputStream(new File(String.format(
|
||||
"%s/%s.xml", ticketPath,
|
||||
getCacheKey(suiteTicket.getSuiteId())))));
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String getCacheKey(String suiteId) {
|
||||
return String.format("qy_suite_ticket_%s", suiteId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuiteTicketMessage read(String suiteId) throws WeixinException {
|
||||
File ticket_file = new File(String.format("%s/%s.xml", ticketPath,
|
||||
getCacheKey(suiteId)));
|
||||
try {
|
||||
return XmlStream.fromXML(new FileInputStream(ticket_file),
|
||||
SuiteTicketMessage.class);
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
/**
|
||||
* 应用套件回调事件
|
||||
*
|
||||
* @className SuiteEventType
|
||||
* @author jy
|
||||
* @date 2015年6月21日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%9B%9E%E8%B0%83%E5%8D%8F%E8%AE%AE">第三方回调协议</a>
|
||||
*/
|
||||
public enum SuiteEventType {
|
||||
/**
|
||||
* 推送ticket
|
||||
*/
|
||||
suite_ticket,
|
||||
/**
|
||||
* 变更授权
|
||||
*/
|
||||
change_auth,
|
||||
/**
|
||||
* 取消授权
|
||||
*/
|
||||
cancel_auth;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement(name = "xml")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class SuiteTicketMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 6457919241019021514L;
|
||||
/**
|
||||
* 应用套件的SuiteId
|
||||
*/
|
||||
@XmlElement(name = "SuiteId")
|
||||
private String suiteId;
|
||||
/**
|
||||
* 事件类型
|
||||
*/
|
||||
@XmlElement(name = "InfoType")
|
||||
private SuiteEventType eventType;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
@XmlElement(name = "TimeStamp")
|
||||
private long timeStamp;
|
||||
/**
|
||||
* Ticket内容
|
||||
*/
|
||||
@XmlElement(name = "SuiteTicket")
|
||||
private String SuiteTicket;
|
||||
/**
|
||||
* 授权方企业号的corpid
|
||||
*/
|
||||
@XmlElement(name = "AuthCorpId")
|
||||
private String authCorpId;
|
||||
|
||||
public String getSuiteId() {
|
||||
return suiteId;
|
||||
}
|
||||
|
||||
public SuiteEventType getEventType() {
|
||||
return eventType;
|
||||
}
|
||||
|
||||
public long getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public String getSuiteTicket() {
|
||||
return SuiteTicket;
|
||||
}
|
||||
|
||||
public String getAuthCorpId() {
|
||||
return authCorpId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SuiteTicketMessage [suiteId=" + suiteId + ", eventType="
|
||||
+ eventType + ", timeStamp=" + timeStamp + ", SuiteTicket="
|
||||
+ SuiteTicket + ", authCorpId=" + authCorpId + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
|
||||
/**
|
||||
* 对套件ticket的处理:写入与读取
|
||||
*
|
||||
* @className SuiteTicketProcessor
|
||||
* @author jy
|
||||
* @date 2015年6月18日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public interface SuiteTicketProcessor {
|
||||
/**
|
||||
* 写入微信推送过来的suite_ticket
|
||||
*
|
||||
* @param suiteTicket
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public void write(SuiteTicketMessage suiteTicket) throws WeixinException;
|
||||
|
||||
/**
|
||||
* 读取最新的suite_ticket
|
||||
*
|
||||
* @param suiteId
|
||||
* @return 最新的ticket
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public SuiteTicketMessage read(String suiteId) throws WeixinException;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.qy.type.URLConsts;
|
||||
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
|
||||
/**
|
||||
* 微信企业号应用套件预授权码创建
|
||||
*
|
||||
* @className WeixinTokenCreator
|
||||
* @author jy
|
||||
* @date 2015年6月17日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E9.A2.84.E6.8E.88.E6.9D.83.E7.A0.81">获取应用套件预授权码</a>
|
||||
* @see com.foxinmy.weixin4j.model.Token
|
||||
*/
|
||||
public class WeixinSuitePreCodeCreator implements TokenCreator {
|
||||
|
||||
private final WeixinHttpClient httpClient;
|
||||
private final TokenHolder suiteTokenHolder;
|
||||
private final String suiteId;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param suiteTokenHolder
|
||||
* 应用套件的token
|
||||
* @param suiteId
|
||||
* 应用套件ID
|
||||
*/
|
||||
public WeixinSuitePreCodeCreator(TokenHolder suiteTokenHolder,
|
||||
String suiteId) {
|
||||
this.suiteTokenHolder = suiteTokenHolder;
|
||||
this.suiteId = suiteId;
|
||||
this.httpClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("qy_suite_precode_%s", suiteId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token createToken() throws WeixinException {
|
||||
WeixinResponse response = httpClient.post(
|
||||
String.format(URLConsts.SUITE_PRE_CODE_URL,
|
||||
suiteTokenHolder.getAccessToken()),
|
||||
String.format("{\"suite_id\":\"%s\"}", suiteId));
|
||||
JSONObject result = response.getAsJson();
|
||||
Token token = new Token(result.getString("pre_auth_code"));
|
||||
token.setExpiresIn(result.getIntValue("expires_in"));
|
||||
token.setTime(System.currentTimeMillis());
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.foxinmy.weixin4j.qy.suite;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.qy.type.URLConsts;
|
||||
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||
|
||||
/**
|
||||
* 微信企业号应用套件凭证创建
|
||||
*
|
||||
* @className WeixinTokenCreator
|
||||
* @author jy
|
||||
* @date 2015年6月17日
|
||||
* @since JDK 1.7
|
||||
* @see <a
|
||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E5.BA.94.E7.94.A8.E5.A5.97.E4.BB.B6.E4.BB.A4.E7.89.8C">获取应用套件凭证</a>
|
||||
* @see com.foxinmy.weixin4j.model.Token
|
||||
*/
|
||||
public class WeixinSuiteTokenCreator implements TokenCreator {
|
||||
|
||||
private final WeixinHttpClient httpClient;
|
||||
private final String suiteId;
|
||||
private final String suiteSecret;
|
||||
private final SuiteTicketProcessor ticketProcessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param suiteId
|
||||
* 套件ID
|
||||
* @param suiteSecret
|
||||
* 套件secret
|
||||
* @param ticketReader
|
||||
* 套件ticket读取器
|
||||
*/
|
||||
public WeixinSuiteTokenCreator(String suiteId, String suiteSecret,
|
||||
SuiteTicketProcessor ticketProcessor) {
|
||||
this.suiteId = suiteId;
|
||||
this.suiteSecret = suiteSecret;
|
||||
this.ticketProcessor = ticketProcessor;
|
||||
this.httpClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCacheKey() {
|
||||
return String.format("qy_suite_token_%s", suiteId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token createToken() throws WeixinException {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("suite_id", suiteId);
|
||||
obj.put("suite_secret", suiteSecret);
|
||||
obj.put("suite_ticket", ticketProcessor.read(suiteId).getSuiteTicket());
|
||||
WeixinResponse response = httpClient.post(URLConsts.SUITE_TOKEN_URL,
|
||||
obj.toJSONString());
|
||||
obj = response.getAsJson();
|
||||
Token token = new Token(obj.getString("suite_access_token"));
|
||||
token.setExpiresIn(obj.getIntValue("expires_in"));
|
||||
token.setTime(System.currentTimeMillis());
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,10 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.qy.type.URLConsts;
|
||||
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信企业号JSTICKET创建
|
||||
@@ -28,19 +27,11 @@ public class WeixinJSTicketCreator implements TokenCreator {
|
||||
private final WeixinHttpClient httpClient;
|
||||
|
||||
/**
|
||||
* jssdk
|
||||
*
|
||||
* @param weixinTokenHolder
|
||||
* <font color="red">公众平台的access_token</font>
|
||||
*/
|
||||
public WeixinJSTicketCreator(TokenHolder weixinTokenHolder) {
|
||||
this(ConfigUtil.getWeixinAccount().getId(), weixinTokenHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* <font color="red">企业号的的access_token</font>
|
||||
*
|
||||
* @param corpid
|
||||
* 企业号ID
|
||||
* @param weixinTokenHolder
|
||||
* <font color="red">企业号的的access_token</font>
|
||||
*/
|
||||
public WeixinJSTicketCreator(String corpid, TokenHolder weixinTokenHolder) {
|
||||
this.corpid = corpid;
|
||||
@@ -56,7 +47,7 @@ public class WeixinJSTicketCreator implements TokenCreator {
|
||||
@Override
|
||||
public Token createToken() throws WeixinException {
|
||||
WeixinResponse response = httpClient.get(String.format(
|
||||
Consts.QY_JS_TICKET_URL, weixinTokenHolder.getToken()
|
||||
URLConsts.JS_TICKET_URL, weixinTokenHolder.getToken()
|
||||
.getAccessToken()));
|
||||
JSONObject result = response.getAsJson();
|
||||
Token token = new Token(result.getString("ticket"));
|
||||
|
||||
+9
-14
@@ -1,15 +1,12 @@
|
||||
package com.foxinmy.weixin4j.qy.token;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||
import com.foxinmy.weixin4j.qy.type.URLConsts;
|
||||
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信企业号应用提供商凭证创建
|
||||
@@ -28,15 +25,13 @@ public class WeixinProviderTokenCreator implements TokenCreator {
|
||||
private final String corpid;
|
||||
private final String providersecret;
|
||||
|
||||
public WeixinProviderTokenCreator() {
|
||||
this(JSON.parseObject(ConfigUtil.getValue("account"),
|
||||
WeixinQyAccount.class));
|
||||
}
|
||||
|
||||
public WeixinProviderTokenCreator(WeixinQyAccount qyAccount) {
|
||||
this(qyAccount.getId(), qyAccount.getProviderSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param corpid
|
||||
* 企业号ID
|
||||
* @param providersecret
|
||||
* 企业号提供商的secret
|
||||
*/
|
||||
public WeixinProviderTokenCreator(String corpid, String providersecret) {
|
||||
this.corpid = corpid;
|
||||
this.providersecret = providersecret;
|
||||
@@ -53,7 +48,7 @@ public class WeixinProviderTokenCreator implements TokenCreator {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("corpid", corpid);
|
||||
obj.put("provider_secret", providersecret);
|
||||
WeixinResponse response = httpClient.post(Consts.QY_PROVIDER_TOKEN_URL,
|
||||
WeixinResponse response = httpClient.post(URLConsts.PROVIDER_TOKEN_URL,
|
||||
obj.toJSONString());
|
||||
obj = response.getAsJson();
|
||||
Token token = new Token(obj.getString("provider_access_token"));
|
||||
|
||||
@@ -4,11 +4,9 @@ import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Consts;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.qy.type.URLConsts;
|
||||
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
|
||||
/**
|
||||
* 微信企业号TOKEN创建
|
||||
@@ -27,14 +25,13 @@ public class WeixinTokenCreator implements TokenCreator {
|
||||
private final String corpid;
|
||||
private final String corpsecret;
|
||||
|
||||
public WeixinTokenCreator() {
|
||||
this(ConfigUtil.getWeixinAccount());
|
||||
}
|
||||
|
||||
public WeixinTokenCreator(WeixinAccount weixinAccount) {
|
||||
this(weixinAccount.getId(), weixinAccount.getSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param corpid
|
||||
* 企业号ID
|
||||
* @param corpsecret
|
||||
* 企业号secret
|
||||
*/
|
||||
public WeixinTokenCreator(String corpid, String corpsecret) {
|
||||
this.corpid = corpid;
|
||||
this.corpsecret = corpsecret;
|
||||
@@ -48,7 +45,7 @@ public class WeixinTokenCreator implements TokenCreator {
|
||||
|
||||
@Override
|
||||
public Token createToken() throws WeixinException {
|
||||
String tokenUrl = String.format(Consts.QY_ASSESS_TOKEN_URL, corpid,
|
||||
String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, corpid,
|
||||
corpsecret);
|
||||
WeixinResponse response = httpClient.get(tokenUrl);
|
||||
Token token = response.getAsObject(new TypeReference<Token>() {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.foxinmy.weixin4j.qy.type;
|
||||
|
||||
/**
|
||||
* URL常量类
|
||||
*
|
||||
* @className URLConsts
|
||||
* @author jy
|
||||
* @date 2014年12月3日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public final class URLConsts {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin";
|
||||
/**
|
||||
* 企业号获取token的url
|
||||
*/
|
||||
public static final String ASSESS_TOKEN_URL = BASE_URL
|
||||
+ "/gettoken?corpid=%s&corpsecret=%s";
|
||||
/**
|
||||
* 企业号提供商获取token的url
|
||||
*/
|
||||
public static final String PROVIDER_TOKEN_URL = BASE_URL
|
||||
+ "/service/get_provider_token";
|
||||
/**
|
||||
* 企业号jssdk获取token的url
|
||||
*/
|
||||
public static final String JS_TICKET_URL = BASE_URL
|
||||
+ "/get_jsapi_ticket?access_token=%s";
|
||||
/**
|
||||
* 企业号第三方应用套件获取token的url
|
||||
*/
|
||||
public static final String SUITE_TOKEN_URL = BASE_URL
|
||||
+ "/service/get_suite_token";
|
||||
|
||||
/**
|
||||
* 企业号第三方应用套件获取预授权码的url
|
||||
*/
|
||||
public static final String SUITE_PRE_CODE_URL = BASE_URL
|
||||
+ "/service/get_pre_auth_code?suite_access_token=%s";
|
||||
}
|
||||
@@ -3,12 +3,18 @@
|
||||
account={"id":"wxf10bce209c91d0e2","secret":"cW0OtP7-7YJ7jHKFZaJW2skJHE9bLHadxOswBdVdI2walRBSPfTSA6QqD_QXw8JZ",\
|
||||
"token":"gp2eGT5mIpngr",\
|
||||
"encodingAesKey":"BRYfV4zPFUJb3v3MySNBg1ERKE3vyyMRoScu76vFySv",\
|
||||
"suiteId":"\u5e94\u7528\u5957\u4ef6\u7684id","suiteSecret":"\u5e94\u7528\u5957\u4ef6\u7684secret",\
|
||||
"suiteToken":"\u5e94\u7528\u5957\u4ef6\u7684token",\
|
||||
"suiteEncodingAesKey":"\u5e94\u7528\u5957\u4ef6\u7684encodingAesKey",\
|
||||
"providerSecret":"\u63d0\u4f9b\u5546\u7684secret"}
|
||||
|
||||
# \u4f7f\u7528FileTokenHolder\u65f6token\u7684\u5b58\u653e\u8def\u5f84
|
||||
# \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84
|
||||
token_path=/tmp/weixin4j/token
|
||||
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84
|
||||
media_path=/tmp/weixin4j/media
|
||||
|
||||
# oauth\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
redirect_uri=
|
||||
# \u4f01\u4e1a\u53f7\u767b\u9646\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
redirect_uri=
|
||||
|
||||
# \u4f01\u4e1a\u53f7\u7b2c\u4e09\u65b9\u5e94\u7528\u5957\u4ef6\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url
|
||||
suite_redirect_uri=
|
||||
Reference in New Issue
Block a user