小程序私信接口提交

This commit is contained in:
danmo 2024-04-18 14:07:48 +08:00
parent 27a934836c
commit 236fa662c0
37 changed files with 1276 additions and 39 deletions

View File

@ -3,8 +3,10 @@ package com.dyj.applet;
import com.dyj.applet.domain.query.CreateQrCodeQuery;
import com.dyj.applet.domain.query.GenerateSchemaQuery;
import com.dyj.applet.domain.query.GenerateUrlLinkQuery;
import com.dyj.applet.domain.query.SendMsgQuery;
import com.dyj.applet.domain.vo.*;
import com.dyj.applet.handler.AppletTokenHandler;
import com.dyj.applet.handler.ChatMsgHandler;
import com.dyj.applet.handler.LoginHandler;
import com.dyj.applet.handler.SchemaHandler;
import com.dyj.common.client.BaseClient;
@ -123,9 +125,10 @@ public class DyAppletClient extends BaseClient {
/**
* code2Session
* @param code login 接口返回的登录凭证
*
* @param code login 接口返回的登录凭证
* @param anonymousCode login 接口返回的匿名登录凭证
* @return DySimpleResult<Code2SessionVo>
* @return DySimpleResult<Code2SessionVo>
*/
public DySimpleResult<Code2SessionVo> code2Session(String code, String anonymousCode) {
return new LoginHandler(configuration().getAgentConfigService().loadAgentByTenantId(tenantId, clientKey)).code2Session(code, anonymousCode);
@ -202,4 +205,61 @@ public class DyAppletClient extends BaseClient {
public DySimpleResult<QrCodeVo> createQrCode(CreateQrCodeQuery query) {
return new SchemaHandler(configuration().getAgentConfigService().loadAgentByTenantId(tenantId, clientKey)).createQrCode(query);
}
}
/**
* 发送私信消息
*
* @param query 入参
* @return ChatMsgResponseVo
*/
public SendMsgResponseVo sendMessage(SendMsgQuery query) {
return new ChatMsgHandler(configuration().getAgentByTenantId(tenantId, clientKey)).sendMessage(query);
}
/**
* 发送主动私信
*
* @param query 入参
* @return DySimpleResult<AuthSendMsgVo>
*/
public DySimpleResult<AuthSendMsgVo> authSendMsg(SendMsgQuery query) {
return new ChatMsgHandler(configuration().getAgentByTenantId(tenantId, clientKey)).authSendMsg(query);
}
/**
* 查询主动私信用户授权状态
*
* @param openId 用户ID
* @param cOpenId C端用户的open_id
* @param appId C端用户open_id所在的小程序 可不传
* @return DySimpleResult<ImAuthStatusVo>
*/
public DySimpleResult<ImAuthStatusVo> queryImAuthStatus(String openId, String cOpenId, String appId) {
return new ChatMsgHandler(configuration().getAgentByTenantId(tenantId, clientKey)).queryImAuthStatus(openId, cOpenId, appId);
}
/**
* 查询授权主动私信用户
*
* @param openId 用户ID
* @param pageNum 页码
* @param pageSize 每页数量
* @return DySimpleResult<ImAuthUserListVo>
*/
public DySimpleResult<ImAuthUserListVo> queryAuthorizeUserList(String openId, Long pageNum, Long pageSize) {
return new ChatMsgHandler(configuration().getAgentByTenantId(tenantId, clientKey)).queryAuthorizeUserList(openId, pageNum, pageSize);
}
/**
* 私信消息撤回
*
* @param openId 用户ID
* @param msgId 消息ID
* @param conversationId 会话 ID来源于私信 webhook接收私信消息事件对应 webhook content 里的conversation_short_id 字段
* @param conversationType 会话类型 1- 单聊 2- 群聊
* @return DyResult<BaseVo>
*/
public DyResult<BaseVo> revokeMessage(String openId, String msgId, String conversationId, Integer conversationType) {
return new ChatMsgHandler(configuration().getAgentByTenantId(tenantId, clientKey)).revokeMessage(openId, msgId, conversationId, conversationType);
}
}

View File

@ -1,9 +1,9 @@
package com.dyj.applet.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.Header;
import com.dtflys.forest.annotation.Post;
import com.dtflys.forest.backend.ContentType;
import com.dyj.common.interceptor.BizTokenHeaderInterceptor;
import com.dyj.common.domain.DyAppletResult;
import java.util.List;
@ -18,6 +18,6 @@ public interface BsClient {
/**
* 经营能力当前状态查询
*/
@Post(value = "${businessScopes}", contentType = ContentType.APPLICATION_JSON ,interceptor = BizTokenHeaderInterceptor.class)
DyAppletResult<List<String>> getBusinessScopes();
@Post(value = "${businessScopes}", contentType = ContentType.APPLICATION_JSON)
DyAppletResult<List<String>> getBusinessScopes(@Header("access-token") String accessToken);
}

View File

@ -1,7 +1,20 @@
package com.dyj.applet.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.JSONBody;
import com.dtflys.forest.annotation.Post;
import com.dtflys.forest.backend.ContentType;
import com.dyj.applet.domain.query.ImAuthStatusQuery;
import com.dyj.applet.domain.query.ImAuthorizeUserListQuery;
import com.dyj.applet.domain.query.RevokeMsgQuery;
import com.dyj.applet.domain.query.SendMsgQuery;
import com.dyj.applet.domain.vo.AuthSendMsgVo;
import com.dyj.applet.domain.vo.ImAuthStatusVo;
import com.dyj.applet.domain.vo.ImAuthUserListVo;
import com.dyj.applet.domain.vo.SendMsgResponseVo;
import com.dyj.common.domain.DyResult;
import com.dyj.common.domain.DySimpleResult;
import com.dyj.common.domain.vo.BaseVo;
import com.dyj.common.interceptor.BizTokenHeaderInterceptor;
/**
@ -13,5 +26,47 @@ import com.dyj.common.interceptor.BizTokenHeaderInterceptor;
@BaseRequest(baseURL = "${domain}", contentType = ContentType.APPLICATION_JSON, interceptor = BizTokenHeaderInterceptor.class)
public interface ChatMsgClient {
/**
* 发送私信消息
*
* @param query 入参
* @return ChatMsgResponseVo
*/
@Post(url = "${sendMessage}")
SendMsgResponseVo sendMessage(@JSONBody SendMsgQuery query);
/**
* 发送主动私信
* @param query 入参
* @return DySimpleResult<AuthSendMsgVo>
*/
@Post(url = "${authSendMsg}")
DySimpleResult<AuthSendMsgVo> authSendMsg(@JSONBody SendMsgQuery query);
/**
* 查询主动私信用户授权状态
* @param query 入参
* @return DySimpleResult<ImAuthStatusVo>
*/
@Post(url = "${imAuthStatus}")
DySimpleResult<ImAuthStatusVo> queryImAuthStatus(@JSONBody ImAuthStatusQuery query);
/**
* 查询授权主动私信用户
*
* @param query
* @return DyResult<AuthorizeUserListVo>
*/
@Post(url = "${queryAuthorizeUserList}")
DySimpleResult<ImAuthUserListVo> queryAuthorizeUserList(@JSONBody ImAuthorizeUserListQuery query);
/**
* 私信消息撤回
*
* @param query 包含消息查询条件的对象用于指定要撤销的消息
* @return 返回一个动态结果对象其中包含操作的结果信息
*/
@Post(url = "${revokeMessage}")
DyResult<BaseVo> revokeMessage(@JSONBody RevokeMsgQuery query);
}

