mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-04-05 17:38:05 +08:00
* #1474 新增客户联系「联系我」管理接口 * fix #1590 提及的me.chanjar.weixin.open.api.impl.WxOpenComponentServiceImpl#getAuthorizerAccessToken()刷新AccessToken后没有同步对应的refreshToken * 补充 me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage#updateToken 方法对 expireInSeconds 边界判断
This commit is contained in:
parent
04fb35d1ba
commit
0758049ea9
@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.cp.api;
|
||||
|
||||
import lombok.NonNull;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.bean.*;
|
||||
|
||||
@ -15,6 +16,83 @@ import java.util.List;
|
||||
* @author <a href="https://github.com/JoeCao">JoeCao</a>
|
||||
*/
|
||||
public interface WxCpExternalContactService {
|
||||
|
||||
/**
|
||||
* 配置客户联系「联系我」方式
|
||||
* <pre>
|
||||
* 企业可以在管理后台-客户联系中配置成员的「联系我」的二维码或者小程序按钮,客户通过扫描二维码或点击小程序上的按钮,即可获取成员联系方式,主动联系到成员。
|
||||
* 企业可通过此接口为具有客户联系功能的成员生成专属的「联系我」二维码或者「联系我」按钮。
|
||||
* 如果配置的是「联系我」按钮,需要开发者的小程序接入小程序插件。
|
||||
*
|
||||
* 注意:
|
||||
* 通过API添加的「联系我」不会在管理端进行展示,每个企业可通过API最多配置50万个「联系我」。
|
||||
* 用户需要妥善存储返回的config_id,config_id丢失可能导致用户无法编辑或删除「联系我」。
|
||||
* 临时会话模式不占用「联系我」数量,但每日最多添加10万个,并且仅支持单人。
|
||||
* 临时会话模式的二维码,添加好友完成后该二维码即刻失效。
|
||||
* </pre>
|
||||
*
|
||||
* @param info 客户联系「联系我」方式
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
WxCpContactWayResult addContactWay(@NonNull WxCpContactWayInfo info) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 获取企业已配置的「联系我」方式
|
||||
*
|
||||
* <pre>
|
||||
* <b>批量</b>获取企业配置的「联系我」二维码和「联系我」小程序按钮。
|
||||
* </pre>
|
||||
*
|
||||
* @param configId 联系方式的配置id,必填
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
WxCpContactWayInfo getContactWay(@NonNull String configId) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 更新企业已配置的「联系我」方式
|
||||
*
|
||||
* <pre>
|
||||
* 更新企业配置的「联系我」二维码和「联系我」小程序按钮中的信息,如使用人员和备注等。
|
||||
* </pre>
|
||||
*
|
||||
* @param info 客户联系「联系我」方式
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
WxCpBaseResp updateContactWay(@NonNull WxCpContactWayInfo info) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 删除企业已配置的「联系我」方式
|
||||
*
|
||||
* <pre>
|
||||
* 删除一个已配置的「联系我」二维码或者「联系我」小程序按钮。
|
||||
* </pre>
|
||||
*
|
||||
* @param configId 企业联系方式的配置id,必填
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
WxCpBaseResp deleteContactWay(@NonNull String configId) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 结束临时会话
|
||||
*
|
||||
* <pre>
|
||||
* 将指定的企业成员和客户之前的临时会话断开,断开前会自动下发已配置的结束语。
|
||||
*
|
||||
* 注意:请保证传入的企业成员和客户之间有仍然有效的临时会话, 通过<b>其他方式的添加外部联系人无法通过此接口关闭会话</b>。
|
||||
* </pre>
|
||||
*
|
||||
* @param userId
|
||||
* @param externalUserId
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
WxCpBaseResp closeTempChat(@NonNull String userId, @NonNull String externalUserId) throws WxErrorException;
|
||||
|
||||
|
||||
/**
|
||||
* 获取外部联系人详情.
|
||||
* <pre>
|
||||
|
@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.error.WxCpErrorMsgEnum;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
@ -9,6 +10,7 @@ import me.chanjar.weixin.cp.api.WxCpExternalContactService;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.*;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@ -23,6 +25,70 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.ExternalContact.*;
|
||||
public class WxCpExternalContactServiceImpl implements WxCpExternalContactService {
|
||||
private final WxCpService mainService;
|
||||
|
||||
@Override
|
||||
public WxCpContactWayResult addContactWay(@NonNull WxCpContactWayInfo info) throws WxErrorException {
|
||||
|
||||
if (info.getUsers() != null && info.getUsers().size() > 100) {
|
||||
throw new RuntimeException("「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)");
|
||||
}
|
||||
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(ADD_CONTACT_WAY);
|
||||
String responseContent = this.mainService.post(url, info.toJson());
|
||||
|
||||
return WxCpContactWayResult.fromJson(responseContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpContactWayInfo getContactWay(@NonNull String configId) throws WxErrorException {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("config_id", configId);
|
||||
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CONTACT_WAY);
|
||||
String responseContent = this.mainService.post(url, json.toString());
|
||||
|
||||
return WxCpContactWayInfo.fromJson(responseContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpBaseResp updateContactWay(@NonNull WxCpContactWayInfo info) throws WxErrorException {
|
||||
if (StringUtils.isBlank(info.getConfigId())) {
|
||||
throw new RuntimeException("更新「联系我」方式需要指定configId");
|
||||
}
|
||||
if (info.getUsers() != null && info.getUsers().size() > 100) {
|
||||
throw new RuntimeException("「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)");
|
||||
}
|
||||
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_CONTACT_WAY);
|
||||
String responseContent = this.mainService.post(url, info.toJson());
|
||||
|
||||
return WxCpBaseResp.fromJson(responseContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpBaseResp deleteContactWay(@NonNull String configId) throws WxErrorException {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("config_id",configId);
|
||||
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(DEL_CONTACT_WAY);
|
||||
String responseContent = this.mainService.post(url, json.toString());
|
||||
|
||||
return WxCpBaseResp.fromJson(responseContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpBaseResp closeTempChat(@NonNull String userId, @NonNull String externalUserId) throws WxErrorException {
|
||||
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("userid",userId);
|
||||
json.addProperty("external_userid",externalUserId);
|
||||
|
||||
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(CLOSE_TEMP_CHAT);
|
||||
String responseContent = this.mainService.post(url, json.toString());
|
||||
|
||||
return WxCpBaseResp.fromJson(responseContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException {
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_EXTERNAL_CONTACT + userId);
|
||||
|
@ -0,0 +1,198 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpConclusionAdapter;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 「联系我」方式 对象
|
||||
*
|
||||
* @author element
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class WxCpContactWayInfo {
|
||||
|
||||
/**
|
||||
* 联系方式的配置id
|
||||
*/
|
||||
@SerializedName("config_id")
|
||||
private String configId;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 必填
|
||||
* 联系方式类型,1-单人, 2-多人
|
||||
* </pre>
|
||||
*/
|
||||
private TYPE type;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 必填
|
||||
* 场景,1-在小程序中联系,2-通过二维码联系
|
||||
* </pre>
|
||||
*/
|
||||
private SCENE scene;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 在小程序中联系时使用的控件样式
|
||||
* <b>单人样式(type=1)时可选1,2,3</b>
|
||||
* <b>多人样式(type=2)时可选1,2</b>
|
||||
* </pre>
|
||||
*/
|
||||
private Integer style;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 联系方式的备注信息,用于助记,不超过30个字符
|
||||
* </pre>
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 外部客户添加时是否无需验证,默认为true
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("skip_verify")
|
||||
private Boolean skipVerify = Boolean.TRUE;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情(WxCpExternalContactService.getContactDetail)” 时会返回该参数值,不超过30个字符
|
||||
* </pre>
|
||||
*/
|
||||
private String state;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 使用该联系方式的用户userID列表,在type为1时为必填,且只能有一个
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("user")
|
||||
private List<String> users;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 使用该联系方式的部门id列表,只在type为2时有效
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("party")
|
||||
private List<String> partys;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 是否临时会话模式,true表示使用临时会话模式,默认为false
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("is_temp")
|
||||
private Boolean isTemp = Boolean.FALSE;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 临时会话二维码有效期,以秒为单位。该参数仅在is_temp为true时有效,默认7天
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("expires_in")
|
||||
private Integer expiresIn;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 临时会话有效期,以秒为单位。该参数仅在is_temp为true时有效,默认为添加好友后24小时
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("chat_expires_in")
|
||||
private Integer chatExpiresIn;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 可进行临时会话的客户unionid,该参数仅在is_temp为true时有效,如不指定则不进行限制
|
||||
* </pre>
|
||||
*/
|
||||
@SerializedName("unionid")
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 非必填
|
||||
* 结束语,会话结束时自动发送给客户,可参考“结束语定义”,仅在is_temp为true时有效
|
||||
* </pre>
|
||||
*/
|
||||
private Conclusion conclusions;
|
||||
|
||||
public static WxCpContactWayInfo fromJson(String json) {
|
||||
return WxCpGsonBuilder.create().fromJson(json, WxCpContactWayInfo.class);
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
return WxCpGsonBuilder.create().toJson(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束语定义
|
||||
*/
|
||||
@Data
|
||||
@JsonAdapter(WxCpConclusionAdapter.class)
|
||||
public static class Conclusion {
|
||||
private String textContent;
|
||||
private String imgMediaId;
|
||||
private String imgPicUrl;
|
||||
private String linkTitle;
|
||||
private String linkPicUrl;
|
||||
private String linkDesc;
|
||||
private String linkUrl;
|
||||
private String miniProgramTitle;
|
||||
private String miniProgramPicMediaId;
|
||||
private String miniProgramAppId;
|
||||
private String miniProgramPage;
|
||||
}
|
||||
|
||||
public enum TYPE {
|
||||
/**
|
||||
* 单人
|
||||
*/
|
||||
@SerializedName("1")
|
||||
SIGLE,
|
||||
|
||||
/**
|
||||
* 多人
|
||||
*/
|
||||
@SerializedName("2")
|
||||
MULTI;
|
||||
|
||||
}
|
||||
|
||||
public enum SCENE {
|
||||
|
||||
/**
|
||||
* 在小程序中联系
|
||||
*/
|
||||
@SerializedName("1")
|
||||
MINIPROGRAM,
|
||||
|
||||
/**
|
||||
* 通过二维码联系
|
||||
*/
|
||||
@SerializedName("2")
|
||||
QRCODE;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
|
||||
/**
|
||||
* 「联系我」方式 处理结果
|
||||
*/
|
||||
@Data
|
||||
public class WxCpContactWayResult extends WxCpBaseResp {
|
||||
@SerializedName("config_id")
|
||||
private String configId;
|
||||
|
||||
public static WxCpContactWayResult fromJson(String json) {
|
||||
return WxCpGsonBuilder.create().fromJson(json, WxCpContactWayResult.class);
|
||||
}
|
||||
}
|
@ -117,6 +117,11 @@ public final class WxCpApiPathConsts {
|
||||
@Deprecated
|
||||
public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid=";
|
||||
|
||||
public static final String ADD_CONTACT_WAY = "/cgi-bin/externalcontact/add_contact_way";
|
||||
public static final String GET_CONTACT_WAY = "/cgi-bin/externalcontact/get_contact_way";
|
||||
public static final String UPDATE_CONTACT_WAY = "/cgi-bin/externalcontact/update_contact_way";
|
||||
public static final String DEL_CONTACT_WAY = "/cgi-bin/externalcontact/del_contact_way";
|
||||
public static final String CLOSE_TEMP_CHAT = "/cgi-bin/externalcontact/close_temp_chat";
|
||||
public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list";
|
||||
public static final String GET_CONTACT_DETAIL = "/cgi-bin/externalcontact/get?external_userid=";
|
||||
public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid=";
|
||||
|
@ -0,0 +1,123 @@
|
||||
package me.chanjar.weixin.cp.util.json;
|
||||
|
||||
import com.google.gson.*;
|
||||
import me.chanjar.weixin.cp.bean.WxCpContactWayInfo;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* 结束语序列化转换器
|
||||
*
|
||||
* @author element
|
||||
*/
|
||||
public class WxCpConclusionAdapter implements JsonSerializer<WxCpContactWayInfo.Conclusion>, JsonDeserializer<WxCpContactWayInfo.Conclusion> {
|
||||
@Override
|
||||
public WxCpContactWayInfo.Conclusion deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
|
||||
WxCpContactWayInfo.Conclusion conclusion = new WxCpContactWayInfo.Conclusion();
|
||||
|
||||
if (jsonObject.get("text") != null) {
|
||||
JsonObject jsonText = jsonObject.get("text").getAsJsonObject();
|
||||
|
||||
if (jsonText.get("content") != null) {
|
||||
conclusion.setTextContent(jsonText.get("content").getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonObject.get("image") != null) {
|
||||
JsonObject jsonImage = jsonObject.get("image").getAsJsonObject();
|
||||
|
||||
if (jsonImage.get("media_id") != null) {
|
||||
conclusion.setImgMediaId(jsonImage.get("media_id").getAsString());
|
||||
}
|
||||
|
||||
if (jsonImage.get("pic_url") != null) {
|
||||
conclusion.setImgPicUrl(jsonImage.get("pic_url").getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonObject.get("link") != null) {
|
||||
JsonObject jsonLink = jsonObject.get("link").getAsJsonObject();
|
||||
|
||||
if (jsonLink.get("title") != null) {
|
||||
conclusion.setLinkTitle(jsonLink.get("title").getAsString());
|
||||
}
|
||||
if (jsonLink.get("picurl") != null) {
|
||||
conclusion.setLinkPicUrl(jsonLink.get("picurl").getAsString());
|
||||
}
|
||||
if (jsonLink.get("desc") != null) {
|
||||
conclusion.setLinkDesc(jsonLink.get("desc").getAsString());
|
||||
}
|
||||
if (jsonLink.get("url") != null) {
|
||||
conclusion.setLinkUrl(jsonLink.get("url").getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonObject.get("miniprogram") != null) {
|
||||
|
||||
JsonObject jsonMiniProgram = jsonObject.get("miniprogram").getAsJsonObject();
|
||||
if (jsonMiniProgram.get("title") != null) {
|
||||
conclusion.setMiniProgramTitle(jsonMiniProgram.get("title").getAsString());
|
||||
}
|
||||
if (jsonMiniProgram.get("pic_media_id") != null) {
|
||||
conclusion.setMiniProgramPicMediaId(jsonMiniProgram.get("pic_media_id").getAsString());
|
||||
}
|
||||
if (jsonMiniProgram.get("appid") != null) {
|
||||
conclusion.setMiniProgramAppId(jsonMiniProgram.get("appid").getAsString());
|
||||
}
|
||||
if (jsonMiniProgram.get("page") != null) {
|
||||
conclusion.setMiniProgramPage(jsonMiniProgram.get("page").getAsString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return conclusion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(WxCpContactWayInfo.Conclusion src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject json = new JsonObject();
|
||||
if (StringUtils.isNotBlank(src.getTextContent())) {
|
||||
JsonObject jsonText = new JsonObject();
|
||||
jsonText.addProperty("content", src.getTextContent());
|
||||
json.add("text", jsonText);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(src.getImgMediaId()) || StringUtils.isNotBlank(src.getImgPicUrl())) {
|
||||
JsonObject jsonImg = new JsonObject();
|
||||
jsonImg.addProperty("media_id", src.getImgMediaId());
|
||||
jsonImg.addProperty("pic_url", src.getImgPicUrl());
|
||||
json.add("image", jsonImg);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(src.getLinkTitle())
|
||||
|| StringUtils.isNotBlank(src.getLinkPicUrl())
|
||||
|| StringUtils.isNotBlank(src.getLinkDesc())
|
||||
|| StringUtils.isNotBlank(src.getLinkUrl())
|
||||
) {
|
||||
JsonObject jsonLink = new JsonObject();
|
||||
jsonLink.addProperty("title", src.getLinkTitle());
|
||||
jsonLink.addProperty("picurl", src.getLinkPicUrl());
|
||||
jsonLink.addProperty("desc", src.getLinkDesc());
|
||||
jsonLink.addProperty("url", src.getLinkUrl());
|
||||
json.add("link", jsonLink);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(src.getMiniProgramTitle())
|
||||
|| StringUtils.isNotBlank(src.getMiniProgramPicMediaId())
|
||||
|| StringUtils.isNotBlank(src.getMiniProgramAppId())
|
||||
|| StringUtils.isNotBlank(src.getMiniProgramPage())
|
||||
) {
|
||||
JsonObject jsonMiniProgram = new JsonObject();
|
||||
jsonMiniProgram.addProperty("title", src.getMiniProgramTitle());
|
||||
jsonMiniProgram.addProperty("pic_media_id", src.getMiniProgramPicMediaId());
|
||||
jsonMiniProgram.addProperty("appid", src.getMiniProgramAppId());
|
||||
jsonMiniProgram.addProperty("page", src.getMiniProgramPage());
|
||||
json.add("miniprogram", jsonMiniProgram);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
@ -1,13 +1,18 @@
|
||||
package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.api.ApiTestModule;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpBaseResp;
|
||||
import me.chanjar.weixin.cp.bean.WxCpContactWayInfo;
|
||||
import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
@ -28,6 +33,55 @@ public class WxCpExternalContactServiceImplTest {
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddContactWay() throws WxErrorException {
|
||||
|
||||
final String concatUserId = "符合要求的userId";
|
||||
|
||||
WxCpContactWayInfo info = new WxCpContactWayInfo();
|
||||
info.setType(WxCpContactWayInfo.TYPE.SIGLE);
|
||||
info.setScene(WxCpContactWayInfo.SCENE.MINIPROGRAM);
|
||||
info.setUsers(Lists.newArrayList(concatUserId));
|
||||
info.setRemark("CreateDate:" + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(new Date()));
|
||||
this.wxCpService.getExternalContactService().addContactWay(info);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetContactWay() throws WxErrorException {
|
||||
final String configId = "2d7a68c657663afbd1d90db19a4b5ee9";
|
||||
WxCpContactWayInfo contactWayInfo = this.wxCpService.getExternalContactService().getContactWay(configId);
|
||||
System.out.println(contactWayInfo);
|
||||
assertNotNull(contactWayInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateContactWay() throws WxErrorException {
|
||||
final String configId = "2d7a68c657663afbd1d90db19a4b5ee9";
|
||||
final String concatUserId = "符合要求的userId";
|
||||
WxCpContactWayInfo info = new WxCpContactWayInfo();
|
||||
info.setConfigId(configId);
|
||||
info.setUsers(Lists.newArrayList(concatUserId));
|
||||
info.setRemark("CreateDate:" + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(new Date()));
|
||||
WxCpBaseResp resp = this.wxCpService.getExternalContactService().updateContactWay(info);
|
||||
System.out.println(resp);
|
||||
assertNotNull(resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelContactWay() throws WxErrorException {
|
||||
final String configId = "2d7a68c657663afbd1d90db19a4b5ee9";
|
||||
WxCpBaseResp resp = this.wxCpService.getExternalContactService().deleteContactWay(configId);
|
||||
System.out.println(resp);
|
||||
assertNotNull(resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseTempChat() throws WxErrorException {
|
||||
final String externalUserId = "externalUserId";
|
||||
WxCpBaseResp resp = this.wxCpService.getExternalContactService().closeTempChat(userId, externalUserId);
|
||||
System.out.println(resp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListExternalContacts() throws WxErrorException {
|
||||
String userId = this.configStorage.getUserId();
|
||||
|
@ -208,6 +208,13 @@ public interface WxOpenConfigStorage {
|
||||
*/
|
||||
void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken);
|
||||
|
||||
/**
|
||||
* setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) 方法重载方法
|
||||
* @param appId the app id
|
||||
* @param authorizerRefreshToken the authorizer refresh token
|
||||
*/
|
||||
void updateAuthorizerRefreshToken(String appId, String authorizerRefreshToken);
|
||||
|
||||
/**
|
||||
* Gets authorizer access token.
|
||||
*
|
||||
|
@ -311,7 +311,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
|
||||
authorizationInfo.getAuthorizerAccessToken(), authorizationInfo.getExpiresIn());
|
||||
}
|
||||
if (authorizationInfo.getAuthorizerRefreshToken() != null) {
|
||||
getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken());
|
||||
getWxOpenConfigStorage().updateAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken());
|
||||
}
|
||||
return queryAuth;
|
||||
}
|
||||
@ -340,7 +340,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
|
||||
String authorizerAppid = data.get("authorizer_appid");
|
||||
String refreshToken = data.get("refresh_token");
|
||||
if (authorizerAppid != null && refreshToken != null) {
|
||||
this.getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizerAppid, refreshToken);
|
||||
this.getWxOpenConfigStorage().updateAuthorizerRefreshToken(authorizerAppid, refreshToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,6 +391,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
|
||||
|
||||
WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent);
|
||||
config.updateAuthorizerAccessToken(appId, wxOpenAuthorizerAccessToken);
|
||||
config.updateAuthorizerRefreshToken(appId,wxOpenAuthorizerAccessToken.getAuthorizerRefreshToken());
|
||||
return config.getAuthorizerAccessToken(appId);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -142,7 +142,7 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
|
||||
map.put(key, token);
|
||||
}
|
||||
token.token = tokenString;
|
||||
if (expiresInSeconds != null) {
|
||||
if (expiresInSeconds != null && expiresInSeconds != -1) {
|
||||
token.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
|
||||
}
|
||||
}
|
||||
@ -157,6 +157,11 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
|
||||
updateToken(authorizerRefreshTokens, appId, authorizerRefreshToken, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAuthorizerRefreshToken(String appId, String authorizerRefreshToken) {
|
||||
this.setAuthorizerRefreshToken(appId, authorizerRefreshToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorizerAccessToken(String appId) {
|
||||
return getTokenString(authorizerAccessTokens, appId);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.open.bean;
|
||||
|
||||
import lombok.Data;
|
||||
import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -7,30 +8,17 @@ import java.io.Serializable;
|
||||
/**
|
||||
* @author <a href="https://github.com/007gzs">007</a>
|
||||
*/
|
||||
@Data
|
||||
public class WxOpenAuthorizerAccessToken implements Serializable {
|
||||
private static final long serialVersionUID = -4069745419280727420L;
|
||||
|
||||
private String authorizerAccessToken;
|
||||
|
||||
private String authorizerRefreshToken;
|
||||
|
||||
private int expiresIn = -1;
|
||||
|
||||
public static WxOpenAuthorizerAccessToken fromJson(String json) {
|
||||
return WxOpenGsonBuilder.create().fromJson(json, WxOpenAuthorizerAccessToken.class);
|
||||
}
|
||||
|
||||
public String getAuthorizerAccessToken() {
|
||||
return authorizerAccessToken;
|
||||
}
|
||||
|
||||
public void setAuthorizerAccessToken(String authorizerAccessToken) {
|
||||
this.authorizerAccessToken = authorizerAccessToken;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public void setExpiresIn(int expiresIn) {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ public class WxOpenAuthorizerAccessTokenGsonAdapter implements JsonDeserializer<
|
||||
WxOpenAuthorizerAccessToken authorizerAccessToken = new WxOpenAuthorizerAccessToken();
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
authorizerAccessToken.setAuthorizerAccessToken(GsonHelper.getString(jsonObject, "authorizer_access_token"));
|
||||
authorizerAccessToken.setAuthorizerRefreshToken(GsonHelper.getString(jsonObject, "authorizer_refresh_token"));
|
||||
authorizerAccessToken.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in"));
|
||||
return authorizerAccessToken;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user