mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2026-03-10 00:13:40 +08:00
Merge remote-tracking branch 'wechat/develop' into develop
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -50,3 +50,4 @@ sonar-project.properties
|
||||
|
||||
# STS
|
||||
.factorypath
|
||||
*.zip
|
||||
|
||||
8
pom.xml
8
pom.xml
@@ -182,7 +182,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>29.0-android</version>
|
||||
<version>29.0-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
@@ -239,6 +239,12 @@
|
||||
<version>3.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.dreamhead</groupId>
|
||||
<artifactId>moco-runner</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
|
||||
@@ -9,6 +9,7 @@ import cn.binarywang.wx.miniapp.config.WxMaConfig;
|
||||
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
|
||||
import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl;
|
||||
import com.binarywang.spring.starter.wxjava.miniapp.enums.HttpClientType;
|
||||
import com.binarywang.spring.starter.wxjava.miniapp.properties.RedisProperties;
|
||||
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.chanjar.weixin.common.redis.JedisWxRedisOps;
|
||||
@@ -52,14 +53,19 @@ public class WxMaAutoConfiguration {
|
||||
public WxMaService service(WxMaConfig wxMaConfig) {
|
||||
HttpClientType httpClientType = wxMaProperties.getConfigStorage().getHttpClientType();
|
||||
WxMaService wxMaService;
|
||||
if (httpClientType == HttpClientType.OkHttp) {
|
||||
wxMaService = new WxMaServiceOkHttpImpl();
|
||||
} else if (httpClientType == HttpClientType.JoddHttp) {
|
||||
wxMaService = new WxMaServiceJoddHttpImpl();
|
||||
} else if (httpClientType == HttpClientType.HttpClient) {
|
||||
wxMaService = new WxMaServiceHttpClientImpl();
|
||||
} else {
|
||||
wxMaService = new WxMaServiceImpl();
|
||||
switch (httpClientType) {
|
||||
case OkHttp:
|
||||
wxMaService = new WxMaServiceOkHttpImpl();
|
||||
break;
|
||||
case JoddHttp:
|
||||
wxMaService = new WxMaServiceJoddHttpImpl();
|
||||
break;
|
||||
case HttpClient:
|
||||
wxMaService = new WxMaServiceHttpClientImpl();
|
||||
break;
|
||||
default:
|
||||
wxMaService = new WxMaServiceImpl();
|
||||
break;
|
||||
}
|
||||
wxMaService.setWxMaConfig(wxMaConfig);
|
||||
return wxMaService;
|
||||
@@ -102,7 +108,7 @@ public class WxMaAutoConfiguration {
|
||||
}
|
||||
|
||||
private WxMaDefaultConfigImpl wxMaJedisConfigStorage() {
|
||||
WxMaProperties.RedisProperties redisProperties = wxMaProperties.getConfigStorage().getRedis();
|
||||
RedisProperties redisProperties = wxMaProperties.getConfigStorage().getRedis();
|
||||
JedisPool jedisPool;
|
||||
if (StringUtils.isNotEmpty(redisProperties.getHost())) {
|
||||
JedisPoolConfig config = new JedisPoolConfig();
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.binarywang.spring.starter.wxjava.miniapp.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* redis 配置.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
@Data
|
||||
public class RedisProperties {
|
||||
|
||||
/**
|
||||
* 主机地址.不填则从spring容器内获取JedisPool
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* 端口号.
|
||||
*/
|
||||
private int port = 6379;
|
||||
|
||||
/**
|
||||
* 密码.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 超时.
|
||||
*/
|
||||
private int timeout = 2000;
|
||||
|
||||
/**
|
||||
* 数据库.
|
||||
*/
|
||||
private int database = 0;
|
||||
|
||||
private Integer maxActive;
|
||||
private Integer maxIdle;
|
||||
private Integer maxWaitMillis;
|
||||
private Integer minIdle;
|
||||
}
|
||||
@@ -88,37 +88,4 @@ public class WxMaProperties {
|
||||
private String httpProxyPassword;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class RedisProperties {
|
||||
|
||||
/**
|
||||
* 主机地址.不填则从spring容器内获取JedisPool
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* 端口号.
|
||||
*/
|
||||
private int port = 6379;
|
||||
|
||||
/**
|
||||
* 密码.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 超时.
|
||||
*/
|
||||
private int timeout = 2000;
|
||||
|
||||
/**
|
||||
* 数据库.
|
||||
*/
|
||||
private int database = 0;
|
||||
|
||||
private Integer maxActive;
|
||||
private Integer maxIdle;
|
||||
private Integer maxWaitMillis;
|
||||
private Integer minIdle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
wx.mp.token = @token
|
||||
wx.mp.aesKey = @aesKey
|
||||
# 存储配置redis(可选)
|
||||
wx.mp.config-storage.type = redis # 配置类型: memory(默认), redis, jedis, redistemplate
|
||||
wx.mp.config-storage.type = Jedis # 配置类型: Memory(默认), Jedis, RedisTemplate
|
||||
wx.mp.config-storage.key-prefix = wx # 相关redis前缀配置: wx(默认)
|
||||
wx.mp.config-storage.redis.host = 127.0.0.1
|
||||
wx.mp.config-storage.redis.port = 6379
|
||||
# http客户端配置
|
||||
wx.mp.config-storage.http-client-type=httpclient # http客户端类型: httpclient(默认), okhttp, joddhttp
|
||||
wx.mp.config-storage.http-client-type=httpclient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp
|
||||
wx.mp.config-storage.http-proxy-host=
|
||||
wx.mp.config-storage.http-proxy-port=
|
||||
wx.mp.config-storage.http-proxy-username=
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.binarywang.spring.starter.wxjava.mp.config;
|
||||
|
||||
import com.binarywang.spring.starter.wxjava.mp.enums.HttpClientType;
|
||||
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
|
||||
import me.chanjar.weixin.common.api.WxOcrService;
|
||||
import me.chanjar.weixin.mp.api.*;
|
||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl;
|
||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
||||
@@ -23,16 +23,21 @@ public class WxMpServiceAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WxMpService wxMpService(WxMpConfigStorage configStorage, WxMpProperties wxMpProperties) {
|
||||
WxMpProperties.HttpClientType httpClientType = wxMpProperties.getConfigStorage().getHttpClientType();
|
||||
HttpClientType httpClientType = wxMpProperties.getConfigStorage().getHttpClientType();
|
||||
WxMpService wxMpService;
|
||||
if (httpClientType == WxMpProperties.HttpClientType.okhttp) {
|
||||
wxMpService = newWxMpServiceOkHttpImpl();
|
||||
} else if (httpClientType == WxMpProperties.HttpClientType.joddhttp) {
|
||||
wxMpService = newWxMpServiceJoddHttpImpl();
|
||||
} else if (httpClientType == WxMpProperties.HttpClientType.httpclient) {
|
||||
wxMpService = newWxMpServiceHttpClientImpl();
|
||||
} else {
|
||||
wxMpService = newWxMpServiceImpl();
|
||||
switch (httpClientType) {
|
||||
case OkHttp:
|
||||
wxMpService = newWxMpServiceOkHttpImpl();
|
||||
break;
|
||||
case JoddHttp:
|
||||
wxMpService = newWxMpServiceJoddHttpImpl();
|
||||
break;
|
||||
case HttpClient:
|
||||
wxMpService = newWxMpServiceHttpClientImpl();
|
||||
break;
|
||||
default:
|
||||
wxMpService = newWxMpServiceImpl();
|
||||
break;
|
||||
}
|
||||
|
||||
wxMpService.setWxMpConfigStorage(configStorage);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.binarywang.spring.starter.wxjava.mp.config;
|
||||
|
||||
import com.binarywang.spring.starter.wxjava.mp.properties.RedisProperties;
|
||||
import com.binarywang.spring.starter.wxjava.mp.enums.StorageType;
|
||||
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.redis.JedisWxRedisOps;
|
||||
@@ -26,7 +28,6 @@ import redis.clients.jedis.JedisPoolConfig;
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class WxMpStorageAutoConfiguration {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
private final WxMpProperties wxMpProperties;
|
||||
@@ -40,25 +41,29 @@ public class WxMpStorageAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(WxMpConfigStorage.class)
|
||||
public WxMpConfigStorage wxMpConfigStorage() {
|
||||
WxMpProperties.StorageType type = wxMpProperties.getConfigStorage().getType();
|
||||
StorageType type = wxMpProperties.getConfigStorage().getType();
|
||||
WxMpConfigStorage config;
|
||||
if (type == WxMpProperties.StorageType.redis || type == WxMpProperties.StorageType.jedis) {
|
||||
config = wxMpInJedisConfigStorage();
|
||||
} else if (type == WxMpProperties.StorageType.redistemplate) {
|
||||
config = wxMpInRedisTemplateConfigStorage();
|
||||
} else {
|
||||
config = wxMpInMemoryConfigStorage();
|
||||
switch (type) {
|
||||
case Jedis:
|
||||
config = jedisConfigStorage();
|
||||
break;
|
||||
case RedisTemplate:
|
||||
config = redisTemplateConfigStorage();
|
||||
break;
|
||||
default:
|
||||
config = defaultConfigStorage();
|
||||
break;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
private WxMpConfigStorage wxMpInMemoryConfigStorage() {
|
||||
private WxMpConfigStorage defaultConfigStorage() {
|
||||
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
|
||||
setWxMpInfo(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
private WxMpConfigStorage wxMpInJedisConfigStorage() {
|
||||
private WxMpConfigStorage jedisConfigStorage() {
|
||||
JedisPool jedisPool;
|
||||
if (StringUtils.isNotEmpty(redisHost) || StringUtils.isNotEmpty(redisHost2)) {
|
||||
jedisPool = getJedisPool();
|
||||
@@ -71,7 +76,7 @@ public class WxMpStorageAutoConfiguration {
|
||||
return wxMpRedisConfig;
|
||||
}
|
||||
|
||||
private WxMpConfigStorage wxMpInRedisTemplateConfigStorage() {
|
||||
private WxMpConfigStorage redisTemplateConfigStorage() {
|
||||
StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class);
|
||||
WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate);
|
||||
WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, wxMpProperties.getConfigStorage().getKeyPrefix());
|
||||
@@ -97,7 +102,7 @@ public class WxMpStorageAutoConfiguration {
|
||||
|
||||
private JedisPool getJedisPool() {
|
||||
WxMpProperties.ConfigStorage storage = wxMpProperties.getConfigStorage();
|
||||
WxMpProperties.RedisProperties redis = storage.getRedis();
|
||||
RedisProperties redis = storage.getRedis();
|
||||
|
||||
JedisPoolConfig config = new JedisPoolConfig();
|
||||
if (redis.getMaxActive() != null) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.binarywang.spring.starter.wxjava.mp.enums;
|
||||
|
||||
/**
|
||||
* httpclient类型.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
public enum HttpClientType {
|
||||
/**
|
||||
* HttpClient.
|
||||
*/
|
||||
HttpClient,
|
||||
/**
|
||||
* OkHttp.
|
||||
*/
|
||||
OkHttp,
|
||||
/**
|
||||
* JoddHttp.
|
||||
*/
|
||||
JoddHttp,
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.binarywang.spring.starter.wxjava.mp.enums;
|
||||
|
||||
/**
|
||||
* storage类型.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
public enum StorageType {
|
||||
/**
|
||||
* 内存.
|
||||
*/
|
||||
Memory,
|
||||
/**
|
||||
* redis(JedisClient).
|
||||
*/
|
||||
Jedis,
|
||||
/**
|
||||
* redis(RedisTemplate).
|
||||
*/
|
||||
RedisTemplate
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.binarywang.spring.starter.wxjava.mp.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* redis 配置属性.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
@Data
|
||||
public class RedisProperties implements Serializable {
|
||||
private static final long serialVersionUID = -5924815351660074401L;
|
||||
|
||||
/**
|
||||
* 主机地址.
|
||||
*/
|
||||
private String host = "127.0.0.1";
|
||||
|
||||
/**
|
||||
* 端口号.
|
||||
*/
|
||||
private int port = 6379;
|
||||
|
||||
/**
|
||||
* 密码.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 超时.
|
||||
*/
|
||||
private int timeout = 2000;
|
||||
|
||||
/**
|
||||
* 数据库.
|
||||
*/
|
||||
private int database = 0;
|
||||
|
||||
private Integer maxActive;
|
||||
private Integer maxIdle;
|
||||
private Integer maxWaitMillis;
|
||||
private Integer minIdle;
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.binarywang.spring.starter.wxjava.mp.properties;
|
||||
|
||||
import com.binarywang.spring.starter.wxjava.mp.enums.HttpClientType;
|
||||
import com.binarywang.spring.starter.wxjava.mp.enums.StorageType;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import static com.binarywang.spring.starter.wxjava.mp.enums.StorageType.Memory;
|
||||
import static com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties.PREFIX;
|
||||
import static com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties.StorageType.memory;
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,7 +53,7 @@ public class WxMpProperties {
|
||||
/**
|
||||
* 存储类型.
|
||||
*/
|
||||
private StorageType type = memory;
|
||||
private StorageType type = Memory;
|
||||
|
||||
/**
|
||||
* 指定key前缀.
|
||||
@@ -66,7 +68,7 @@ public class WxMpProperties {
|
||||
/**
|
||||
* http客户端类型.
|
||||
*/
|
||||
private HttpClientType httpClientType = HttpClientType.httpclient;
|
||||
private HttpClientType httpClientType = HttpClientType.HttpClient;
|
||||
|
||||
/**
|
||||
* http代理主机.
|
||||
@@ -90,73 +92,4 @@ public class WxMpProperties {
|
||||
|
||||
}
|
||||
|
||||
public enum StorageType {
|
||||
/**
|
||||
* 内存.
|
||||
*/
|
||||
memory,
|
||||
/**
|
||||
* jedis.
|
||||
*/
|
||||
redis,
|
||||
/**
|
||||
* redis(JedisClient).
|
||||
*/
|
||||
jedis,
|
||||
/**
|
||||
* redis(RedisTemplate).
|
||||
*/
|
||||
redistemplate
|
||||
}
|
||||
|
||||
public enum HttpClientType {
|
||||
/**
|
||||
* HttpClient.
|
||||
*/
|
||||
httpclient,
|
||||
/**
|
||||
* OkHttp.
|
||||
*/
|
||||
okhttp,
|
||||
/**
|
||||
* JoddHttp.
|
||||
*/
|
||||
joddhttp
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class RedisProperties implements Serializable {
|
||||
private static final long serialVersionUID = -5924815351660074401L;
|
||||
|
||||
/**
|
||||
* 主机地址.
|
||||
*/
|
||||
private String host = "127.0.0.1";
|
||||
|
||||
/**
|
||||
* 端口号.
|
||||
*/
|
||||
private int port = 6379;
|
||||
|
||||
/**
|
||||
* 密码.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 超时.
|
||||
*/
|
||||
private int timeout = 2000;
|
||||
|
||||
/**
|
||||
* 数据库.
|
||||
*/
|
||||
private int database = 0;
|
||||
|
||||
private Integer maxActive;
|
||||
private Integer maxIdle;
|
||||
private Integer maxWaitMillis;
|
||||
private Integer minIdle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -121,31 +121,6 @@ public class WxConsts {
|
||||
public static final String MINIPROGRAM_NOTICE = "miniprogram_notice";
|
||||
}
|
||||
|
||||
/**
|
||||
* 群机器人的消息类型.
|
||||
*/
|
||||
public static class GroupRobotMsgType {
|
||||
/**
|
||||
* 文本消息.
|
||||
*/
|
||||
public static final String TEXT = "text";
|
||||
|
||||
/**
|
||||
* 图片消息.
|
||||
*/
|
||||
public static final String IMAGE = "image";
|
||||
|
||||
/**
|
||||
* markdown消息.
|
||||
*/
|
||||
public static final String MARKDOWN = "markdown";
|
||||
|
||||
/**
|
||||
* 图文消息(点击跳转到外链).
|
||||
*/
|
||||
public static final String NEWS = "news";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表示是否是保密消息,0表示否,1表示是,默认0.
|
||||
*/
|
||||
|
||||
@@ -83,6 +83,11 @@
|
||||
<artifactId>assertj-guava</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.dreamhead</groupId>
|
||||
<artifactId>moco-runner</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.api;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpChat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package me.chanjar.weixin.cp.api;
|
||||
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
|
||||
|
||||
/**
|
||||
* 消息推送接口.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020 -08-30
|
||||
*/
|
||||
public interface WxCpMessageService {
|
||||
/**
|
||||
* <pre>
|
||||
* 发送消息
|
||||
* 详情请见: https://work.weixin.qq.com/api/doc/90000/90135/90236
|
||||
* </pre>
|
||||
*
|
||||
* @param message 要发送的消息对象
|
||||
* @return the wx cp message send result
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 互联企业的应用支持推送文本、图片、视频、文件、图文等类型。
|
||||
*
|
||||
* 请求地址:https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/message/send?access_token=ACCESS_TOKEN
|
||||
* 文章地址:https://work.weixin.qq.com/api/doc/90000/90135/90250
|
||||
* </pre>
|
||||
*
|
||||
* @param message 要发送的消息对象
|
||||
* @return the wx cp message send result
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
WxCpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException;
|
||||
}
|
||||
@@ -8,8 +8,6 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.RequestHttp;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
|
||||
import me.chanjar.weixin.cp.bean.WxCpProviderToken;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
|
||||
@@ -29,13 +27,16 @@ public interface WxCpService {
|
||||
* @param timestamp 时间戳
|
||||
* @param nonce 随机数
|
||||
* @param data 微信传输过来的数据,有可能是echoStr,有可能是xml消息
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean checkSignature(String msgSignature, String timestamp, String nonce, String data);
|
||||
|
||||
/**
|
||||
* 获取access_token, 不强制刷新access_token
|
||||
*
|
||||
* @see #getAccessToken(boolean)
|
||||
* @return the access token
|
||||
* @throws WxErrorException the wx error exception
|
||||
* @see #getAccessToken(boolean) #getAccessToken(boolean)
|
||||
*/
|
||||
String getAccessToken() throws WxErrorException;
|
||||
|
||||
@@ -49,13 +50,17 @@ public interface WxCpService {
|
||||
* </pre>
|
||||
*
|
||||
* @param forceRefresh 强制刷新
|
||||
* @return the access token
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String getAccessToken(boolean forceRefresh) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 获得jsapi_ticket,不强制刷新jsapi_ticket
|
||||
*
|
||||
* @see #getJsapiTicket(boolean)
|
||||
* @return the jsapi ticket
|
||||
* @throws WxErrorException the wx error exception
|
||||
* @see #getJsapiTicket(boolean) #getJsapiTicket(boolean)
|
||||
*/
|
||||
String getJsapiTicket() throws WxErrorException;
|
||||
|
||||
@@ -68,6 +73,8 @@ public interface WxCpService {
|
||||
* </pre>
|
||||
*
|
||||
* @param forceRefresh 强制刷新
|
||||
* @return the jsapi ticket
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String getJsapiTicket(boolean forceRefresh) throws WxErrorException;
|
||||
|
||||
@@ -78,7 +85,9 @@ public interface WxCpService {
|
||||
* 签名的jsapi_ticket必须使用以下接口获取。且必须用wx.agentConfig中的agentid对应的应用secret去获取access_token。
|
||||
* 签名用的noncestr和timestamp必须与wx.agentConfig中的nonceStr和timestamp相同。
|
||||
*
|
||||
* @see #getJsapiTicket(boolean)
|
||||
* @return the agent jsapi ticket
|
||||
* @throws WxErrorException the wx error exception
|
||||
* @see #getJsapiTicket(boolean) #getJsapiTicket(boolean)
|
||||
*/
|
||||
String getAgentJsapiTicket() throws WxErrorException;
|
||||
|
||||
@@ -96,6 +105,8 @@ public interface WxCpService {
|
||||
* </pre>
|
||||
*
|
||||
* @param forceRefresh 强制刷新
|
||||
* @return the agent jsapi ticket
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException;
|
||||
|
||||
@@ -107,23 +118,18 @@ public interface WxCpService {
|
||||
* </pre>
|
||||
*
|
||||
* @param url url
|
||||
* @return the wx jsapi signature
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 发送消息
|
||||
* 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
|
||||
* </pre>
|
||||
*
|
||||
* @param message 要发送的消息对象
|
||||
*/
|
||||
WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 小程序登录凭证校验
|
||||
*
|
||||
* @param jsCode 登录时获取的 code
|
||||
* @return the wx cp ma js code 2 session result
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException;
|
||||
|
||||
@@ -134,6 +140,7 @@ public interface WxCpService {
|
||||
* </pre>
|
||||
*
|
||||
* @return { "ip_list": ["101.226.103.*", "101.226.62.*"] }
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String[] getCallbackIp() throws WxErrorException;
|
||||
|
||||
@@ -147,12 +154,7 @@ public interface WxCpService {
|
||||
*
|
||||
* @param corpId 服务商的corpid
|
||||
* @param providerSecret 服务商的secret,在服务商管理后台可见
|
||||
* @return {
|
||||
* "errcode":0 ,
|
||||
* "errmsg":"ok" ,
|
||||
* "provider_access_token":"enLSZ5xxxxxxJRL",
|
||||
* "expires_in":7200
|
||||
* }
|
||||
* @return { "errcode":0 , "errmsg":"ok" , "provider_access_token":"enLSZ5xxxxxxJRL", "expires_in":7200 }
|
||||
* @throws WxErrorException .
|
||||
*/
|
||||
WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException;
|
||||
@@ -162,6 +164,8 @@ public interface WxCpService {
|
||||
*
|
||||
* @param url 接口地址
|
||||
* @param queryParam 请求参数
|
||||
* @return the string
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String get(String url, String queryParam) throws WxErrorException;
|
||||
|
||||
@@ -170,6 +174,8 @@ public interface WxCpService {
|
||||
*
|
||||
* @param url 接口地址
|
||||
* @param postData 请求body字符串
|
||||
* @return the string
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String post(String url, String postData) throws WxErrorException;
|
||||
|
||||
@@ -178,6 +184,8 @@ public interface WxCpService {
|
||||
*
|
||||
* @param url 接口地址
|
||||
* @param postData 请求body字符串
|
||||
* @return the string
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String postWithoutToken(String url, String postData) throws WxErrorException;
|
||||
|
||||
@@ -188,11 +196,13 @@ public interface WxCpService {
|
||||
* 可以参考,{@link MediaUploadRequestExecutor}的实现方法
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> 请求值类型
|
||||
* @param <E> 返回值类型
|
||||
* @param executor 执行器
|
||||
* @param uri 请求地址
|
||||
* @param data 参数
|
||||
* @param <T> 请求值类型
|
||||
* @param <E> 返回值类型
|
||||
* @return the t
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
<T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException;
|
||||
|
||||
@@ -220,6 +230,7 @@ public interface WxCpService {
|
||||
* 获取某个sessionId对应的session,如果sessionId没有对应的session,则新建一个并返回。
|
||||
*
|
||||
* @param id id可以为任意字符串,建议使用FromUserName作为id
|
||||
* @return the session
|
||||
*/
|
||||
WxSession getSession(String id);
|
||||
|
||||
@@ -228,13 +239,14 @@ public interface WxCpService {
|
||||
*
|
||||
* @param id id可以为任意字符串,建议使用FromUserName作为id
|
||||
* @param create 是否新建
|
||||
* @return the session
|
||||
*/
|
||||
WxSession getSession(String id, boolean create);
|
||||
|
||||
/**
|
||||
* 获取WxSessionManager 对象
|
||||
*
|
||||
* @return WxSessionManager
|
||||
* @return WxSessionManager session manager
|
||||
*/
|
||||
WxSessionManager getSessionManager();
|
||||
|
||||
@@ -252,6 +264,8 @@ public interface WxCpService {
|
||||
* 上传部门列表覆盖企业号上的部门信息
|
||||
*
|
||||
* @param mediaId 媒体id
|
||||
* @return the string
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String replaceParty(String mediaId) throws WxErrorException;
|
||||
|
||||
@@ -259,11 +273,17 @@ public interface WxCpService {
|
||||
* 上传用户列表覆盖企业号上的用户信息
|
||||
*
|
||||
* @param mediaId 媒体id
|
||||
* @return the string
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String replaceUser(String mediaId) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 获取异步任务结果
|
||||
*
|
||||
* @param joinId the join id
|
||||
* @return the task result
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String getTaskResult(String joinId) throws WxErrorException;
|
||||
|
||||
@@ -275,7 +295,7 @@ public interface WxCpService {
|
||||
/**
|
||||
* 获取WxMpConfigStorage 对象
|
||||
*
|
||||
* @return WxMpConfigStorage
|
||||
* @return WxMpConfigStorage wx cp config storage
|
||||
*/
|
||||
WxCpConfigStorage getWxCpConfigStorage();
|
||||
|
||||
@@ -288,75 +308,141 @@ public interface WxCpService {
|
||||
|
||||
/**
|
||||
* 获取部门相关接口的服务类对象
|
||||
*
|
||||
* @return the department service
|
||||
*/
|
||||
WxCpDepartmentService getDepartmentService();
|
||||
|
||||
/**
|
||||
* 获取媒体相关接口的服务类对象
|
||||
*
|
||||
* @return the media service
|
||||
*/
|
||||
WxCpMediaService getMediaService();
|
||||
|
||||
/**
|
||||
* 获取菜单相关接口的服务类对象
|
||||
*
|
||||
* @return the menu service
|
||||
*/
|
||||
WxCpMenuService getMenuService();
|
||||
|
||||
/**
|
||||
* 获取Oauth2相关接口的服务类对象
|
||||
*
|
||||
* @return the oauth 2 service
|
||||
*/
|
||||
WxCpOAuth2Service getOauth2Service();
|
||||
|
||||
/**
|
||||
* 获取标签相关接口的服务类对象
|
||||
*
|
||||
* @return the tag service
|
||||
*/
|
||||
WxCpTagService getTagService();
|
||||
|
||||
/**
|
||||
* 获取用户相关接口的服务类对象
|
||||
*
|
||||
* @return the user service
|
||||
*/
|
||||
WxCpUserService getUserService();
|
||||
|
||||
/**
|
||||
* Gets external contact service.
|
||||
*
|
||||
* @return the external contact service
|
||||
*/
|
||||
WxCpExternalContactService getExternalContactService();
|
||||
|
||||
/**
|
||||
* 获取群聊服务
|
||||
*
|
||||
* @return 群聊服务
|
||||
* @return 群聊服务 chat service
|
||||
*/
|
||||
WxCpChatService getChatService();
|
||||
|
||||
/**
|
||||
* 获取任务卡片服务
|
||||
*
|
||||
* @return 任务卡片服务
|
||||
* @return 任务卡片服务 task card service
|
||||
*/
|
||||
WxCpTaskCardService getTaskCardService();
|
||||
|
||||
/**
|
||||
* Gets agent service.
|
||||
*
|
||||
* @return the agent service
|
||||
*/
|
||||
WxCpAgentService getAgentService();
|
||||
|
||||
/**
|
||||
* Gets message service.
|
||||
*
|
||||
* @return the message service
|
||||
*/
|
||||
WxCpMessageService getMessageService();
|
||||
|
||||
/**
|
||||
* Gets oa service.
|
||||
*
|
||||
* @return the oa service
|
||||
*/
|
||||
WxCpOaService getOAService();
|
||||
|
||||
/**
|
||||
* 获取群机器人消息推送服务
|
||||
*
|
||||
* @return 群机器人消息推送服务
|
||||
* @return 群机器人消息推送服务 group robot service
|
||||
*/
|
||||
WxCpGroupRobotService getGroupRobotService();
|
||||
|
||||
/**
|
||||
* http请求对象
|
||||
*
|
||||
* @return the request http
|
||||
*/
|
||||
RequestHttp<?, ?> getRequestHttp();
|
||||
|
||||
/**
|
||||
* Sets user service.
|
||||
*
|
||||
* @param userService the user service
|
||||
*/
|
||||
void setUserService(WxCpUserService userService);
|
||||
|
||||
/**
|
||||
* Sets department service.
|
||||
*
|
||||
* @param departmentService the department service
|
||||
*/
|
||||
void setDepartmentService(WxCpDepartmentService departmentService);
|
||||
|
||||
/**
|
||||
* Sets media service.
|
||||
*
|
||||
* @param mediaService the media service
|
||||
*/
|
||||
void setMediaService(WxCpMediaService mediaService);
|
||||
|
||||
/**
|
||||
* Sets menu service.
|
||||
*
|
||||
* @param menuService the menu service
|
||||
*/
|
||||
void setMenuService(WxCpMenuService menuService);
|
||||
|
||||
/**
|
||||
* Sets oauth 2 service.
|
||||
*
|
||||
* @param oauth2Service the oauth 2 service
|
||||
*/
|
||||
void setOauth2Service(WxCpOAuth2Service oauth2Service);
|
||||
|
||||
/**
|
||||
* Sets tag service.
|
||||
*
|
||||
* @param tagService the tag service
|
||||
*/
|
||||
void setTagService(WxCpTagService tagService);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.cp.api.*;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
|
||||
import me.chanjar.weixin.cp.bean.WxCpProviderToken;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
|
||||
@@ -53,6 +51,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
||||
private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this);
|
||||
private WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(this);
|
||||
private WxCpGroupRobotService groupRobotService = new WxCpGroupRobotServiceImpl(this);
|
||||
private WxCpMessageService messageService = new WxCpMessageServiceImpl(this);
|
||||
|
||||
/**
|
||||
* 全局的是否正在刷新access token的锁.
|
||||
@@ -169,16 +168,6 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
||||
return jsapiSignature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException {
|
||||
Integer agentId = message.getAgentId();
|
||||
if (null == agentId) {
|
||||
message.setAgentId(this.getWxCpConfigStorage().getAgentId());
|
||||
}
|
||||
|
||||
return WxCpMessageSendResult.fromJson(this.post(this.configStorage.getApiUrl(MESSAGE_SEND), message.toJson()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException {
|
||||
Map<String, String> params = new HashMap<>(2);
|
||||
@@ -486,6 +475,11 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
||||
return agentService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpMessageService getMessageService() {
|
||||
return this.messageService;
|
||||
}
|
||||
|
||||
public void setAgentService(WxCpAgentService agentService) {
|
||||
this.agentService = agentService;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
|
||||
import me.chanjar.weixin.cp.api.WxCpChatService;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpChat;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.api.WxCpGroupRobotService;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpGroupRobotMessage;
|
||||
import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpGroupRobotMessage;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType.*;
|
||||
|
||||
/**
|
||||
* 微信群机器人消息发送api 实现
|
||||
*
|
||||
@@ -30,7 +32,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService {
|
||||
@Override
|
||||
public void sendText(String content, List<String> mentionedList, List<String> mobileList) throws WxErrorException {
|
||||
WxCpGroupRobotMessage message = new WxCpGroupRobotMessage()
|
||||
.setMsgType(WxConsts.GroupRobotMsgType.TEXT)
|
||||
.setMsgType(TEXT)
|
||||
.setContent(content)
|
||||
.setMentionedList(mentionedList)
|
||||
.setMentionedMobileList(mobileList);
|
||||
@@ -40,7 +42,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService {
|
||||
@Override
|
||||
public void sendMarkDown(String content) throws WxErrorException {
|
||||
WxCpGroupRobotMessage message = new WxCpGroupRobotMessage()
|
||||
.setMsgType(WxConsts.GroupRobotMsgType.MARKDOWN)
|
||||
.setMsgType(MARKDOWN)
|
||||
.setContent(content);
|
||||
cpService.postWithoutToken(this.getApiUrl(), message.toJson());
|
||||
}
|
||||
@@ -48,7 +50,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService {
|
||||
@Override
|
||||
public void sendImage(String base64, String md5) throws WxErrorException {
|
||||
WxCpGroupRobotMessage message = new WxCpGroupRobotMessage()
|
||||
.setMsgType(WxConsts.GroupRobotMsgType.IMAGE)
|
||||
.setMsgType(GroupRobotMsgType.IMAGE)
|
||||
.setBase64(base64)
|
||||
.setMd5(md5);
|
||||
cpService.postWithoutToken(this.getApiUrl(), message.toJson());
|
||||
@@ -57,7 +59,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService {
|
||||
@Override
|
||||
public void sendNews(List<NewArticle> articleList) throws WxErrorException {
|
||||
WxCpGroupRobotMessage message = new WxCpGroupRobotMessage()
|
||||
.setMsgType(WxConsts.GroupRobotMsgType.NEWS)
|
||||
.setMsgType(GroupRobotMsgType.NEWS)
|
||||
.setArticles(articleList);
|
||||
cpService.postWithoutToken(this.getApiUrl(), message.toJson());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.api.WxCpMessageService;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
|
||||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts;
|
||||
|
||||
/**
|
||||
* 消息推送接口实现类.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class WxCpMessageServiceImpl implements WxCpMessageService {
|
||||
private final WxCpService cpService;
|
||||
|
||||
@Override
|
||||
public WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException {
|
||||
Integer agentId = message.getAgentId();
|
||||
if (null == agentId) {
|
||||
message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId());
|
||||
}
|
||||
|
||||
return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage()
|
||||
.getApiUrl(WxCpApiPathConsts.Message.MESSAGE_SEND), message.toJson()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxCpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException {
|
||||
Integer agentId = message.getAgentId();
|
||||
if (null == agentId) {
|
||||
message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId());
|
||||
}
|
||||
|
||||
return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage()
|
||||
.getApiUrl(WxCpApiPathConsts.Message.LINKEDCORP_MESSAGE_SEND), message.toJson()));
|
||||
}
|
||||
}
|
||||
@@ -37,4 +37,8 @@ public class NewArticle implements Serializable {
|
||||
*/
|
||||
private String picUrl;
|
||||
|
||||
/**
|
||||
* 按钮文字,仅在图文数为1条时才生效。 默认为“阅读全文”, 不超过4个文字,超过自动截断。该设置只在企业微信上生效,微工作台(原企业号)上不生效。
|
||||
*/
|
||||
private String btnText;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -10,7 +10,7 @@ import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.GroupRobotMsgType.*;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType.*;
|
||||
|
||||
/**
|
||||
* 微信群机器人消息
|
||||
@@ -0,0 +1,244 @@
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
|
||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
|
||||
import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType.*;
|
||||
|
||||
/**
|
||||
* 互联企业消息.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class WxCpLinkedCorpMessage implements Serializable {
|
||||
private static final long serialVersionUID = 8833792280163704238L;
|
||||
|
||||
/**
|
||||
* 1表示发送给应用可见范围内的所有人(包括互联企业的成员),默认为0
|
||||
*/
|
||||
private Boolean isToAll;
|
||||
|
||||
/**
|
||||
* 成员ID列表(消息接收者,最多支持1000个)。每个元素的格式为: corpid/userid,其中,corpid为该互联成员所属的企业,userid为该互联成员所属企业中的帐号。如果是本企业的成员,则直接传userid即可
|
||||
*/
|
||||
private String[] toUsers;
|
||||
/**
|
||||
* 部门ID列表,最多支持100个。partyid在互联圈子内唯一。每个元素都是字符串类型,格式为:linked_id/party_id,其中linked_id是互联id,party_id是在互联圈子中的部门id。如果是本企业的部门,则直接传party_id即可。
|
||||
*/
|
||||
private String[] toParties;
|
||||
/**
|
||||
* 本企业的标签ID列表,最多支持100个。
|
||||
*/
|
||||
private String[] toTags;
|
||||
|
||||
/**
|
||||
* 企业应用的id,整型。可在应用的设置页面查看
|
||||
*/
|
||||
private Integer agentId;
|
||||
private String msgType;
|
||||
/**
|
||||
* 消息内容,最长不超过2048个字节
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 图片媒体文件id,可以调用上传临时素材接口获取
|
||||
*/
|
||||
private String mediaId;
|
||||
private String thumbMediaId;
|
||||
private String title;
|
||||
private String description;
|
||||
/**
|
||||
* 表示是否是保密消息,0表示否,1表示是,默认0
|
||||
*/
|
||||
private Boolean isSafe;
|
||||
private String url;
|
||||
private String btnTxt;
|
||||
private List<NewArticle> articles = new ArrayList<>();
|
||||
private List<MpnewsArticle> mpNewsArticles = new ArrayList<>();
|
||||
private String appId;
|
||||
private String page;
|
||||
private Boolean emphasisFirstItem;
|
||||
private Map<String, String> contentItems;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 请使用.
|
||||
* {@link LinkedCorpMsgType#TEXT}
|
||||
* {@link LinkedCorpMsgType#IMAGE}
|
||||
* {@link LinkedCorpMsgType#VIDEO}
|
||||
* {@link LinkedCorpMsgType#NEWS}
|
||||
* {@link LinkedCorpMsgType#MPNEWS}
|
||||
* {@link LinkedCorpMsgType#MARKDOWN}
|
||||
* {@link LinkedCorpMsgType#MINIPROGRAM_NOTICE}
|
||||
* </pre>
|
||||
*
|
||||
* @param msgType 消息类型
|
||||
*/
|
||||
public void setMsgType(String msgType) {
|
||||
this.msgType = msgType;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
JsonObject messageJson = new JsonObject();
|
||||
|
||||
if (ArrayUtils.isNotEmpty(this.getToUsers())) {
|
||||
messageJson.add("touser", WxGsonBuilder.create().toJsonTree(this.getToUsers()));
|
||||
}
|
||||
|
||||
if (ArrayUtils.isNotEmpty(this.getToParties())) {
|
||||
messageJson.add("toparty", WxGsonBuilder.create().toJsonTree(this.getToParties()));
|
||||
}
|
||||
|
||||
if (ArrayUtils.isNotEmpty(this.getToTags())) {
|
||||
messageJson.add("totag", WxGsonBuilder.create().toJsonTree(this.getToTags()));
|
||||
}
|
||||
|
||||
if (this.getIsToAll() != null) {
|
||||
messageJson.addProperty("toall", this.getIsToAll() ? 1 : 0);
|
||||
}
|
||||
messageJson.addProperty("msgtype", this.getMsgType());
|
||||
|
||||
if (this.getAgentId() != null) {
|
||||
messageJson.addProperty("agentid", this.getAgentId());
|
||||
}
|
||||
|
||||
this.handleMsgType(messageJson);
|
||||
|
||||
if (this.getIsSafe() != null) {
|
||||
messageJson.addProperty("safe", this.getIsSafe() ? 1 : 0);
|
||||
}
|
||||
|
||||
return messageJson.toString();
|
||||
}
|
||||
|
||||
private void handleMsgType(JsonObject messageJson) {
|
||||
switch (this.getMsgType()) {
|
||||
case TEXT: {
|
||||
JsonObject text = new JsonObject();
|
||||
text.addProperty("content", this.getContent());
|
||||
messageJson.add("text", text);
|
||||
break;
|
||||
}
|
||||
case MARKDOWN: {
|
||||
JsonObject text = new JsonObject();
|
||||
text.addProperty("content", this.getContent());
|
||||
messageJson.add("markdown", text);
|
||||
break;
|
||||
}
|
||||
case TEXTCARD: {
|
||||
JsonObject text = new JsonObject();
|
||||
text.addProperty("title", this.getTitle());
|
||||
text.addProperty("description", this.getDescription());
|
||||
text.addProperty("url", this.getUrl());
|
||||
text.addProperty("btntxt", this.getBtnTxt());
|
||||
messageJson.add("textcard", text);
|
||||
break;
|
||||
}
|
||||
case IMAGE: {
|
||||
JsonObject image = new JsonObject();
|
||||
image.addProperty("media_id", this.getMediaId());
|
||||
messageJson.add("image", image);
|
||||
break;
|
||||
}
|
||||
case FILE: {
|
||||
JsonObject image = new JsonObject();
|
||||
image.addProperty("media_id", this.getMediaId());
|
||||
messageJson.add("file", image);
|
||||
break;
|
||||
}
|
||||
case VIDEO: {
|
||||
JsonObject video = new JsonObject();
|
||||
video.addProperty("media_id", this.getMediaId());
|
||||
video.addProperty("title", this.getTitle());
|
||||
video.addProperty("description", this.getDescription());
|
||||
messageJson.add("video", video);
|
||||
break;
|
||||
}
|
||||
case NEWS: {
|
||||
JsonObject newsJsonObject = new JsonObject();
|
||||
JsonArray articleJsonArray = new JsonArray();
|
||||
for (NewArticle article : this.getArticles()) {
|
||||
JsonObject articleJson = new JsonObject();
|
||||
articleJson.addProperty("title", article.getTitle());
|
||||
articleJson.addProperty("description", article.getDescription());
|
||||
articleJson.addProperty("url", article.getUrl());
|
||||
articleJson.addProperty("picurl", article.getPicUrl());
|
||||
articleJson.addProperty("btntxt", article.getBtnText());
|
||||
articleJsonArray.add(articleJson);
|
||||
}
|
||||
newsJsonObject.add("articles", articleJsonArray);
|
||||
messageJson.add("news", newsJsonObject);
|
||||
break;
|
||||
}
|
||||
case MPNEWS: {
|
||||
JsonObject newsJsonObject = new JsonObject();
|
||||
if (this.getMediaId() != null) {
|
||||
newsJsonObject.addProperty("media_id", this.getMediaId());
|
||||
} else {
|
||||
JsonArray articleJsonArray = new JsonArray();
|
||||
for (MpnewsArticle article : this.getMpNewsArticles()) {
|
||||
JsonObject articleJson = new JsonObject();
|
||||
articleJson.addProperty("title", article.getTitle());
|
||||
articleJson.addProperty("thumb_media_id", article.getThumbMediaId());
|
||||
articleJson.addProperty("author", article.getAuthor());
|
||||
articleJson.addProperty("content_source_url", article.getContentSourceUrl());
|
||||
articleJson.addProperty("content", article.getContent());
|
||||
articleJson.addProperty("digest", article.getDigest());
|
||||
if (article.getShowCoverPic() != null) {
|
||||
articleJson.addProperty("show_cover_pic", article.getShowCoverPic());
|
||||
}
|
||||
articleJsonArray.add(articleJson);
|
||||
}
|
||||
|
||||
newsJsonObject.add("articles", articleJsonArray);
|
||||
}
|
||||
messageJson.add("mpnews", newsJsonObject);
|
||||
break;
|
||||
}
|
||||
case MINIPROGRAM_NOTICE: {
|
||||
JsonObject notice = new JsonObject();
|
||||
notice.addProperty("appid", this.getAppId());
|
||||
notice.addProperty("page", this.getPage());
|
||||
notice.addProperty("title", this.getTitle());
|
||||
notice.addProperty("description", this.getDescription());
|
||||
notice.addProperty("emphasis_first_item", this.getEmphasisFirstItem());
|
||||
JsonArray content = new JsonArray();
|
||||
for (Map.Entry<String, String> item : this.getContentItems().entrySet()) {
|
||||
JsonObject articleJson = new JsonObject();
|
||||
articleJson.addProperty("key", item.getKey());
|
||||
articleJson.addProperty("value", item.getValue());
|
||||
content.add(articleJson);
|
||||
}
|
||||
notice.add("content_item", content);
|
||||
|
||||
messageJson.add("miniprogram_notice", notice);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamConverter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamConverter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamConverter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamConverter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamConverter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import com.thoughtworks.xstream.annotations.XStreamConverter;
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class BaseBuilder<T> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* 获得消息builder
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* 获得消息builder
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* 文本消息builder
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* 视频消息builder
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.messagebuilder;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
|
||||
/**
|
||||
* 语音消息builder
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.chanjar.weixin.cp.bean.outxmlbuilder;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
|
||||
public abstract class BaseBuilder<BuilderType, ValueType> {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.chanjar.weixin.cp.bean.outxmlbuilder;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
|
||||
|
||||
/**
|
||||
* 图片消息builder
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean.outxmlbuilder;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage.Item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.chanjar.weixin.cp.bean.outxmlbuilder;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
|
||||
|
||||
/**
|
||||
* 文本消息builder
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.chanjar.weixin.cp.bean.outxmlbuilder;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
|
||||
|
||||
/**
|
||||
* 视频消息builder
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.chanjar.weixin.cp.bean.outxmlbuilder;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
|
||||
|
||||
/**
|
||||
* 语音消息builder
|
||||
|
||||
@@ -24,7 +24,7 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
|
||||
|
||||
private volatile String token;
|
||||
protected volatile String accessToken;
|
||||
protected Lock accessTokenLock = new ReentrantLock();
|
||||
protected transient Lock accessTokenLock = new ReentrantLock();
|
||||
private volatile String aesKey;
|
||||
protected volatile Integer agentId;
|
||||
private volatile long expiresTime;
|
||||
@@ -37,16 +37,16 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
|
||||
private volatile String httpProxyPassword;
|
||||
|
||||
private volatile String jsapiTicket;
|
||||
protected Lock jsapiTicketLock = new ReentrantLock();
|
||||
protected transient Lock jsapiTicketLock = new ReentrantLock();
|
||||
private volatile long jsapiTicketExpiresTime;
|
||||
|
||||
private volatile String agentJsapiTicket;
|
||||
protected Lock agentJsapiTicketLock = new ReentrantLock();
|
||||
protected transient Lock agentJsapiTicketLock = new ReentrantLock();
|
||||
private volatile long agentJsapiTicketExpiresTime;
|
||||
|
||||
private volatile File tmpDirFile;
|
||||
|
||||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
|
||||
private transient volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
|
||||
|
||||
private volatile String baseApiUrl;
|
||||
|
||||
@@ -297,4 +297,9 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
|
||||
public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
|
||||
this.apacheHttpClientBuilder = apacheHttpClientBuilder;
|
||||
}
|
||||
|
||||
public WxCpDefaultConfigImpl setWebhookKey(String webhookKey) {
|
||||
this.webhookKey = webhookKey;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ public final class WxCpApiPathConsts {
|
||||
|
||||
public static final String GET_JSAPI_TICKET = "/cgi-bin/get_jsapi_ticket";
|
||||
public static final String GET_AGENT_CONFIG_TICKET = "/cgi-bin/ticket/get?&type=agent_config";
|
||||
public static final String MESSAGE_SEND = "/cgi-bin/message/send";
|
||||
public static final String GET_CALLBACK_IP = "/cgi-bin/getcallbackip";
|
||||
public static final String BATCH_REPLACE_PARTY = "/cgi-bin/batch/replaceparty";
|
||||
public static final String BATCH_REPLACE_USER = "/cgi-bin/batch/replaceuser";
|
||||
@@ -23,6 +22,22 @@ public final class WxCpApiPathConsts {
|
||||
public static final String GET_TOKEN = "/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
|
||||
public static final String WEBHOOK_SEND = "/cgi-bin/webhook/send?key=";
|
||||
|
||||
/**
|
||||
* 消息推送相关接口
|
||||
* https://work.weixin.qq.com/api/doc/90000/90135/90235
|
||||
*/
|
||||
public static class Message {
|
||||
/**
|
||||
* 发送应用消息
|
||||
*/
|
||||
public static final String MESSAGE_SEND = "/cgi-bin/message/send";
|
||||
|
||||
/**
|
||||
* 互联企业发送应用消息
|
||||
*/
|
||||
public static final String LINKEDCORP_MESSAGE_SEND = "/cgi-bin/linkedcorp/message/send";
|
||||
}
|
||||
|
||||
public static class Agent {
|
||||
public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d";
|
||||
public static final String AGENT_SET = "/cgi-bin/agent/set";
|
||||
|
||||
@@ -166,6 +166,75 @@ public class WxCpConsts {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 互联企业发送应用消息的消息类型.
|
||||
*/
|
||||
public static class LinkedCorpMsgType {
|
||||
/**
|
||||
* 文本消息.
|
||||
*/
|
||||
public static final String TEXT = "text";
|
||||
/**
|
||||
* 图片消息.
|
||||
*/
|
||||
public static final String IMAGE = "image";
|
||||
/**
|
||||
* 视频消息.
|
||||
*/
|
||||
public static final String VIDEO = "video";
|
||||
/**
|
||||
* 图文消息(点击跳转到外链).
|
||||
*/
|
||||
public static final String NEWS = "news";
|
||||
/**
|
||||
* 图文消息(点击跳转到图文消息页面).
|
||||
*/
|
||||
public static final String MPNEWS = "mpnews";
|
||||
/**
|
||||
* markdown消息.
|
||||
* (目前仅支持markdown语法的子集,微工作台(原企业号)不支持展示markdown消息)
|
||||
*/
|
||||
public static final String MARKDOWN = "markdown";
|
||||
/**
|
||||
* 发送文件.
|
||||
*/
|
||||
public static final String FILE = "file";
|
||||
/**
|
||||
* 文本卡片消息.
|
||||
*/
|
||||
public static final String TEXTCARD = "textcard";
|
||||
|
||||
/**
|
||||
* 小程序通知消息.
|
||||
*/
|
||||
public static final String MINIPROGRAM_NOTICE = "miniprogram_notice";
|
||||
}
|
||||
|
||||
/**
|
||||
* 群机器人的消息类型.
|
||||
*/
|
||||
public static class GroupRobotMsgType {
|
||||
/**
|
||||
* 文本消息.
|
||||
*/
|
||||
public static final String TEXT = "text";
|
||||
|
||||
/**
|
||||
* 图片消息.
|
||||
*/
|
||||
public static final String IMAGE = "image";
|
||||
|
||||
/**
|
||||
* markdown消息.
|
||||
*/
|
||||
public static final String MARKDOWN = "markdown";
|
||||
|
||||
/**
|
||||
* 图文消息(点击跳转到外链).
|
||||
*/
|
||||
public static final String NEWS = "news";
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用推送消息的消息类型.
|
||||
*/
|
||||
|
||||
@@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.message;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.message;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.chanjar.weixin.cp.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
|
||||
/**
|
||||
* 消息匹配器,用在消息路由的时候
|
||||
|
||||
@@ -18,8 +18,8 @@ import me.chanjar.weixin.common.session.InternalSessionManager;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.common.util.LogExceptionHandler;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
|
||||
@@ -4,8 +4,8 @@ import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -1,135 +1,135 @@
|
||||
package me.chanjar.weixin.cp.util.xml;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.cp.bean.WxCpTpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
|
||||
|
||||
public class XStreamTransformer {
|
||||
|
||||
protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
|
||||
|
||||
/**
|
||||
* xml -> pojo
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T fromXml(Class<T> clazz, String xml) {
|
||||
T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
|
||||
return object;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T fromXml(Class<T> clazz, InputStream is) {
|
||||
T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册扩展消息的解析器.
|
||||
*
|
||||
* @param clz 类型
|
||||
* @param xStream xml解析器
|
||||
*/
|
||||
public static void register(Class clz, XStream xStream) {
|
||||
CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* pojo -> xml.
|
||||
*/
|
||||
public static <T> String toXml(Class<T> clazz, T object) {
|
||||
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
|
||||
}
|
||||
|
||||
private static Map<Class, XStream> configXStreamInstance() {
|
||||
Map<Class, XStream> map = new HashMap<>();
|
||||
map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
|
||||
map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
|
||||
map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
|
||||
map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
|
||||
map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
|
||||
map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
|
||||
map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
|
||||
map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
|
||||
return map;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutImageMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutImageMessage.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutNewsMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutTextMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutTextMessage.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutVideoMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutVoiceMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpTpXmlPackage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxCpTpXmlPackage.class);
|
||||
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpTpXmlMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxCpTpXmlMessage.class);
|
||||
|
||||
return xstream;
|
||||
}
|
||||
|
||||
}
|
||||
package me.chanjar.weixin.cp.util.xml;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
|
||||
|
||||
public class XStreamTransformer {
|
||||
|
||||
protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
|
||||
|
||||
/**
|
||||
* xml -> pojo
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T fromXml(Class<T> clazz, String xml) {
|
||||
T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
|
||||
return object;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T fromXml(Class<T> clazz, InputStream is) {
|
||||
T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册扩展消息的解析器.
|
||||
*
|
||||
* @param clz 类型
|
||||
* @param xStream xml解析器
|
||||
*/
|
||||
public static void register(Class clz, XStream xStream) {
|
||||
CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* pojo -> xml.
|
||||
*/
|
||||
public static <T> String toXml(Class<T> clazz, T object) {
|
||||
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
|
||||
}
|
||||
|
||||
private static Map<Class, XStream> configXStreamInstance() {
|
||||
Map<Class, XStream> map = new HashMap<>();
|
||||
map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
|
||||
map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
|
||||
map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
|
||||
map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
|
||||
map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
|
||||
map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
|
||||
map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
|
||||
map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
|
||||
return map;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
|
||||
xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutImageMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutImageMessage.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutNewsMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutTextMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutTextMessage.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutVideoMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpXmlOutVoiceMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
|
||||
xstream.processAnnotations(WxCpXmlOutMessage.class);
|
||||
xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpTpXmlPackage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxCpTpXmlPackage.class);
|
||||
|
||||
return xstream;
|
||||
}
|
||||
|
||||
private static XStream configWxCpTpXmlMessage() {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxCpTpXmlMessage.class);
|
||||
|
||||
return xstream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
package me.chanjar.weixin.cp.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Module;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Slf4j
|
||||
public class ApiTestModule implements Module {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
private static final String TEST_CONFIG_XML = "test-config.xml";
|
||||
protected WxXmlCpInMemoryConfigStorage config;
|
||||
|
||||
private static <T> T fromXml(Class<T> clazz, InputStream is) {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
@@ -32,70 +33,27 @@ public class ApiTestModule implements Module {
|
||||
throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成");
|
||||
}
|
||||
|
||||
WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream);
|
||||
config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream);
|
||||
WxCpService wxService = new WxCpServiceImpl();
|
||||
wxService.setWxCpConfigStorage(config);
|
||||
|
||||
binder.bind(WxCpService.class).toInstance(wxService);
|
||||
binder.bind(WxXmlCpInMemoryConfigStorage.class).toInstance(config);
|
||||
} catch (IOException e) {
|
||||
this.log.error(e.getMessage(), e);
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@XStreamAlias("xml")
|
||||
public static class WxXmlCpInMemoryConfigStorage extends WxCpDefaultConfigImpl {
|
||||
private static final long serialVersionUID = -4521839921547374822L;
|
||||
|
||||
protected String userId;
|
||||
|
||||
protected String departmentId;
|
||||
|
||||
protected String tagId;
|
||||
|
||||
protected String externalUserId;
|
||||
|
||||
public String getUserId() {
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getDepartmentId() {
|
||||
return this.departmentId;
|
||||
}
|
||||
|
||||
public void setDepartmentId(String departmentId) {
|
||||
this.departmentId = departmentId;
|
||||
}
|
||||
|
||||
public String getTagId() {
|
||||
return this.tagId;
|
||||
}
|
||||
|
||||
public void setTagId(String tagId) {
|
||||
this.tagId = tagId;
|
||||
}
|
||||
|
||||
public String getExternalUserId() {
|
||||
return externalUserId;
|
||||
}
|
||||
|
||||
public void setExternalUserId(String externalUserId) {
|
||||
this.externalUserId = externalUserId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " > WxXmlCpConfigStorage{" +
|
||||
"userId='" + this.userId + '\'' +
|
||||
", departmentId='" + this.departmentId + '\'' +
|
||||
", tagId='" + this.tagId + '\'' +
|
||||
", externalUserId='" + this.externalUserId + '\'' +
|
||||
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.chanjar.weixin.cp.api;
|
||||
|
||||
import com.google.inject.Binder;
|
||||
|
||||
/**
|
||||
* 带mock server 的test module.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
public class ApiTestModuleWithMockServer extends ApiTestModule {
|
||||
public static final int mockServerPort = 8080;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder) {
|
||||
super.configure(binder);
|
||||
super.config.setBaseApiUrl("http://localhost:" + mockServerPort);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageMatcher;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -11,7 +11,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType;
|
||||
import me.chanjar.weixin.cp.api.ApiTestModule;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpChat;
|
||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
|
||||
import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
|
||||
@@ -16,8 +16,6 @@ import java.io.InputStream;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* 微信群机器人消息发送api 单元测试
|
||||
*
|
||||
@@ -62,7 +60,8 @@ public class WxCpGroupRobotServiceImplTest {
|
||||
|
||||
@Test
|
||||
public void testSendNews() throws WxErrorException {
|
||||
NewArticle article = new NewArticle("图文消息测试","hello world","http://www.baidu.com","http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png");
|
||||
NewArticle article = new NewArticle("图文消息测试", "hello world", "http://www.baidu.com",
|
||||
"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png", null);
|
||||
robotService.sendNews(Stream.of(article).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,54 @@
|
||||
package me.chanjar.weixin.cp.api;
|
||||
package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import com.github.dreamhead.moco.HttpServer;
|
||||
import com.github.dreamhead.moco.Runner;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
|
||||
import me.chanjar.weixin.cp.api.ApiTestModule;
|
||||
import me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
import static com.github.dreamhead.moco.Moco.file;
|
||||
import static com.github.dreamhead.moco.MocoJsonRunner.jsonHttpServer;
|
||||
import static me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer.mockServerPort;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/***
|
||||
* 测试发送消息
|
||||
* @author Daniel Qian
|
||||
/**
|
||||
* 测试类.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
@Test
|
||||
@Guice(modules = ApiTestModule.class)
|
||||
public class WxCpMessageAPITest {
|
||||
|
||||
@Guice(modules = ApiTestModuleWithMockServer.class)
|
||||
//@Guice(modules = ApiTestModule.class)
|
||||
public class WxCpMessageServiceImplTest {
|
||||
@Inject
|
||||
protected WxCpService wxService;
|
||||
|
||||
private Runner mockRunner;
|
||||
private ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage;
|
||||
|
||||
@BeforeTest
|
||||
public void setup() {
|
||||
configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.getWxCpConfigStorage();
|
||||
HttpServer mockServer = jsonHttpServer(mockServerPort, file("src/test/resources/moco/message.json"));
|
||||
this.mockRunner = Runner.runner(mockServer);
|
||||
this.mockRunner.start();
|
||||
this.configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.getWxCpConfigStorage();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void stopMockServer() {
|
||||
this.mockRunner.stop();
|
||||
}
|
||||
|
||||
public void testSendMessage() throws WxErrorException {
|
||||
@@ -37,7 +58,7 @@ public class WxCpMessageAPITest {
|
||||
message.setToUser(configStorage.getUserId());
|
||||
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
|
||||
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
|
||||
assertNotNull(messageSendResult);
|
||||
System.out.println(messageSendResult);
|
||||
System.out.println(messageSendResult.getInvalidPartyList());
|
||||
@@ -54,7 +75,7 @@ public class WxCpMessageAPITest {
|
||||
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>")
|
||||
.build();
|
||||
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
|
||||
assertNotNull(messageSendResult);
|
||||
System.out.println(messageSendResult);
|
||||
System.out.println(messageSendResult.getInvalidPartyList());
|
||||
@@ -82,7 +103,7 @@ public class WxCpMessageAPITest {
|
||||
" >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)")
|
||||
.build();
|
||||
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
|
||||
assertNotNull(messageSendResult);
|
||||
System.out.println(messageSendResult);
|
||||
System.out.println(messageSendResult.getInvalidPartyList());
|
||||
@@ -96,12 +117,12 @@ public class WxCpMessageAPITest {
|
||||
.TEXTCARD()
|
||||
.toUser(configStorage.getUserId())
|
||||
.btnTxt("更多")
|
||||
.description( "<div class=\"gray\">2016年9月26日</div> <div class=\"normal\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\"highlight\">请于2016年10月10日前联系行政同事领取</div>")
|
||||
.description("<div class=\"gray\">2016年9月26日</div> <div class=\"normal\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\"highlight\">请于2016年10月10日前联系行政同事领取</div>")
|
||||
.url("URL")
|
||||
.title("领奖通知")
|
||||
.build();
|
||||
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
|
||||
assertNotNull(messageSendResult);
|
||||
System.out.println(messageSendResult);
|
||||
System.out.println(messageSendResult.getInvalidPartyList());
|
||||
@@ -110,7 +131,7 @@ public class WxCpMessageAPITest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendMessage_miniprogram_notice() throws WxErrorException {
|
||||
public void testSendMessage_miniProgram_notice() throws WxErrorException {
|
||||
WxCpMessage message = WxCpMessage
|
||||
.newMiniProgramNoticeBuilder()
|
||||
.toUser(configStorage.getUserId())
|
||||
@@ -119,16 +140,25 @@ public class WxCpMessageAPITest {
|
||||
.title("会议室预订成功通知")
|
||||
.description("4月27日 16:16")
|
||||
.emphasisFirstItem(true)
|
||||
.contentItems(ImmutableMap.of("会议室","402",
|
||||
"会议地点","广州TIT-402会议室",
|
||||
"会议时间","2018年8月1日 09:00-09:30"))
|
||||
.contentItems(ImmutableMap.of("会议室", "402",
|
||||
"会议地点", "广州TIT-402会议室",
|
||||
"会议时间", "2018年8月1日 09:00-09:30"))
|
||||
.build();
|
||||
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
|
||||
WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
|
||||
assertNotNull(messageSendResult);
|
||||
System.out.println(messageSendResult);
|
||||
System.out.println(messageSendResult.getInvalidPartyList());
|
||||
System.out.println(messageSendResult.getInvalidUserList());
|
||||
System.out.println(messageSendResult.getInvalidTagList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkedCorpMessageSend() throws WxErrorException {
|
||||
this.wxService.getMessageService().sendLinkedCorpMessage(WxCpLinkedCorpMessage.builder()
|
||||
.msgType(WxConsts.KefuMsgType.TEXT)
|
||||
.toUsers(new String[]{configStorage.getUserId()})
|
||||
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@ 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.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
|
||||
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
@@ -49,7 +49,7 @@ public class WxCpTaskCardServiceImplTest {
|
||||
.buttons(Arrays.asList(btn1, btn2))
|
||||
.build();
|
||||
|
||||
WxCpMessageSendResult messageSendResult = this.wxCpService.messageSend(message);
|
||||
WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().send(message);
|
||||
assertNotNull(messageSendResult);
|
||||
System.out.println(messageSendResult);
|
||||
System.out.println(messageSendResult.getInvalidPartyList());
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
|
||||
import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* 测试用例中的json参考 https://work.weixin.qq.com/api/doc/90000/90135/90250
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
* @date 2020-08-30
|
||||
*/
|
||||
public class WxCpLinkedCorpMessageTest {
|
||||
|
||||
@Test
|
||||
public void testToJson_text() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.TEXT)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.isSafe(false)
|
||||
.content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。")
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"text\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"text\" : {\n" +
|
||||
" \"content\" : \"你的快递已到,请携带工卡前往邮件中心领取。\\n出发前可查看<a href=\\\"http://work.weixin.qq.com\\\">邮件中心视频实况</a>,聪明避开排队。\"\n" +
|
||||
" },\n" +
|
||||
" \"safe\":0\n" +
|
||||
"}";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_image() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.IMAGE)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.isSafe(false)
|
||||
.mediaId("MEDIA_ID")
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"image\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"image\" : {\n" +
|
||||
" \"media_id\" : \"MEDIA_ID\"\n" +
|
||||
" },\n" +
|
||||
" \"safe\":0\n" +
|
||||
"}";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_video() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.VIDEO)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.isSafe(false)
|
||||
.mediaId("MEDIA_ID")
|
||||
.title("Title")
|
||||
.description("Description")
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"video\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"video\" : {\n" +
|
||||
" \"media_id\" : \"MEDIA_ID\",\n" +
|
||||
" \"title\" : \"Title\",\n" +
|
||||
" \"description\" : \"Description\"\n" +
|
||||
" },\n" +
|
||||
" \"safe\":0\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_file() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.FILE)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.isSafe(false)
|
||||
.mediaId("1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o")
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"file\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"file\" : {\n" +
|
||||
" \"media_id\" : \"1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o\"\n" +
|
||||
" },\n" +
|
||||
" \"safe\":0\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_textCard() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.TEXTCARD)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.title("领奖通知")
|
||||
.description("<div class=\"gray\">2016年9月26日</div> <div class=\"normal\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\"highlight\">请于2016年10月10日前联系行政同事领取</div>")
|
||||
.url("URL")
|
||||
.btnTxt("更多")
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"textcard\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"textcard\" : {\n" +
|
||||
" \"title\" : \"领奖通知\",\n" +
|
||||
" \"description\" : \"<div class=\\\"gray\\\">2016年9月26日</div> <div class=\\\"normal\\\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\\\"highlight\\\">请于2016年10月10日前联系行政同事领取</div>\",\n" +
|
||||
" \"url\" : \"URL\",\n" +
|
||||
" \"btntxt\":\"更多\"\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_news() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.NEWS)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.articles(Lists.newArrayList(NewArticle.builder()
|
||||
.title("中秋节礼品领取")
|
||||
.description("今年中秋节公司有豪礼相送")
|
||||
.url("URL")
|
||||
.picUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png")
|
||||
.btnText("更多")
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"news\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"news\" : {\n" +
|
||||
" \"articles\" : [\n" +
|
||||
" {\n" +
|
||||
" \"title\" : \"中秋节礼品领取\",\n" +
|
||||
" \"description\" : \"今年中秋节公司有豪礼相送\",\n" +
|
||||
" \"url\" : \"URL\",\n" +
|
||||
" \"picurl\" : \"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png\",\n" +
|
||||
" \"btntxt\":\"更多\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testToJson_mpnews() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.MPNEWS)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.isSafe(false)
|
||||
.mpNewsArticles(Lists.newArrayList(MpnewsArticle.newBuilder()
|
||||
.title("Title")
|
||||
.thumbMediaId("MEDIA_ID")
|
||||
.author("Author")
|
||||
.contentSourceUrl("URL")
|
||||
.content("Content")
|
||||
.digest("Digest description")
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"mpnews\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"mpnews\" : {\n" +
|
||||
" \"articles\":[\n" +
|
||||
" {\n" +
|
||||
" \"title\": \"Title\", \n" +
|
||||
" \"thumb_media_id\": \"MEDIA_ID\",\n" +
|
||||
" \"author\": \"Author\",\n" +
|
||||
" \"content_source_url\": \"URL\",\n" +
|
||||
" \"content\": \"Content\",\n" +
|
||||
" \"digest\": \"Digest description\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"safe\":0\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_markdown() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.MARKDOWN)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.agentId(1)
|
||||
.isToAll(false)
|
||||
.content("您的会议室已经预定,稍后会同步到`邮箱`\n" +
|
||||
" >**事项详情**\n" +
|
||||
" >事 项:<font color=\"info\">开会</font>\n" +
|
||||
" >组织者:@miglioguan\n" +
|
||||
" >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" +
|
||||
" >\n" +
|
||||
" >会议室:<font color=\"info\">广州TIT 1楼 301</font>\n" +
|
||||
" >日 期:<font color=\"warning\">2018年5月18日</font>\n" +
|
||||
" >时 间:<font color=\"comment\">上午9:00-11:00</font>\n" +
|
||||
" >\n" +
|
||||
" >请准时参加会议。\n" +
|
||||
" >\n" +
|
||||
" >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)")
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"toall\" : 0,\n" +
|
||||
" \"msgtype\" : \"markdown\",\n" +
|
||||
" \"agentid\" : 1,\n" +
|
||||
" \"markdown\": {\n" +
|
||||
" \"content\": \"您的会议室已经预定,稍后会同步到`邮箱`\n" +
|
||||
" >**事项详情**\n" +
|
||||
" >事 项:<font color=\\\"info\\\">开会</font>\n" +
|
||||
" >组织者:@miglioguan\n" +
|
||||
" >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" +
|
||||
" >\n" +
|
||||
" >会议室:<font color=\\\"info\\\">广州TIT 1楼 301</font>\n" +
|
||||
" >日 期:<font color=\\\"warning\\\">2018年5月18日</font>\n" +
|
||||
" >时 间:<font color=\\\"comment\\\">上午9:00-11:00</font>\n" +
|
||||
" >\n" +
|
||||
" >请准时参加会议。\n" +
|
||||
" >\n" +
|
||||
" >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)\"\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToJson_miniProgramNotice() {
|
||||
WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
|
||||
.msgType(KefuMsgType.MINIPROGRAM_NOTICE)
|
||||
.toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
|
||||
.toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
|
||||
.toTags(new String[]{"tagid1", "tagid2"})
|
||||
.emphasisFirstItem(true)
|
||||
.description("4月27日 16:16")
|
||||
.title("会议室预订成功通知")
|
||||
.appId("wx123123123123123")
|
||||
.page("pages/index?userid=zhangsan&orderid=123123123")
|
||||
.contentItems(ImmutableMap.of("会议室","402",
|
||||
"会议地点","广州TIT-402会议室",
|
||||
"会议时间","2018年8月1日 09:00-09:30",
|
||||
"参与人员","周剑轩"))
|
||||
.build();
|
||||
|
||||
final String json = message.toJson();
|
||||
String expectedJson = "{\n" +
|
||||
" \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
|
||||
" \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
|
||||
" \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
|
||||
" \"msgtype\" : \"miniprogram_notice\",\n" +
|
||||
" \"miniprogram_notice\" : {\n" +
|
||||
" \"appid\": \"wx123123123123123\",\n" +
|
||||
" \"page\": \"pages/index?userid=zhangsan&orderid=123123123\",\n" +
|
||||
" \"title\": \"会议室预订成功通知\",\n" +
|
||||
" \"description\": \"4月27日 16:16\",\n" +
|
||||
" \"emphasis_first_item\": true,\n" +
|
||||
" \"content_item\": [\n" +
|
||||
" {\n" +
|
||||
" \"key\": \"会议室\",\n" +
|
||||
" \"value\": \"402\"\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"key\": \"会议地点\",\n" +
|
||||
" \"value\": \"广州TIT-402会议室\"\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"key\": \"会议时间\",\n" +
|
||||
" \"value\": \"2018年8月1日 09:00-09:30\"\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"key\": \"参与人员\",\n" +
|
||||
" \"value\": \"周剑轩\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
|
||||
assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
|
||||
import me.chanjar.weixin.cp.bean.article.NewArticle;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
|
||||
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.constant.WxCpConsts;
|
||||
import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
|
||||
import org.testng.annotations.Test;
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.chanjar.weixin.cp.bean;
|
||||
package me.chanjar.weixin.cp.bean.message;
|
||||
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -13,9 +13,9 @@ import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.constant.WxCpConsts;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
|
||||
|
||||
@@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.demo;
|
||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
||||
26
weixin-java-cp/src/test/resources/moco/message.json
Normal file
26
weixin-java-cp/src/test/resources/moco/message.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"request": {
|
||||
"uri": "/cgi-bin/gettoken"
|
||||
},
|
||||
"response": {
|
||||
"text": "{\"errcode\":0,\"errmsg\":\"ok\",\"access_token\":\"oG1MrhLSzGBl4YxM1W2EHJlL_5vAotNwQ6KBp98sP2fO8XGPPRUlWS9w98CKjxSgPx4YnTy0DU_DvmNXAwt3mSDJ1Uhg_WCFrxX8GWbbCRlzrj2csK-1Y3tzI6dBCMa2YmblBo2sX7qkkzc9pnjP38GzO7Yuo_Bbpyi4doilNWZme0z9ovwiBCkAtV7DXYuh14EsnNrODG454kstOxsqWA\",\"expires_in\":7200}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"uri": "/cgi-bin/message/send"
|
||||
},
|
||||
"response": {
|
||||
"text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"uri": "/cgi-bin/linkedcorp/message/send"
|
||||
},
|
||||
"response": {
|
||||
"text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
<test name="Bean_Test">
|
||||
<classes>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpXmlMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessageTest"/>
|
||||
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessageTest"/>
|
||||
</classes>
|
||||
</test>
|
||||
</suite>
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user