View File

@ -0,0 +1,95 @@
package com.dyj.applet.domain;
/**
* 授权归因不同的授权来源对应不同的归因字段
* @author danmo
* @date 2024-04-08 17:23
**/
public class AuthAttribution {
/**
* 主播id
*/
private String anchor_id;
/**
* 作者id
*/
private String author_id;
/**
* 群聊id
*/
private String conversation_id;
/**
* 消息发送者id
*/
private String from_att_uid;
/**
* 群id
*/
private String group_id;
/**
* 消息id
*/
private String message_id;
/**
* 直播房间id
*/
private String room_id;
public String getAnchor_id() {
return anchor_id;
}
public void setAnchor_id(String anchor_id) {
this.anchor_id = anchor_id;
}
public String getAuthor_id() {
return author_id;
}
public void setAuthor_id(String author_id) {
this.author_id = author_id;
}
public String getConversation_id() {
return conversation_id;
}
public void setConversation_id(String conversation_id) {
this.conversation_id = conversation_id;
}
public String getFrom_att_uid() {
return from_att_uid;
}
public void setFrom_att_uid(String from_att_uid) {
this.from_att_uid = from_att_uid;
}
public String getGroup_id() {
return group_id;
}
public void setGroup_id(String group_id) {
this.group_id = group_id;
}
public String getMessage_id() {
return message_id;
}
public void setMessage_id(String message_id) {
this.message_id = message_id;
}
public String getRoom_id() {
return room_id;
}
public void setRoom_id(String room_id) {
this.room_id = room_id;
}
}

View File

@ -35,4 +35,40 @@ public class ColorRGB {
public void setB(Integer b) {
this.b = b;
}
public static ColorRGBBuilder builder() {
return new ColorRGBBuilder();
}
public static class ColorRGBBuilder {
private Integer r;
private Integer g;
private Integer b;
public ColorRGBBuilder r
(Integer r) {
this.r = r;
return this;
}
public ColorRGBBuilder g
(Integer g) {
this.g = g;
return this;
}
public ColorRGBBuilder b
(Integer b) {
this.b = b;
return this;
}
public ColorRGB build() {
ColorRGB colorRGB = new ColorRGB();
colorRGB.setR(r);
colorRGB.setG(g);
colorRGB.setB(b);
return colorRGB;
}
}
}

View File

