Browse Source

#783 企业微信模块增加群聊相关接口

* 实现消息推送的服务,添加发送应用消息的方法

* 添加创建群聊会话方法,去除不需要的类

* 完成群聊会话的修改和获取

* 重构群聊服务,提出到单独的服务类里面

* 完成群聊的测试
gaigeshen 6 years ago
parent
commit
9b6893161a

+ 48 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java

@@ -0,0 +1,48 @@
+package me.chanjar.weixin.cp.api;
+
+import java.util.List;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.WxCpChat;
+
+/**
+ * 群聊服务
+ *
+ * @author gaigeshen
+ */
+public interface WxCpChatService {
+
+  /**
+   * 创建群聊会话,注意:刚创建的群,如果没有下发消息,在企业微信不会出现该群。
+   *
+   * @param name 群聊名,最多50个utf8字符,超过将截断
+   * @param owner 指定群主的id。如果不指定,系统会随机从userlist中选一人作为群主
+   * @param users 群成员id列表。至少2人,至多500人
+   * @param chatId 群聊的唯一标志,不能与已有的群重复;字符串类型,最长32个字符。只允许字符0-9及字母a-zA-Z。如果不填,系统会随机生成群id
+   * @return 创建群聊会话的结果,群聊的唯一标志
+   * @throws WxErrorException 发生异常
+   */
+  String chatCreate(String name, String owner, List<String> users, String chatId) throws WxErrorException;
+  
+  /**
+   * 修改群聊会话
+   * 
+   * @param chatId 群聊id
+   * @param name 新的群聊名。若不需更新,请忽略此参数(null or empty)。最多50个utf8字符,超过将截断
+   * @param owner 新群主的id。若不需更新,请忽略此参数(null or empty)
+   * @param usersToAdd 添加成员的id列表,若不需要更新,则传递空对象或者空集合
+   * @param usersToDelete 踢出成员的id列表,若不需要更新,则传递空对象或者空集合
+   * @throws WxErrorException 发生异常
+   */
+  void chatUpdate(String chatId, String name, String owner, List<String> usersToAdd, List<String> usersToDelete) throws WxErrorException;
+
+  /**
+   * 获取群聊会话
+   * 
+   * @param chatId 群聊编号
+   * @return 群聊会话
+   * @throws WxErrorException 发生异常
+   */
+  WxCpChat chatGet(String chatId) throws WxErrorException;
+  
+}

+ 10 - 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java

@@ -7,7 +7,8 @@ import me.chanjar.weixin.common.session.WxSessionManager;
 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.*;
+import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
 import me.chanjar.weixin.cp.config.WxCpConfigStorage;
 
 /**
@@ -241,13 +242,20 @@ public interface WxCpService {
    * 获取用户相关接口的服务类对象
    */
   WxCpUserService getUserService();
+  
+  /**
+   * 获取群聊服务
+   * 
+   * @return 群聊服务
+   */
+  WxCpChatService getChatService();
 
   WxCpAgentService getAgentService();
 
   /**
    * http请求对象
    */
-  RequestHttp getRequestHttp();
+  RequestHttp<?, ?> getRequestHttp();
 
   void setUserService(WxCpUserService userService);
 

+ 3 - 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java

@@ -1,9 +1,11 @@
 package me.chanjar.weixin.cp.api.impl;
 
-import com.google.gson.Gson;
+import java.util.List;
+
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
 import com.google.gson.reflect.TypeToken;
+
 import me.chanjar.weixin.common.error.WxError;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.api.WxCpAgentService;
@@ -11,8 +13,6 @@ import me.chanjar.weixin.cp.api.WxCpService;
 import me.chanjar.weixin.cp.bean.WxCpAgent;
 import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
 
