diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java index 8b07086b2..ca6c62611 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java @@ -22,6 +22,11 @@ public class WxErrorException extends Exception { this.error = error; } + public WxErrorException(Throwable cause) { + super(cause.getMessage(), cause); + this.error = WxError.builder().errorCode(-1).errorMsg(cause.getMessage()).build(); + } + public WxError getError() { return this.error; } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxService.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxService.java index fc49bfd9c..24897561c 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxService.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxService.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.common.service; +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.bean.ToJson; import me.chanjar.weixin.common.error.WxErrorException; /** @@ -38,4 +40,24 @@ public interface WxService { * @throws WxErrorException 异常 */ String post(String url, Object obj) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. + * + * @param url 请求接口地址 + * @param jsonObject 请求对象 + * @return 接口响应字符串 + * @throws WxErrorException 异常 + */ + String post(String url, JsonObject jsonObject) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. + * + * @param url 请求接口地址 + * @param obj 请求对象,实现了ToJson接口 + * @return 接口响应字符串 + * @throws WxErrorException 异常 + */ + String post(String url, ToJson obj) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 90c66ab91..1933c1469 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import me.chanjar.weixin.common.bean.ToJson; import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.service.WxService; import me.chanjar.weixin.common.session.WxSession; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; @@ -18,7 +19,7 @@ import me.chanjar.weixin.cp.config.WxCpConfigStorage; * * @author chanjaster */ -public interface WxCpService { +public interface WxCpService extends WxService { /** *
    * 验证推送过来的消息的正确性
@@ -161,46 +162,6 @@ public interface WxCpService {
    */
   WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException;
 
-  /**
-   * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求
-   *
-   * @param url        接口地址
-   * @param queryParam 请求参数
-   * @return the string
-   * @throws WxErrorException the wx error exception
-   */
-  String get(String url, String queryParam) throws WxErrorException;
-
-  /**
-   * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求
-   *
-   * @param url      接口地址
-   * @param postData 请求body字符串
-   * @return the string
-   * @throws WxErrorException the wx error exception
-   */
-  String post(String url, String postData) throws WxErrorException;
-
-  /**
-   * 内部使用.
-   *
-   * @param url        接口地址
-   * @param jsonObject 请求body的json对象
-   * @return the string
-   * @throws WxErrorException the wx error exception
-   */
-  String post(String url, JsonObject jsonObject) throws WxErrorException;
-
-  /**
-   * 内部使用.
-   *
-   * @param url 接口地址
-   * @param obj 请求body的对象,实现了ToJson接口
-   * @return the string
-   * @throws WxErrorException the wx error exception
-   */
-  String post(String url, ToJson obj) throws WxErrorException;
-
   /**
    * 当不需要自动带accessToken的时候,可以用这个发起post请求
    *
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index 092e48eb6..d356819e0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -222,6 +222,11 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
     return this.post(url, obj.toJson());
   }
 
+  @Override
+  public String post(String url, Object obj) throws WxErrorException {
+    return this.post(url, obj.toString());
+  }
+
   @Override
   public String postWithoutToken(String url, String postData) throws WxErrorException {
     return this.executeNormal(SimplePostRequestExecutor.create(this), url, postData);
@@ -319,7 +324,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
       return null;
     } catch (IOException e) {
       log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uri, data, e.getMessage());
-      throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).errorCode(-1).build(), e);
+      throw new WxErrorException(e);
     }
   }
 
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java
index 9f9cec331..f8f43cb81 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java
@@ -58,8 +58,7 @@ public class WxCpOaCalendarServiceImplTest {
 
   @Test
   public void testGet() throws WxErrorException {
-    final List calendars = this.wxService.getOaCalendarService()
-      .get(Arrays.asList(calId));
+    final List calendars = this.wxService.getOaCalendarService().get(Arrays.asList(calId));
     assertThat(calendars).isNotEmpty();
   }
 
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java
index e155fea0d..492f8a9e1 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java
@@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.api.WxImgProcService;
 import me.chanjar.weixin.common.api.WxOcrService;
+import me.chanjar.weixin.common.bean.ToJson;
 import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.enums.WxType;
 import me.chanjar.weixin.common.error.WxError;
@@ -186,7 +187,15 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
   public String post(String url, Object obj) throws WxErrorException {
     return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
   }
+  @Override
+  public String post(String url, ToJson obj) throws WxErrorException {
+    return this.post(url, obj.toJson());
+  }
 
+  @Override
+  public String post(String url, JsonObject jsonObject) throws WxErrorException {
+    return this.post(url, jsonObject.toString());
+  }
   /**
    * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
    */
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaOcrServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaOcrServiceImpl.java
index 8106dcd6c..edc5a363c 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaOcrServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaOcrServiceImpl.java
@@ -43,7 +43,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
       // ignore cannot happen
     }
 
-    final String result = this.mainService.post(String.format(IDCARD, imgUrl), null);
+    final String result = this.mainService.post(String.format(IDCARD, imgUrl), (String) null);
     return WxOcrIdCardResult.fromJson(result);
   }
 