@ -0,0 +1,106 @@
package com.dyj.applet.domain;
/**
* @author danmo
* @date 2024-04-08 17:20
**/
public class ImAuthUser {
/**
* 授权来源
* micro_app 小程序
* button组件
* im_card 服务私信授权卡片
* action_bar 会话页快捷入口
* live_shelf_panel 直播间货架入口
* micro_app_pendant 小程序内免研悬浮组件
* mp_follow_account 小程序内关注后拉起主动私信授权
*/
private String enter_from;
/**
* C 端用户授权来源小程序
*/
private String auth_user_source_app_id;
/**
* 开发者在主动私信授权组件中自定义参数
*/
private String data_im_extra;
/**
* 用户在获取用户私信授权组件授权服务账号所在小程序当前页面的path参数
*/
private String path;
/**
* 用户在获取用户私信授权组件中授权服务账号所在小程序当前页面的query参数
*/
private String query;
/**
* 使用调用应用加密的 open_id
*/
private String target_open_id;
/**
* 授权归因不同的授权来源对应不同的归因字段
*/
private AuthAttribution attribution;
public String getEnter_from() {
return enter_from;
}
public void setEnter_from(String enter_from) {
this.enter_from = enter_from;
}
public String getAuth_user_source_app_id() {
return auth_user_source_app_id;
}
public void setAuth_user_source_app_id(String auth_user_source_app_id) {
this.auth_user_source_app_id = auth_user_source_app_id;
}
public String getData_im_extra() {
return data_im_extra;
}
public void setData_im_extra(String data_im_extra) {
this.data_im_extra = data_im_extra;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public String getTarget_open_id() {
return target_open_id;
}
public void setTarget_open_id(String target_open_id) {
this.target_open_id = target_open_id;
}
public AuthAttribution getAttribution() {
return attribution;
}
public void setAttribution(AuthAttribution attribution) {
this.attribution = attribution;
}
}

View File

@ -21,4 +21,136 @@ public class CreateQrCodeQuery extends BaseQuery {
private ColorRGB line_color;
private ColorRGB background;
public String getApp_id() {
return app_id;
}
public void setApp_id(String app_id) {
this.app_id = app_id;
}
public String getApp_name() {
return app_name;
}
public void setApp_name(String app_name) {
this.app_name = app_name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Boolean getSet_icon() {
return set_icon;
}
public void setSet_icon(Boolean set_icon) {
this.set_icon = set_icon;
}
public ColorRGB getLine_color() {
return line_color;
}
public void setLine_color(ColorRGB line_color) {
this.line_color = line_color;
}
public ColorRGB getBackground() {
return background;
}
public void setBackground(ColorRGB background) {
this.background = background;
}
public static CreateQrCodeQueryBuilder builder() {
return new CreateQrCodeQueryBuilder();
}
public static class CreateQrCodeQueryBuilder {
private String appId;
private String appName;
private String path;
private Integer width;
private Boolean setIcon;
private ColorRGB lineColor;
private ColorRGB background;
private Integer tenantId;
private String clientKey;
public CreateQrCodeQueryBuilder appId(String appId) {
this.appId = appId;
return this;
}
public CreateQrCodeQueryBuilder appName(String appName) {
this.appName = appName;
return this;
}
public CreateQrCodeQueryBuilder path(String path) {
this.path = path;
return this;
}
public CreateQrCodeQueryBuilder width(Integer width) {
this.width = width;
return this;
}
public CreateQrCodeQueryBuilder setIcon(Boolean setIcon) {
this.setIcon = setIcon;
return this;
}
public CreateQrCodeQueryBuilder lineColor(ColorRGB lineColor) {
this.lineColor = lineColor;
return this;
}
public CreateQrCodeQueryBuilder background(ColorRGB background) {
this.background = background;
return this;
}
public CreateQrCodeQueryBuilder tenantId(Integer tenantId) {
this.tenantId = tenantId;
return this;
}
public CreateQrCodeQueryBuilder clientKey(String clientKey) {
this.clientKey = clientKey;
return this;
}
public CreateQrCodeQuery build() {
CreateQrCodeQuery createQrCodeQuery = new CreateQrCodeQuery();
createQrCodeQuery.setApp_id(appId);
createQrCodeQuery.setApp_name(appName);
createQrCodeQuery.setPath(path);
createQrCodeQuery.setWidth(width);
createQrCodeQuery.setSet_icon(setIcon);
createQrCodeQuery.setLine_color(lineColor);
createQrCodeQuery.setBackground(background);
createQrCodeQuery.setTenantId(tenantId);
createQrCodeQuery.setClientKey(clientKey);
return createQrCodeQuery;
}
}
}

View File

@ -0,0 +1,83 @@
package com.dyj.applet.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
/**
* @author danmo
* @date 2024-04-18 13:35
**/
public class ImAuthStatusQuery extends UserInfoQuery {
/**
* C端用户的open_id
*/
private String c_open_id;
/**
* C端用户open_id所在的小程序
*/
private String app_id;
public String getC_open_id() {
return c_open_id;
}
public void setC_open_id(String c_open_id) {
this.c_open_id = c_open_id;
}
public String getApp_id() {
return app_id;
}
public void setApp_id(String app_id) {
this.app_id = app_id;
}
public static ImAuthStatusQueryBuilder builder() {
return new ImAuthStatusQueryBuilder();
}
public static class ImAuthStatusQueryBuilder {
private String cOpenId;
private String appId;
private Integer tenantId;
private String clientKey;
private String openId;
public ImAuthStatusQueryBuilder cOpenId(String cOpenId) {
this.cOpenId = cOpenId;
return this;
}
public ImAuthStatusQueryBuilder appId(String appId) {
this.appId = appId;
return this;
}
public ImAuthStatusQueryBuilder tenantId(Integer tenantId) {
this.tenantId = tenantId;
return this;
}
public ImAuthStatusQueryBuilder clientKey(String clientKey) {
this.clientKey = clientKey;
return this;
}
public ImAuthStatusQueryBuilder openId(String openId) {
this.openId = openId;
return this;
}
public ImAuthStatusQuery build() {
ImAuthStatusQuery imAuthStatusQuery = new ImAuthStatusQuery();
imAuthStatusQuery.setC_open_id(cOpenId);
imAuthStatusQuery.setApp_id(appId);
imAuthStatusQuery.setTenantId(tenantId);
imAuthStatusQuery.setClientKey(clientKey);
imAuthStatusQuery.setOpen_id(openId);
return imAuthStatusQuery;
}
}
}

View File

@ -0,0 +1,85 @@
package com.dyj.applet.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
/**
* @author danmo
* @date 2024-04-08 17:16
**/
public class ImAuthorizeUserListQuery extends UserInfoQuery {
private Long page_num;
private Long page_size;
public Long getPage_num() {
return page_num;
}
public void setPage_num(Long page_num) {
this.page_num = page_num;
}
public Long getPage_size() {
return page_size;
}
public void setPage_size(Long page_size) {
this.page_size = page_size;
}
public static AuthorizeUserListQueryBuilder builder() {
return new AuthorizeUserListQueryBuilder();
}
public static class AuthorizeUserListQueryBuilder {
private Long pageNum;
private Long pageSize;
private String openId;
private String clientKey;
private Integer tenantId;
public AuthorizeUserListQueryBuilder pageNum(Long pageNum) {
this.pageNum = pageNum;
return this;
}
public AuthorizeUserListQueryBuilder pageSize(Long pageSize) {
this.pageSize = pageSize;
return this;
}
public AuthorizeUserListQueryBuilder openId(String openId) {
this.openId = openId;
return this;
}
public AuthorizeUserListQueryBuilder clientKey(String clientKey) {
this.clientKey = clientKey;
return this;
}
public AuthorizeUserListQueryBuilder tenantId(Integer tenantId) {
this.tenantId = tenantId;
return this;
}
public ImAuthorizeUserListQuery build() {
ImAuthorizeUserListQuery authorizeUserListQuery = new ImAuthorizeUserListQuery();
authorizeUserListQuery.setPage_num(pageNum);
authorizeUserListQuery.setPage_size(pageSize);
authorizeUserListQuery.setOpen_id(openId);
authorizeUserListQuery.setClientKey(clientKey);
authorizeUserListQuery.setTenantId(tenantId);
return authorizeUserListQuery;
}
}
}

View File

@ -0,0 +1,101 @@
package com.dyj.applet.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
/**
* @author danmo
* @date 2024-04-08 18:20
**/
public class RevokeMsgQuery extends UserInfoQuery {
/**
* 会话 ID来源于私信 webhook接收私信消息事件对应 webhook content 里的conversation_short_id 字段
*/
private String conversation_id;
/**
* 会话类型 1- 单聊 2- 群聊
*/
private Integer conversation_type;
/**
* 消息 id来源于私信 webhook 接收私信消息事件对应 webhook content 里的server_message_id 字段
*/
private String msg_id;
public String getConversation_id() {
return conversation_id;
}
public void setConversation_id(String conversation_id) {
this.conversation_id = conversation_id;
}
public Integer getConversation_type() {
return conversation_type;
}
public void setConversation_type(Integer conversation_type) {
this.conversation_type = conversation_type;
}
public String getMsg_id() {
return msg_id;
}
public void setMsg_id(String msg_id) {
this.msg_id = msg_id;
}
public static RevokeMsgQueryBuilder builder() {
return new RevokeMsgQueryBuilder();
}
public static class RevokeMsgQueryBuilder {
private String conversationId;
private Integer conversationType;
private String msgId;
private String openId;
private Integer tenantId;
private String clientKey;
public RevokeMsgQueryBuilder conversationId(String conversationId) {
this.conversationId = conversationId;
return this;
}
public RevokeMsgQueryBuilder conversationType(Integer conversationType) {
this.conversationType = conversationType;
return this;
}
public RevokeMsgQueryBuilder msgId(String msgId) {
this.msgId = msgId;
return this;
}
public RevokeMsgQueryBuilder openId(String openId) {
this.openId = openId;
return this;
}
public RevokeMsgQueryBuilder tenantId(Integer tenantId) {
this.tenantId = tenantId;
return this;
}
public RevokeMsgQueryBuilder clientKey(String clientKey) {
this.clientKey = clientKey;
return this;
}
public RevokeMsgQuery build() {
RevokeMsgQuery revokeMsgQuery = new RevokeMsgQuery();
revokeMsgQuery.setConversation_id(conversationId);
revokeMsgQuery.setConversation_type(conversationType);
revokeMsgQuery.setMsg_id(msgId);
revokeMsgQuery.setOpen_id(openId);
revokeMsgQuery.setTenantId(tenantId);
revokeMsgQuery.setClientKey(clientKey);
return revokeMsgQuery;
}
}
}

View File

@ -0,0 +1,185 @@
package com.dyj.applet.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
import java.util.List;
/**
* @author danmo
* @date 2024-04-08 13:37
**/
public class SendMsgQuery<T> extends UserInfoQuery {
/**
* 消息id场景一场景二必传
* 场景一来源于接收私信消息事件对应 webhook content server_message_id 字段有效期为24小时
* 场景二:来源于接收用户进入私信会话页事件对应 webhook content server_message_id 字段有效期为24小时
*/
private String msg_id;
/**
* 会话 id场景一场景二必传
* 场景一来源于接收私信消息事件对应webhook content 里的 conversation_short_id 字段长期有效
* 场景二来源于接收用户进入私信会话页事件对应webhook content 里的 conversation_short_id 字段长期有效
*/
private String conversation_id;
/**
* 消息的接收方 open_id
*/
private String to_user_id;
/**
* 消息体场景一场景二必传
* 文本 content
* 图片 content
* 视频 content
* 留资卡片 content
* 小程序引导卡片 content
* 群邀请卡片 content
* 小程序券 content
* 主动私信卡片 content
*/
private T content;
/**
* 私信场景
* 场景一默认场景可选传入 im_replay_msg
* 场景二用户主动进入私信会话页必传 im_enter_direct_msg
* 场景三: B2B场景私信触达必传 im_b2b_direct_message
* 场景四主动私信持续触达必传 im_authorize_message
*/
private String scene;
/**
* 场景三, 场景四必传最多支持三条消息
* 场景三必须包含一条小程序卡片消息
* 场景四必须包含一条小程序卡片/主动私信卡片/小程序券消息
*/
private List<T> content_list;
public String getMsg_id() {
return msg_id;
}
public void setMsg_id(String msg_id) {
this.msg_id = msg_id;
}
public String getConversation_id() {
return conversation_id;
}
public void setConversation_id(String conversation_id) {
this.conversation_id = conversation_id;
}
public String getTo_user_id() {
return to_user_id;
}
public void setTo_user_id(String to_user_id) {
this.to_user_id = to_user_id;
}
public T getContent() {
return content;
}
public void setContent(T content) {
this.content = content;
}
public String getScene() {
return scene;
}
public void setScene(String scene) {
this.scene = scene;
}
public List<T> getContent_list() {
return content_list;
}
public void setContent_list(List<T> content_list) {
this.content_list = content_list;
}
public static SendMsgQueryBuilder builder() {
return new SendMsgQueryBuilder();
}
public static class SendMsgQueryBuilder<T> {
private String msgId;
private String conversationId;
private String toUserId;
private T content;
private String scene;
private List<T> contentList;
private Integer tenantId;
private String clientKey;
private String openId;
public SendMsgQueryBuilder msgId(String msgId) {
this.msgId = msgId;
return this;
}
public SendMsgQueryBuilder conversationId(String conversationId) {
this.conversationId = conversationId;
return this;
}
public SendMsgQueryBuilder toUserId(String toUserId) {
this.toUserId = toUserId;
return this;
}
public SendMsgQueryBuilder content(T content) {
this.content = content;
return this;
}
public SendMsgQueryBuilder scene(String scene) {
this.scene = scene;
return this;
}
public SendMsgQueryBuilder contentList(List<T> contentList) {
this.contentList = contentList;
return this;
}
public SendMsgQueryBuilder tenantId(Integer tenantId) {
this.tenantId = tenantId;
return this;
}
public SendMsgQueryBuilder clientKey(String clientKey) {
this.clientKey = clientKey;
return this;
}
public SendMsgQueryBuilder openId(String openId) {
this.openId = openId;
return this;
}
public SendMsgQuery build() {
SendMsgQuery sendMsgQuery = new SendMsgQuery();
sendMsgQuery.setMsg_id(msgId);
sendMsgQuery.setConversation_id(conversationId);
sendMsgQuery.setTo_user_id(toUserId);
sendMsgQuery.setContent(content);
sendMsgQuery.setScene(scene);
sendMsgQuery.setContent_list(contentList);
sendMsgQuery.setTenantId(tenantId);
sendMsgQuery.setClientKey(clientKey);
sendMsgQuery.setOpen_id(openId);
return sendMsgQuery;
}
}
}

View File

@ -0,0 +1,18 @@
package com.dyj.applet.domain.vo;
/**
* @author danmo
* @date 2024-04-18 11:40
**/
public class AuthSendMsgVo {
private String msg_id;
public String getMsg_id() {
return msg_id;
}
public void setMsg_id(String msg_id) {
this.msg_id = msg_id;
}
}

View File

@ -0,0 +1,97 @@
package com.dyj.applet.domain.vo;
import com.dyj.applet.domain.AuthAttribution;
/**
* @author danmo
* @date 2024-04-18 13:39
**/
public class ImAuthStatusVo {
/**
* 授权状态
* 1 授权中
* 2 未授权
*/
private Integer status;
/**
* 授权归因不同的授权来源对应不同的归因字段
*/
private AuthAttribution attribution;
/**
* 在小程序跳转私信组件中开发者自定义参数
*/
private String data_im_extra;
/**
* 授权来源
* micro_app 小程序
* button组件
* im_card 服务私信授权卡片
* action_bar 会话页快捷入口
* live_shelf_panel 直播间货架入口
* micro_app_pendant 小程序内免研悬浮组件
* mp_follow_account 小程序内关注后拉起主动私信授权
*/
private String enter_from;
/**
* 用户点击获取用户私信授权组件时所在小程序当前页面的path参数
*/
private String path;
/**
* 用户点击获取用户私信授权组件时所在小程序当前页面的query参数
*/
private String query;
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public AuthAttribution getAttribution() {
return attribution;
}
public void setAttribution(AuthAttribution attribution) {
this.attribution = attribution;
}
public String getData_im_extra() {
return data_im_extra;
}
public void setData_im_extra(String data_im_extra) {
this.data_im_extra = data_im_extra;
}
public String getEnter_from() {
return enter_from;
}
public void setEnter_from(String enter_from) {
this.enter_from = enter_from;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
}

View File

@ -0,0 +1,18 @@
package com.dyj.applet.domain.vo;
import com.dyj.applet.domain.ImAuthUser;
import com.dyj.common.domain.vo.BaseVo;
import java.util.List;
/**
* @author danmo
* @date 2024-04-08 17:18
**/
public class ImAuthUserListVo extends BaseVo {
private List<ImAuthUser> auth_user_list;
private Boolean has_more;
}

View File

@ -0,0 +1,41 @@
package com.dyj.applet.domain.vo;
import com.dyj.common.domain.DyResult;
import com.dyj.common.domain.vo.BaseVo;
import java.util.List;
/**
* @author danmo
* @date 2024-04-09 10:20
**/
public class SendMsgResponseVo extends DyResult<BaseVo> {
/**
* 消息ID
*/
public String msg_id;
/**
* 消息ID列表
*/
public List<String> msg_list;
public String getMsg_id() {
return msg_id;
}
public void setMsg_id(String msg_id) {
this.msg_id = msg_id;
}
public List<String> getMsg_list() {
return msg_list;
}
public void setMsg_list(List<String> msg_list) {
this.msg_list = msg_list;
}
}

View File

@ -1,10 +1,12 @@
package com.dyj.applet.handler;
import com.dyj.applet.client.ChatMsgClient;
import com.dyj.applet.client.LoginClient;
import com.dyj.applet.client.SchemaClient;
import com.dyj.common.client.AuthClient;
import com.dyj.common.config.AgentConfiguration;
import com.dyj.common.domain.query.BaseQuery;
import com.dyj.common.domain.query.UserInfoQuery;
import com.dyj.spring.utils.SpringUtils;
import java.util.Objects;
@ -33,6 +35,12 @@ public abstract class AbstractAppletHandler {
return SpringUtils.getBean(SchemaClient.class);
}
protected ChatMsgClient getChatMsgClient() {
return SpringUtils.getBean(ChatMsgClient.class);
}
protected BaseQuery baseQuery(){
return baseQuery(null);
}
@ -45,4 +53,23 @@ public abstract class AbstractAppletHandler {
query.setClientKey(agentConfiguration.getClientKey());
return query;
}
protected UserInfoQuery userInfoQuery(){
return userInfoQuery(new UserInfoQuery());
}
protected UserInfoQuery userInfoQuery(String openId){
UserInfoQuery query = new UserInfoQuery();
query.setOpen_id(openId);
return userInfoQuery(query);
}
protected UserInfoQuery userInfoQuery(UserInfoQuery query){
if(Objects.isNull(query)){
query = new UserInfoQuery();
}
query.setTenantId(agentConfiguration.getTenantId());
query.setClientKey(agentConfiguration.getClientKey());
return query;
}
}

View File

@ -59,7 +59,11 @@ public class AppletTokenHandler extends AbstractAppletHandler {
* @return DyAppletResult<BizTokenVo>
*/
public DyAppletResult<BizTokenVo> getBizToken(String openId, String scope) {
return getAuthClient().getBizToken(BizTokenQuery.builder().clientKey(agentConfiguration.getClientKey()).clientSecret(agentConfiguration.getClientSecret()).openId(openId).scope(scope).build());
DyAppletResult<BizTokenVo> dyAppletResult = getAuthClient().getBizToken(BizTokenQuery.builder().clientKey(agentConfiguration.getClientKey()).clientSecret(agentConfiguration.getClientSecret()).openId(openId).scope(scope).build());
if (Objects.nonNull(dyAppletResult) && dyAppletResult.getError_code() == 0) {
DyConfigUtils.getAgentTokenService().setBizToken(agentConfiguration.getTenantId(), agentConfiguration.getClientKey(), dyAppletResult.getData().getBiz_token(), dyAppletResult.getData().getBiz_expires_in(), dyAppletResult.getData().getBiz_refresh_token(), dyAppletResult.getData().getBiz_refresh_expires_in(), openId);
}
return dyAppletResult;
}
/**

View File

@ -0,0 +1,93 @@
package com.dyj.applet.handler;
import com.dyj.applet.domain.query.ImAuthStatusQuery;
import com.dyj.applet.domain.query.ImAuthorizeUserListQuery;
import com.dyj.applet.domain.query.RevokeMsgQuery;
import com.dyj.applet.domain.query.SendMsgQuery;
import com.dyj.applet.domain.vo.AuthSendMsgVo;
import com.dyj.applet.domain.vo.ImAuthStatusVo;
import com.dyj.applet.domain.vo.ImAuthUserListVo;
import com.dyj.applet.domain.vo.SendMsgResponseVo;
import com.dyj.common.config.AgentConfiguration;
import com.dyj.common.domain.DyResult;
import com.dyj.common.domain.DySimpleResult;
import com.dyj.common.domain.vo.BaseVo;
/**
* @author danmo
* @date 2024-04-18 13:48
**/
public class ChatMsgHandler extends AbstractAppletHandler {
public ChatMsgHandler(AgentConfiguration agentConfiguration) {
super(agentConfiguration);
}
/**
* 发送私信消息
*
* @param query 入参
* @return ChatMsgResponseVo
*/
public SendMsgResponseVo sendMessage(SendMsgQuery query) {
query.setTenantId(agentConfiguration.getTenantId());
query.setClientKey(agentConfiguration.getClientKey());
return getChatMsgClient().sendMessage(query);
}
/**
* 发送主动私信
*
* @param query 入参
* @return DySimpleResult<AuthSendMsgVo>
*/
public DySimpleResult<AuthSendMsgVo> authSendMsg(SendMsgQuery query) {
query.setTenantId(agentConfiguration.getTenantId());
query.setClientKey(agentConfiguration.getClientKey());
return getChatMsgClient().authSendMsg(query);
}
/**
* 查询主动私信用户授权状态
*
* @param openId 用户ID
* @param cOpenId C端用户的open_id
* @param appId C端用户open_id所在的小程序 可不传
* @return DySimpleResult<ImAuthStatusVo>
*/
public DySimpleResult<ImAuthStatusVo> queryImAuthStatus(String openId, String cOpenId, String appId) {
ImAuthStatusQuery query = ImAuthStatusQuery.builder().openId(openId).cOpenId(cOpenId).appId(appId)
.clientKey(agentConfiguration.getClientKey()).tenantId(agentConfiguration.getTenantId()).build();
return getChatMsgClient().queryImAuthStatus(query);
}
/**
* 查询授权主动私信用户
*
* @param openId 用户ID
* @param pageNum 页码
* @param pageSize 每页数量
* @return DySimpleResult<ImAuthUserListVo>
*/
public DySimpleResult<ImAuthUserListVo> queryAuthorizeUserList(String openId, Long pageNum, Long pageSize) {
return getChatMsgClient().queryAuthorizeUserList(ImAuthorizeUserListQuery.builder()
.openId(openId).pageNum(pageNum).pageSize(pageSize)
.clientKey(agentConfiguration.getClientKey()).tenantId(agentConfiguration.getTenantId()).build());
}
/**
* 私信消息撤回
*
* @param openId 用户ID
* @param msgId 消息ID
* @param conversationId 会话 ID来源于私信 webhook接收私信消息事件对应 webhook content 里的conversation_short_id 字段
* @param conversationType 会话类型 1- 单聊 2- 群聊
* @return DyResult<BaseVo>
*/
public DyResult<BaseVo> revokeMessage(String openId, String msgId, String conversationId, Integer conversationType) {
return getChatMsgClient().revokeMessage(RevokeMsgQuery.builder()
.openId(openId).msgId(msgId).conversationId(conversationId).conversationType(conversationType)
.clientKey(agentConfiguration.getClientKey()).tenantId(agentConfiguration.getTenantId())
.build());
}
}

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -1,4 +1,4 @@
package com.dyj.web.domain;
package com.dyj.common.domain;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.MediaTypeEnum;

View File

@ -32,7 +32,11 @@ public enum DyAppletUrlPathEnum {
//生成QRCodeV2
CREATE_QR_CODE("createQrCode", "/api/apps/v1/qrcode/create/"),
//发送主动私信
AUTHORIZE_SEND_MSG("authSendMsg","/im/authorize/send/msg/"),
//查询主动私信用户授权状态
IM_AUTHORIZE_STATUS("imAuthStatus","/im/authorize/status/"),
;

View File

@ -20,7 +20,6 @@ import java.util.Objects;
**/
public class BizTokenHeaderInterceptor implements Interceptor<DyAppletResult> {
@Override
public boolean beforeExecute(ForestRequest request) {
Integer tenantId = null;
@ -44,6 +43,7 @@ public class BizTokenHeaderInterceptor implements Interceptor<DyAppletResult> {
throw new RuntimeException("access-token is null");
}
request.addHeader("access-token", bizToken.getBiz_token());
request.replaceOrAddQuery("open_id", openId);
return true;
}

View File

@ -19,7 +19,7 @@ public interface IAgentTokenService {
BizTokenVo getBizToken(Integer tenantId, String clientKey, String openId);
void setBizToken(Integer tenantId, String clientKey, String bizToken, Long bizExpiresIn, String bizRefreshToken, Long bizRefreshExpiresIn);
void setBizToken(Integer tenantId, String clientKey, String bizToken, Long bizExpiresIn, String bizRefreshToken, Long bizRefreshExpiresIn, String openId);
//String getOpenId() throws OpenIdIsNullException;
}

View File

@ -59,9 +59,7 @@ public class CacheAgentTokenServiceImpl implements IAgentTokenService {
}
@Override
public void setBizToken(Integer tenantId, String clientKey, String bizToken, Long bizExpiresIn, String bizRefreshToken, Long bizRefreshExpiresIn) {
public void setBizToken(Integer tenantId, String clientKey, String bizToken, Long bizExpiresIn, String bizRefreshToken, Long bizRefreshExpiresIn, String openId) {
}
}

View File

@ -78,7 +78,7 @@ public class RedisAgentTokenService implements IAgentTokenService {
}
@Override
public void setBizToken(Integer tenantId, String clientKey, String bizToken, Long bizExpiresIn, String bizRefreshToken, Long bizRefreshExpiresIn) {
public void setBizToken(Integer tenantId, String clientKey, String bizToken, Long bizExpiresIn, String bizRefreshToken, Long bizRefreshExpiresIn, String openId) {
}
}

View File

@ -4,7 +4,7 @@ package com.dyj.examples;
import com.alibaba.fastjson.JSONArray;
import com.dyj.common.domain.DyResult;
import com.dyj.web.DyWebClient;
import com.dyj.web.domain.TextMsg;
import com.dyj.common.domain.TextMsg;
import com.dyj.web.domain.query.AuthorizeUserListQuery;
import com.dyj.web.domain.query.RevokeMsgQuery;
import com.dyj.web.domain.query.SendMsgQuery;

View File

@ -4,7 +4,7 @@ package com.dyj.examples;
import com.alibaba.fastjson.JSONObject;
import com.dyj.common.enums.GroupSettingTypeEnum;
import com.dyj.web.DyWebClient;
import com.dyj.web.domain.TextMsg;
import com.dyj.common.domain.TextMsg;
import com.dyj.web.domain.query.*;
import com.dyj.web.domain.vo.CreateFansGroupVo;
import com.dyj.web.domain.vo.FansGroupSettingVo;

View File

@ -2,7 +2,7 @@ package com.dyj.web.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
import com.dyj.common.enums.GroupSettingTypeEnum;
import com.dyj.web.domain.MsgContent;
import com.dyj.common.domain.MsgContent;
import java.util.List;

View File

@ -1,7 +1,7 @@
package com.dyj.web.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
import com.dyj.web.domain.MsgContent;
import com.dyj.common.domain.MsgContent;
/**
* @author danmo

View File

@ -1,7 +1,6 @@
package com.dyj.web.domain.query;
import com.dyj.common.domain.query.UserInfoQuery;
import com.dyj.web.domain.MsgContent;
import java.util.List;
@ -9,7 +8,7 @@ import java.util.List;
* @author danmo
* @date 2024-04-08 13:37
**/
public class SendMsgQuery extends UserInfoQuery {
public class SendMsgQuery<T> extends UserInfoQuery {
/**
* 消息id场景一场景二必传
@ -41,7 +40,7 @@ public class SendMsgQuery extends UserInfoQuery {
* 小程序券 content
* 主动私信卡片 content
*/
private MsgContent content;
private T content;
/**
* 私信场景
@ -57,7 +56,7 @@ public class SendMsgQuery extends UserInfoQuery {
* 场景三必须包含一条小程序卡片消息
* 场景四必须包含一条小程序卡片/主动私信卡片/小程序券消息
*/
private List<MsgContent> content_list;
private List<T> content_list;
public String getMsg_id() {
return msg_id;
@ -83,11 +82,11 @@ public class SendMsgQuery extends UserInfoQuery {
this.to_user_id = to_user_id;
}
public MsgContent getContent() {
public T getContent() {
return content;
}
public void setContent(MsgContent content) {
public void setContent(T content) {
this.content = content;
}
@ -99,24 +98,24 @@ public class SendMsgQuery extends UserInfoQuery {
this.scene = scene;
}
public List<MsgContent> getContent_list() {
public List<T> getContent_list() {
return content_list;
}
public void setContent_list(List<MsgContent> content_list) {
public void setContent_list(List<T> content_list) {
this.content_list = content_list;
}
public static SendMsgQueryBuilder builder() {
return new SendMsgQueryBuilder();
}
public static class SendMsgQueryBuilder {
public static class SendMsgQueryBuilder<T> {
private String msgId;
private String conversationId;
private String toUserId;
private MsgContent content;
private T content;
private String scene;
private List<MsgContent> contentList;
private List<T> contentList;
private Integer tenantId;
private String clientKey;
@ -137,7 +136,7 @@ public class SendMsgQuery extends UserInfoQuery {
return this;
}
public SendMsgQueryBuilder content(MsgContent content) {
public SendMsgQueryBuilder content(T content) {
this.content = content;
return this;
}
@ -147,7 +146,7 @@ public class SendMsgQuery extends UserInfoQuery {
return this;
}
public SendMsgQueryBuilder contentList(List<MsgContent> contentList) {
public SendMsgQueryBuilder contentList(List<T> contentList) {
this.contentList = contentList;
return this;
}