-import java.util.List;
-
 
 /**
  * <pre>

+ 83 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java

@@ -0,0 +1,83 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.gson.JsonParser;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+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.WxCpChat;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * 群聊服务实现
+ *
+ * @author gaigeshen
+ */
+public class WxCpChatServiceImpl implements WxCpChatService { 
+
+  private final WxCpService internalService;
+  
+  /**
+   * 创建群聊服务实现的实例
+   * 
+   * @param internalService 企业微信的服务
+   */
+  public WxCpChatServiceImpl(WxCpService internalService) {
+    this.internalService = internalService;
+  }
+
+  @Override
+  public String chatCreate(String name, String owner, List<String> users, String chatId) throws WxErrorException {
+    Map<String, Object> data = new HashMap<>(4);
+    if (StringUtils.isNotBlank(name)) {
+      data.put("name", name);
+    }
+    if (StringUtils.isNotBlank(owner)) {
+      data.put("owner", owner);
+    }
+    if (users != null) {
+      data.put("userlist", users);
+    }
+    if (StringUtils.isNotBlank(chatId)) {
+      data.put("chatid", chatId);
+    }
+    String result = internalService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/create", WxGsonBuilder.create().toJson(data));
+    return new JsonParser().parse(result).getAsJsonObject().get("chatid").getAsString();
+  }
+
+  @Override
+  public void chatUpdate(String chatId, String name, String owner, List<String> usersToAdd, List<String> usersToDelete) throws WxErrorException {
+    Map<String, Object> data = new HashMap<>(5);
+    if (StringUtils.isNotBlank(chatId)) {
+      data.put("chatid", chatId);
+    }
+    if (StringUtils.isNotBlank(name)) {
+      data.put("name", name);
+    }
+    if (StringUtils.isNotBlank(owner)) {
+      data.put("owner", owner);
+    }
+    if (usersToAdd != null && !usersToAdd.isEmpty()) {
+      data.put("add_user_list", usersToAdd);
+    }
+    if (usersToDelete != null && !usersToDelete.isEmpty()) {
+      data.put("del_user_list", usersToDelete);
+    }
+    internalService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/update", WxGsonBuilder.create().toJson(data));
+  }
+
+  @Override
+  public WxCpChat chatGet(String chatId) throws WxErrorException {
+    String result = internalService.get("https://qyapi.weixin.qq.com/cgi-bin/appchat/get?chatid=" + chatId, null);
+    return WxCpGsonBuilder.create().fromJson(
+        new JsonParser().parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class);
+  }
+
+}

+ 9 - 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java

@@ -10,6 +10,7 @@ import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+
 import me.chanjar.weixin.common.bean.WxJsapiSignature;
 import me.chanjar.weixin.common.error.WxError;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -24,6 +25,7 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
 import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
 import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
 import me.chanjar.weixin.cp.api.WxCpAgentService;
+import me.chanjar.weixin.cp.api.WxCpChatService;
 import me.chanjar.weixin.cp.api.WxCpDepartmentService;
 import me.chanjar.weixin.cp.api.WxCpMediaService;
 import me.chanjar.weixin.cp.api.WxCpMenuService;
@@ -39,6 +41,7 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ
   protected final Logger log = LoggerFactory.getLogger(this.getClass());
 
   private WxCpUserService userService = new WxCpUserServiceImpl(this);
+  private WxCpChatService chatService = new WxCpChatServiceImpl(this);
   private WxCpDepartmentService departmentService = new WxCpDepartmentServiceImpl(this);
   private WxCpMediaService mediaService = new WxCpMediaServiceImpl(this);
   private WxCpMenuService menuService = new WxCpMenuServiceImpl(this);
@@ -343,7 +346,12 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ
   }
 
   @Override