@@ -62,7 +62,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
       // ignore cannot happen
     }
 
-    final String result = this.mainService.post(String.format(BANK_CARD, imgUrl), null);
+    final String result = this.mainService.post(String.format(BANK_CARD, imgUrl), (String) null);
     return WxOcrBankCardResult.fromJson(result);
   }
 
@@ -81,7 +81,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
       // ignore cannot happen
     }
 
-    final String result = this.mainService.post(String.format(DRIVING, imgUrl), null);
+    final String result = this.mainService.post(String.format(DRIVING, imgUrl), (String) null);
     return WxOcrDrivingResult.fromJson(result);
   }
 
@@ -100,7 +100,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
       // ignore cannot happen
     }
 
-    final String result = this.mainService.post(String.format(DRIVING_LICENSE, imgUrl), null);
+    final String result = this.mainService.post(String.format(DRIVING_LICENSE, imgUrl), (String) null);
     return WxOcrDrivingLicenseResult.fromJson(result);
   }
 
@@ -119,7 +119,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
       // ignore cannot happen
     }
 
-    final String result = this.mainService.post(String.format(BIZ_LICENSE, imgUrl), null);
+    final String result = this.mainService.post(String.format(BIZ_LICENSE, imgUrl), (String) null);
     return WxOcrBizLicenseResult.fromJson(result);
   }
 
@@ -138,7 +138,7 @@ public class WxMaOcrServiceImpl implements WxOcrService {
       // ignore cannot happen
     }
 
-    final String result = this.mainService.post(String.format(COMM, imgUrl), null);
+    final String result = this.mainService.post(String.format(COMM, imgUrl), (String) null);
     return WxOcrCommResult.fromJson(result);
   }
 
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideService.java
new file mode 100644
index 000000000..372589c82
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGuideService.java
@@ -0,0 +1,54 @@
+package me.chanjar.weixin.mp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.guide.WxMpGuideInfo;
+
+/**
+ * 微信导购助手(现在叫对话能力)接口.
+ *
+ * @author Binary Wang
+ * @date 2020 -10-06
+ */
+public interface WxMpGuideService {
+  /**
+   * 为服务号添加顾问
+   * 
+   * 请求地址: POST https://api.weixin.qq.com/cgi-bin/guide/addguideacct?access_token=ACCESS_TOKEN
+   * 文档地址:https://developers.weixin.qq.com/doc/offiaccount/Shopping_Guide/guide-account/shopping-guide.addGuideAcct.html
+   * 
+ * + * @param account 顾问微信号(guide_account和guide_openid二选一,若同时请求,默认为guide_account) + * @param openid 顾问openid或者unionid(guide_account和guide_openid二选一) + * @param headImgUrl 顾问头像,头像url只能用《上传图文消息内的图片获取URL》 me.chanjar.weixin.mp.api.impl.WxMpMaterialServiceImpl#mediaImgUpload(java.io.File) + * @param nickName 顾问昵称 + * @throws WxErrorException . + */ + void addGuide(String account, String openid, String headImgUrl, String nickName) throws WxErrorException; + + /** + * 为服务号添加顾问 + *
+   * 请求地址: POST https://api.weixin.qq.com/cgi-bin/guide/addguideacct?access_token=ACCESS_TOKEN
+   * 文档地址:https://developers.weixin.qq.com/doc/offiaccount/Shopping_Guide/guide-account/shopping-guide.addGuideAcct.html
+   * 
+ * + * @param guideInfo 顾问信息 + * @throws WxErrorException . + */ + void addGuide(WxMpGuideInfo guideInfo) throws WxErrorException; + + /** + * 获取顾问信息 + * + *
+   * 请求地址:  POST https://api.weixin.qq.com/cgi-bin/guide/getguideacct?access_token=ACCESS_TOKEN
+   * 文档地址:https://developers.weixin.qq.com/doc/offiaccount/Shopping_Guide/guide-account/shopping-guide.getGuideAcct.html
+   * 
+ * + * @param account 顾问微信号(guide_account和guide_openid二选一,若同时请求,默认为guide_account) + * @param openid 顾问openid或者unionid(guide_account和guide_openid二选一) + * @return 顾问信息 + * @throws WxErrorException . + */ + WxMpGuideInfo getGuide(String account, String openid) throws WxErrorException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 958e7f730..50c6e48ba 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.api; +import com.google.gson.JsonObject; import me.chanjar.weixin.common.api.WxImgProcService; import me.chanjar.weixin.common.api.WxOcrService; import me.chanjar.weixin.common.bean.WxJsapiSignature; @@ -33,16 +34,16 @@ public interface WxMpService extends WxService { * @param timestamp 时间戳 * @param nonce 随机串 * @param signature 签名 - * @return 是否验证通过 + * @return 是否验证通过 boolean */ boolean checkSignature(String timestamp, String nonce, String signature); /** * 获取access_token, 不强制刷新access_token. * - * @return token + * @return token access token * @throws WxErrorException . - * @see #getAccessToken(boolean) + * @see #getAccessToken(boolean) #getAccessToken(boolean) */ String getAccessToken() throws WxErrorException; @@ -59,7 +60,7 @@ public interface WxMpService extends WxService { *
* * @param forceRefresh 是否强制刷新 - * @return token + * @return token access token * @throws WxErrorException . */ String getAccessToken(boolean forceRefresh) throws WxErrorException; @@ -68,9 +69,9 @@ public interface WxMpService extends WxService { * 获得ticket,不强制刷新ticket. * * @param type ticket 类型 - * @return ticket + * @return ticket ticket * @throws WxErrorException . - * @see #getTicket(TicketType, boolean) + * @see #getTicket(TicketType, boolean) #getTicket(TicketType, boolean) */ String getTicket(TicketType type) throws WxErrorException; @@ -82,7 +83,7 @@ public interface WxMpService extends WxService { * * @param type ticket类型 * @param forceRefresh 强制刷新 - * @return ticket + * @return ticket ticket * @throws WxErrorException . */ String getTicket(TicketType type, boolean forceRefresh) throws WxErrorException; @@ -92,7 +93,7 @@ public interface WxMpService extends WxService { * * @return jsapi ticket * @throws WxErrorException . - * @see #getJsapiTicket(boolean) + * @see #getJsapiTicket(boolean) #getJsapiTicket(boolean) */ String getJsapiTicket() throws WxErrorException; @@ -118,7 +119,7 @@ public interface WxMpService extends WxService { * * * @param url 地址 - * @return 生成的签名对象 + * @return 生成的签名对象 wx jsapi signature * @throws WxErrorException . */ WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; @@ -130,7 +131,7 @@ public interface WxMpService extends WxService { * * * @param longUrl 长url - * @return 生成的短地址 + * @return 生成的短地址 string * @throws WxErrorException . */ String shortUrl(String longUrl) throws WxErrorException; @@ -142,7 +143,7 @@ public interface WxMpService extends WxService { * * * @param semanticQuery 查询条件 - * @return 查询结果 + * @return 查询结果 wx mp semantic query result * @throws WxErrorException . */ WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; @@ -167,7 +168,7 @@ public interface WxMpService extends WxService { * http://mp.weixin.qq.com/wiki/0/2ad4b6bfd29f30f71d39616c2a0fcedc.html * * - * @return 微信服务器ip地址数组 + * @return 微信服务器ip地址数组 string [ ] * @throws WxErrorException . */ String[] getCallbackIP() throws WxErrorException; @@ -181,7 +182,7 @@ public interface WxMpService extends WxService { * * @param action 执行的检测动作 * @param operator 指定平台从某个运营商进行检测 - * @return 检测结果 + * @return 检测结果 wx net check result * @throws WxErrorException . */ WxNetCheckResult netCheck(String action, String operator) throws WxErrorException; @@ -202,7 +203,7 @@ public interface WxMpService extends WxService { * https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=ACCESS_TOKEN * * - * @return 公众号的自动回复规则 + * @return 公众号的自动回复规则 current auto reply info * @throws WxErrorException . */ WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException; @@ -232,7 +233,7 @@ public interface WxMpService extends WxService { * @param executor 执行器 * @param url 接口地址 * @param data 参数数据 - * @return 结果 + * @return 结果 t * @throws WxErrorException 异常 */ T execute(RequestExecutor executor, String url, E data) throws WxErrorException; @@ -242,7 +243,7 @@ public interface WxMpService extends WxService { * * @param url 请求接口地址 * @param queryParam 参数 - * @return 接口响应字符串 + * @return 接口响应字符串 string * @throws WxErrorException 异常 */ String get(WxMpApiUrl url, String queryParam) throws WxErrorException; @@ -252,11 +253,21 @@ public interface WxMpService extends WxService { * * @param url 请求接口地址 * @param postData 请求参数json值 - * @return 接口响应字符串 + * @return 接口响应字符串 string * @throws WxErrorException 异常 */ String post(WxMpApiUrl url, String postData) throws WxErrorException; + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. + * + * @param url 请求接口地址 + * @param jsonObject 请求参数json对象 + * @return 接口响应字符串 string + * @throws WxErrorException 异常 + */ + String post(WxMpApiUrl url, JsonObject jsonObject) throws WxErrorException; + /** *
    * Service没有实现某个API的时候,可以用这个,
@@ -269,7 +280,7 @@ public interface WxMpService extends WxService {
    * @param executor 执行器
    * @param url      接口地址
    * @param data     参数数据
-   * @return 结果
+   * @return 结果 t
    * @throws WxErrorException 异常
    */
    T execute(RequestExecutor executor, WxMpApiUrl url, E data) throws WxErrorException;
@@ -294,7 +305,7 @@ public interface WxMpService extends WxService {
   /**
    * 获取WxMpConfigStorage 对象.
    *
-   * @return WxMpConfigStorage
+   * @return WxMpConfigStorage wx mp config storage
    */
   WxMpConfigStorage getWxMpConfigStorage();
 
@@ -340,7 +351,7 @@ public interface WxMpService extends WxService {
    * 进行相应的公众号切换.
    *
    * @param mpId 公众号标识
-   * @return 切换是否成功
+   * @return 切换是否成功 boolean
    */
   boolean switchover(String mpId);
 
@@ -348,119 +359,119 @@ public interface WxMpService extends WxService {
    * 进行相应的公众号切换.
    *
    * @param mpId 公众号标识
-   * @return 切换成功,则返回当前对象,方便链式调用,否则抛出异常
+   * @return 切换成功 ,则返回当前对象,方便链式调用,否则抛出异常
    */
   WxMpService switchoverTo(String mpId);
 
   /**
    * 返回客服接口方法实现类,以方便调用其各个接口.
    *
-   * @return WxMpKefuService
+   * @return WxMpKefuService kefu service
    */
   WxMpKefuService getKefuService();
 
   /**
    * 返回素材相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpMaterialService
+   * @return WxMpMaterialService material service
    */
   WxMpMaterialService getMaterialService();
 
   /**
    * 返回菜单相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpMenuService
+   * @return WxMpMenuService menu service
    */
   WxMpMenuService getMenuService();
 
   /**
    * 返回用户相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpUserService
+   * @return WxMpUserService user service
    */
   WxMpUserService getUserService();
 
   /**
    * 返回用户标签相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpUserTagService
+   * @return WxMpUserTagService user tag service
    */
   WxMpUserTagService getUserTagService();
 
   /**
    * 返回二维码相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpQrcodeService
+   * @return WxMpQrcodeService qrcode service
    */
   WxMpQrcodeService getQrcodeService();
 
   /**
    * 返回卡券相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpCardService
+   * @return WxMpCardService card service
    */
   WxMpCardService getCardService();
 
   /**
    * 返回数据分析统计相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpDataCubeService
+   * @return WxMpDataCubeService data cube service
    */
   WxMpDataCubeService getDataCubeService();
 
   /**
    * 返回用户黑名单管理相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpUserBlacklistService
+   * @return WxMpUserBlacklistService black list service
    */
   WxMpUserBlacklistService getBlackListService();
 
   /**
    * 返回门店管理相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpStoreService
+   * @return WxMpStoreService store service
    */
   WxMpStoreService getStoreService();
 
   /**
    * 返回模板消息相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpTemplateMsgService
+   * @return WxMpTemplateMsgService template msg service
    */
   WxMpTemplateMsgService getTemplateMsgService();
 
   /**
    * 返回一次性订阅消息相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpSubscribeMsgService
+   * @return WxMpSubscribeMsgService subscribe msg service
    */
   WxMpSubscribeMsgService getSubscribeMsgService();
 
   /**
    * 返回硬件平台相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpDeviceService
+   * @return WxMpDeviceService device service
    */
   WxMpDeviceService getDeviceService();
 
   /**
    * 返回摇一摇周边相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpShakeService
+   * @return WxMpShakeService shake service
    */
   WxMpShakeService getShakeService();
 
   /**
    * 返回会员卡相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpMemberCardService
+   * @return WxMpMemberCardService member card service
    */
   WxMpMemberCardService getMemberCardService();
 
   /**
    * 返回营销相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpMarketingService
+   * @return WxMpMarketingService marketing service
    */
   WxMpMarketingService getMarketingService();
 
@@ -472,42 +483,42 @@ public interface WxMpService extends WxService {
   /**
    * 获取RequestHttp对象.
    *
-   * @return RequestHttp对象
+   * @return RequestHttp对象 request http
    */
   RequestHttp getRequestHttp();
 
   /**
    * 返回群发消息相关接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpMassMessageService
+   * @return WxMpMassMessageService mass message service
    */
   WxMpMassMessageService getMassMessageService();
 
   /**
    * 返回AI开放接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpAiOpenService
+   * @return WxMpAiOpenService ai open service
    */
   WxMpAiOpenService getAiOpenService();
 
   /**
    * 返回WIFI接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpWifiService
+   * @return WxMpWifiService wifi service
    */
   WxMpWifiService getWifiService();
 
   /**
    * 返回WIFI接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpWifiService
+   * @return WxMpWifiService ocr service
    */
   WxOcrService getOcrService();
 
   /**
    * 返回图像处理接口的实现类对象,以方便调用其各个接口.
    *
-   * @return WxImgProcService
+   * @return WxImgProcService img proc service
    */
   WxImgProcService getImgProcService();
 
@@ -647,7 +658,7 @@ public interface WxMpService extends WxService {
   /**
    * 返回评论数据管理接口方法的实现类对象,以方便调用其各个接口.
    *
-   * @return WxMpWifiService
+   * @return WxMpWifiService comment service
    */
   WxMpCommentService getCommentService();
 
@@ -671,4 +682,18 @@ public interface WxMpService extends WxService {
    * @param oAuth2Service the o auth 2 service
    */
   void setOAuth2Service(WxOAuth2Service oAuth2Service);
+
+  /**
+   * Gets guide service.
+   *
+   * @return the guide service
+   */
+  WxMpGuideService getGuideService();
+
+  /**
+   * Sets guide service.
+   *
+   * @param guideService the guide service
+   */
+  void setGuideService(WxMpGuideService guideService);
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
index 966ddc4c0..6fe921fb8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java
@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.api.WxImgProcService;
 import me.chanjar.weixin.common.api.WxOcrService;
+import me.chanjar.weixin.common.bean.ToJson;
 import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.bean.WxJsapiSignature;
 import me.chanjar.weixin.common.bean.WxNetCheckResult;
@@ -119,6 +120,10 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
   @Setter
   private WxMpMerchantInvoiceService merchantInvoiceService = new WxMpMerchantInvoiceServiceImpl(this, this.cardService);
 
+  @Getter
+  @Setter
+  private WxMpGuideService guideService = new WxMpGuideServiceImpl(this);
+
   @Getter
   @Setter
   private WxOAuth2Service oAuth2Service = new WxOAuth2ServiceImpl(this);
@@ -278,6 +283,21 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
     return this.post(url.getUrl(this.getWxMpConfigStorage()), postData);
   }
 
+  @Override
+  public String post(WxMpApiUrl url, JsonObject jsonObject) throws WxErrorException {
+    return this.post(url.getUrl(this.getWxMpConfigStorage()), jsonObject.toString());
+  }
+
+  @Override
+  public String post(String url, ToJson obj) throws WxErrorException {
+    return this.post(url, obj.toJson());
+  }
+
+  @Override
+  public String post(String url, JsonObject jsonObject) throws WxErrorException {
+    return this.post(url, jsonObject.toString());
+  }
+
   @Override
   public String post(String url, Object obj) throws WxErrorException {
     return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
@@ -366,7 +386,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
       return null;
     } catch (IOException e) {
       log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
-      throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e);
+      throw new WxErrorException(e);
     }
   }
 
@@ -475,4 +495,13 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH
     return this;
   }
 
+  @Override
+  public WxMpGuideService getGuideService() {
+    return this.guideService;
+  }
+
+  @Override
+  public void setGuideService(WxMpGuideService guideService) {
+    this.guideService = guideService;
+  }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideServiceImpl.java
new file mode 100644
index 000000000..6e6f71a7c
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpGuideServiceImpl.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.mp.api.impl;
+
+import lombok.AllArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.json.GsonHelper;
+import me.chanjar.weixin.mp.api.WxMpGuideService;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.guide.WxMpGuideInfo;
+import me.chanjar.weixin.mp.enums.WxMpApiUrl;
+
+/**
+ * .
+ *
+ * @author Binary Wang
+ * @date 2020-10-06
+ */
+@AllArgsConstructor
+public class WxMpGuideServiceImpl implements WxMpGuideService {
+  private static final String ACCOUNT = "guide_account";
+  private static final String OPENID = "guide_openid";
+  private final WxMpService mpService;
+
+  @Override
+  public void addGuide(String account, String openid, String headImgUrl, String nickName) throws WxErrorException {
+    this.mpService.post(WxMpApiUrl.Guide.ADD_GUIDE, GsonHelper.buildJsonObject(ACCOUNT, account,
+      "guide_headimgurl", headImgUrl, "guide_nickname", nickName, OPENID, openid));
+  }
+
+  @Override
+  public void addGuide(WxMpGuideInfo guideInfo) throws WxErrorException {
+    this.mpService.post(WxMpApiUrl.Guide.ADD_GUIDE,
+      GsonHelper.buildJsonObject(ACCOUNT, guideInfo.getAccount(),
+        "guide_headimgurl", guideInfo.getHeadImgUrl(),
+        "guide_nickname", guideInfo.getNickName(),
+        OPENID, guideInfo.getOpenid()));
+  }
+
+  @Override
+  public WxMpGuideInfo getGuide(String account, String openid) throws WxErrorException {
+    return WxMpGuideInfo.fromJson(this.mpService.post(WxMpApiUrl.Guide.GET_GUIDE,
+      GsonHelper.buildJsonObject(ACCOUNT, account, OPENID, openid)));
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java
index f6748b564..d4286b617 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpOcrServiceImpl.java
@@ -1,34 +1,18 @@
 package me.chanjar.weixin.mp.api.impl;
 
 import lombok.RequiredArgsConstructor;
-import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.api.WxOcrService;
-import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.common.bean.ocr.WxOcrBankCardResult;
-import me.chanjar.weixin.common.bean.ocr.WxOcrBizLicenseResult;
-import me.chanjar.weixin.common.bean.ocr.WxOcrCommResult;
-import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingLicenseResult;
-import me.chanjar.weixin.common.bean.ocr.WxOcrDrivingResult;
-import me.chanjar.weixin.common.bean.ocr.WxOcrIdCardResult;
+import me.chanjar.weixin.common.bean.ocr.*;
+import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.requestexecuter.ocr.OcrDiscernRequestExecutor;
+import me.chanjar.weixin.mp.api.WxMpService;
 
 import java.io.File;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.BANK_CARD;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.BIZ_LICENSE;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.COMM;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.DRIVING;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.DRIVING_LICENSE;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILEIDCARD;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_BANK_CARD;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_BIZ_LICENSE;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_COMM;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_DRIVING;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.FILE_DRIVING_LICENSE;
-import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.IDCARD;
+import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Ocr.*;
 
 /**
  * ocr 接口实现.
@@ -49,7 +33,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
     }
 
     final String result = this.mainService.post(String.format(IDCARD.getUrl(this.mainService.getWxMpConfigStorage()),
-      imgUrl), null);
+      imgUrl), (String) null);
     return WxOcrIdCardResult.fromJson(result);
   }
 
@@ -69,7 +53,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
     }
 
     final String result = this.mainService.post(String.format(BANK_CARD.getUrl(this.mainService.getWxMpConfigStorage()),
-      imgUrl), null);
+      imgUrl), (String) null);
     return WxOcrBankCardResult.fromJson(result);
   }
 
@@ -89,7 +73,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
     }
 
     final String result = this.mainService.post(String.format(DRIVING.getUrl(this.mainService.getWxMpConfigStorage()),
-      imgUrl), null);
+      imgUrl), (String) null);
     return WxOcrDrivingResult.fromJson(result);
   }
 
@@ -109,7 +93,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
     }
 
     final String result = this.mainService.post(String.format(DRIVING_LICENSE.getUrl(this.mainService.getWxMpConfigStorage()),
-      imgUrl), null);
+      imgUrl), (String) null);
     return WxOcrDrivingLicenseResult.fromJson(result);
   }
 
@@ -129,7 +113,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
     }
 
     final String result = this.mainService.post(String.format(BIZ_LICENSE.getUrl(this.mainService.getWxMpConfigStorage()),
-      imgUrl), null);
+      imgUrl), (String) null);
     return WxOcrBizLicenseResult.fromJson(result);
   }
 
@@ -149,7 +133,7 @@ public class WxMpOcrServiceImpl implements WxOcrService {
     }
 
     final String result = this.mainService.post(String.format(COMM.getUrl(this.mainService.getWxMpConfigStorage()),
-      imgUrl), null);
+      imgUrl), (String) null);
     return WxOcrCommResult.fromJson(result);
   }
 
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/guide/WxMpGuideInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/guide/WxMpGuideInfo.java
new file mode 100644
index 000000000..b20b743ab
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/guide/WxMpGuideInfo.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.mp.bean.guide;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import me.chanjar.weixin.common.bean.ToJson;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * 对话能力-顾问信息.
+ *
+ * @author Binary Wang
+ * @date 2020-10-06
+ */
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMpGuideInfo implements ToJson, Serializable {
+  private static final long serialVersionUID = -8159470115679031290L;
+
+  /**
+   * 顾问的微信帐号
+   */
+  @SerializedName("guide_account")
+  private String account;
+
+  /**
+   * 顾问的openid或者unionid
+   */
+  @SerializedName("guide_openid")
+  private String openid;
+
+  /**
+   * 顾问昵称
+   */
+  @SerializedName("guide_nickname")
+  private String nickName;
+
+  /**
+   * 顾问头像
+   */
+  @SerializedName("guide_headimgurl")
+  private String headImgUrl;
+
+  /**
+   * 顾问状态(1:确认中;2已确认;3已拒绝;4已过期)
+   */
+  @SerializedName("status")
+  private Integer status;
+
+  @Override
+  public String toJson() {
+    return WxGsonBuilder.create().toJson(this);
+  }
+
+  public static WxMpGuideInfo fromJson(String json) {
+    return WxGsonBuilder.create().fromJson(json, WxMpGuideInfo.class);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
index 7e1086765..9a5c9a965 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
@@ -1156,4 +1156,31 @@ public interface WxMpApiUrl {
       return buildUrl(config.getHostConfig(), prefix, path);
     }
   }
+
+  /**
+   * 对话能力
+   */
+  @AllArgsConstructor
+  enum Guide implements WxMpApiUrl {
+    /**
+     * 添加顾问
+     */
+    ADD_GUIDE(API_DEFAULT_HOST_URL, "/cgi-bin/guide/addguideacct"),
+
+    /**
+     * 获取顾问信息
+     */
+    GET_GUIDE(API_DEFAULT_HOST_URL, "/cgi-bin/guide/getguideacct");
+    private final String prefix;
+    private final String path;
+
+    @Override
+    public String getUrl(WxMpConfigStorage config) {
+      if (null == config) {
+        return buildUrl(null, prefix, path);
+      }
+
+      return buildUrl(config.getHostConfig(), prefix, path);
+    }
+  }
 }
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpGuideServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpGuideServiceImplTest.java
new file mode 100644
index 000000000..28b28caef
--- /dev/null
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpGuideServiceImplTest.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.mp.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.test.ApiTestModule;
+import me.chanjar.weixin.mp.bean.guide.WxMpGuideInfo;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * 单元测试.
+ *
+ * @author Binary Wang
+ * @date 2020-10-06
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxMpGuideServiceImplTest {
+  @Inject
+  protected WxMpService wxService;
+
+  @Test
+  public void testAddGuide() throws WxErrorException {
+    this.wxService.getGuideService().addGuide("abc", "", null, null);
+  }
+
+  @Test
+  public void testAddGuide_another() throws WxErrorException {
+    this.wxService.getGuideService().addGuide(WxMpGuideInfo.builder().account("cde").build());
+  }
+
+  @Test
+  public void testGetGuide() throws WxErrorException {
+    final WxMpGuideInfo guideInfo = this.wxService.getGuideService().getGuide("abc", null);
+    assertThat(guideInfo).isNotNull();
+  }
+}