-  public RequestHttp getRequestHttp() {
+  public WxCpChatService getChatService() {
+    return chatService;
+  }
+
+  @Override
+  public RequestHttp<?, ?> getRequestHttp() {
     return this;
   }
 

+ 20 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpChat.java

@@ -0,0 +1,20 @@
+package me.chanjar.weixin.cp.bean;
+
+import java.util.List;
+
+import lombok.Data;
+
+/**
+ * 群聊
+ *
+ * @author gaigeshen
+ */
+@Data
+public class WxCpChat {
+  
+  private String id;
+  private String name;
+  private String owner;
+  private List<String> users;
+
+}

+ 77 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpChatGsonAdapter.java

@@ -0,0 +1,77 @@
+/*
+ * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
+ *
+ * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
+ * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
+ * arose from modification of the original source, or other redistribution of this source
+ * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
+ */
+package me.chanjar.weixin.cp.util.json;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import me.chanjar.weixin.common.util.json.GsonHelper;
+import me.chanjar.weixin.cp.bean.WxCpChat;
+
+/**
+ * 群聊适配器
+ *
+ * @author gaigeshen
+ */
+public class WxCpChatGsonAdapter implements JsonSerializer<WxCpChat>, JsonDeserializer<WxCpChat> {
+
+  @Override
+  public JsonElement serialize(WxCpChat chat, Type typeOfSrc, JsonSerializationContext context) {
+    JsonObject json = new JsonObject();
+    if (chat.getId() != null) { 
+      json.addProperty("chatid", chat.getId());
+    }
+    if (chat.getName() != null) {
+      json.addProperty("name", chat.getName());
+    } 
+    if (chat.getOwner() != null) {
+      json.addProperty("owner", chat.getOwner());
+    }
+    if (chat.getUsers() != null) {
+      JsonArray users = new JsonArray();
+      for (String user : chat.getUsers()) {
+        users.add(user);
+      }
+      json.add("userlist", users);
+    }
+    return json;
+  }
+
+  @Override
+  public WxCpChat deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+    JsonObject chatJson = json.getAsJsonObject();
+
+    WxCpChat chat = new WxCpChat();
+    chat.setId(GsonHelper.getAsString(chatJson.get("chatid")));
+    chat.setName(GsonHelper.getAsString(chatJson.get("name")));
+    chat.setOwner(GsonHelper.getAsString(chatJson.get("owner")));
+    
+    JsonArray usersJson = chatJson.getAsJsonArray("userlist");
+    if (usersJson != null) {
+      List<String> users = new ArrayList<>(usersJson.size());
+      chat.setUsers(users);
+      for (JsonElement userJson : usersJson) {
+        users.add(userJson.getAsString());
+      }
+    }
+    
+    return chat;
+  }
+
+}

+ 2 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java

@@ -5,6 +5,7 @@ import com.google.gson.GsonBuilder;
 import me.chanjar.weixin.common.bean.menu.WxMenu;
 import me.chanjar.weixin.common.error.WxError;
 import me.chanjar.weixin.common.util.json.WxErrorAdapter;
+import me.chanjar.weixin.cp.bean.WxCpChat;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 import me.chanjar.weixin.cp.bean.WxCpMessage;
 import me.chanjar.weixin.cp.bean.WxCpTag;
@@ -20,6 +21,7 @@ public class WxCpGsonBuilder {
   static {
     INSTANCE.disableHtmlEscaping();
     INSTANCE.registerTypeAdapter(WxCpMessage.class, new WxCpMessageGsonAdapter());
+    INSTANCE.registerTypeAdapter(WxCpChat.class, new WxCpChatGsonAdapter());
     INSTANCE.registerTypeAdapter(WxCpDepart.class, new WxCpDepartGsonAdapter());
     INSTANCE.registerTypeAdapter(WxCpUser.class, new WxCpUserGsonAdapter());
     INSTANCE.registerTypeAdapter(WxError.class, new WxErrorAdapter());

+ 46 - 0
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java

@@ -0,0 +1,46 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import java.util.Arrays;
+
+import me.chanjar.weixin.cp.bean.WxCpChat;
+import org.testng.Assert;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.WxCpService;
+
+/**
+ * 测试群聊服务
+ *
+ * @author gaigeshen
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxCpChatServiceImplTest {
+
+  @Inject
+  private WxCpService wxCpService;
+  
+  @Test
+  public void create() throws Exception {
+    wxCpService.getChatService().chatCreate("测试群聊", "gaige_shen", Arrays.asList("gaige_shen", "ZhangXiaoMing"), "mychatid");
+  }
+
+  @Test
+  public void get() throws Exception {
+    WxCpChat chat = wxCpService.getChatService().chatGet("mychatid");
+    System.out.println(chat);
+    Assert.assertEquals(chat.getName(), "测试群聊");
+  }
+
+  @Test
+  public void update() throws Exception {
+    wxCpService.getChatService().chatUpdate("mychatid",  "", "", Arrays.asList("ZhengWuYao"), null);
+    WxCpChat chat = wxCpService.getChatService().chatGet("mychatid");
+    System.out.println(chat);
+    Assert.assertEquals(chat.getUsers().size(), 3);
+  }
+
+}