腾讯IM文档地址:https://cloud.tencent.com/document/product/269/32688
首先要明白的是腾讯IM的聊天接发都是前端完成的,后台只需添加聊天账号与返回UserSig。
首先导包:
com.github.tencentyun
tls-sig-api-v2
2.0
org.apache.httpcomponents
httpclient
com.fasterxml.jackson.core
jackson-databind
2.11.4
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-lang3
创建一个http请求工具 HttpUtil.java
package com.example.demo.im.util;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author xiaochi
* @date 2022/5/8 18:28
* @desc HttpUtil
*/
public class HttpUtil {
private static final CloseableHttpClient httpclient = HttpClients.createDefault();
/**
* 发送HttpGet请求
* @param url
* @return
*/
public static String sendGet(String url) {
HttpGet httpget = new HttpGet(url);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpget);
} catch (IOException e1) {
e1.printStackTrace();
}
String result = null;
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 发送HttpPost请求,参数为map
* @param url
* @param map
* @return
*/
public static String sendPost(String url, Map map) {
List formparams = new ArrayList();
for (Map.Entry entry : map.entrySet()) {
formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost(url);
httppost.setEntity(entity);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity1 = response.getEntity();
String result = null;
try {
result = EntityUtils.toString(entity1);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 发送不带参数的HttpPost请求
* @param url
* @return
*/
public static String sendPost(String url) {
HttpPost httppost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
String result = null;
try {
result = EntityUtils.toString(entity);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String doPost2(String url, JSONObject param) {
HttpPost httpPost = null;
String result = null;
try {
HttpClient client = new DefaultHttpClient();
httpPost = new HttpPost(url);
if (param != null) {
StringEntity se = new StringEntity(param.toString(), "utf-8");
httpPost.setEntity(se); // post方法中,加入json数据
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Authorization", param.getString("authorization"));
}
HttpResponse response = client.execute(httpPost);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
result = EntityUtils.toString(resEntity, "utf-8");
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
}
接着创建 redis 工具 RedisUtil
package com.example.demo.im.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author xiaochi
* @date 2022/5/8 18:58
* @desc RedisServiceUtil
*/
@Component
public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
/**
* 写入缓存
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存设置时效时间
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 设置指定键的过期时间
* @param key 键
* @param expireTime 过期时间
* @param timeUnit 时间单位
* @return true:成功
*/
public boolean setExpire(final String key, Long expireTime, TimeUnit timeUnit) {
return redisTemplate.expire(key, expireTime, timeUnit);
}
/**
* 批量删除对应的value
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 删除对应的value
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
* @param key
* @return
*/
public T get(final String key) {
Object result = null;
ValueOperations operations = redisTemplate.opsForValue();
result = operations.get(key);
if (null == result) {
return null;
}
return (T)result;
}
/**
* 哈希 添加
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations hash = redisTemplate.opsForHash();
hash.put(key,hashKey,value);
}
/**
* 以map集合的形式添加键值对
* @param key 键
* @param map Map
*/
public void hPutAll(String key, Map map) {
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 哈希获取数据
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations hash = redisTemplate.opsForHash();
return hash.get(key,hashKey);
}
/**
* 根据键获取到redis中存储的map
* @param key 键
* @return 键对应的map
*/
public Map hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 自增/自减key对应map中的指定字段的long型数值
* @param key 键
* @param field key对应map中存储的字段
* @param increment 正数-自增;负数-自减
* @return 自增/自减后的数值
*/
public Long hashIncrBy(String key, Object field, long increment) {
return redisTemplate.opsForHash().increment(key, field, increment);
}
/**
* 自增/自减key对应map中的指定字段的double型数值
* @param key 键
* @param field key对应map中存储的字段
* @param delta 正数-自增;负数-自减
* @return 自增/自减后的数值
*/
public Double hIncrByDouble(String key, Object field, double delta) {
return redisTemplate.opsForHash().increment(key, field, delta);
}
/**
* 查询redis中指定字段是否存在
* @param key 键
* @param field key对应map中存储的字段
* @return true:存在
*/
public boolean hashExists(String key, String field) {
return redisTemplate.opsForHash().hasKey(key, field);
}
/**
* 列表添加
* @param k
* @param v
*/
public void lPush(String k, Object v) {
ListOperations list = redisTemplate.opsForList();
list.rightPush(k,v);
}
/**
* 列表获取
* @param k
* @param l
* @param l1
* @return
*/
public List
接下来就是创建腾讯IM常量类 TencentImConstant
package com.example.demo.im.constant;
/**
* @author xiaochi
* @date 2022/5/8 18:26
* @desc TencentImConstant
*/
public class TencentImConstant {
/**
* IM请求处理结果
*/
public final static String ACTION_STATUS_OK = "OK";
public final static String ACTION_STATUS_FAIL = "FAIL";
/**
* IM发消息是否同步到发送方(1-同步,2-不同步)
*/
public final static Integer SYNC_OTHER_MACHINE_YES = 1;
public final static Integer SYNC_OTHER_MACHINE_NO = 2;
/**
* IM消息对象类型:
* TIMTextElem 文本消息。
* TIMLocationElem 地理位置消息。
* TIMFaceElem 表情消息。
* TIMCustomElem 自定义消息,当接收方为 iOS 系统且应用处在后台时,此消息类型可携带除文本以外的字段到 APNs。一条组合消息中只能包含一个 TIMCustomElem 自定义消息元素。
* TIMSoundElem 语音消息。
* TIMImageElem 图像消息。
* TIMFileElem 文件消息。
* TIMVideoFileElem 视频消息。
*/
public final static String TIM_TEXT_ELEM = "TIMTextElem";
public final static String TIM_LOCATION_ELEM = "TIMLocationElem";
public final static String TIM_FACE_ELEM = "TIMFaceElem";
public final static String TIM_CUSTOM_ELEM = "TIMCustomElem";
public final static String TIM_SOUND_ELEM = "TIMSoundElem";
public final static String TIM_IMAGE_ELEM = "TIMImageElem";
public final static String TIM_FILE_ELEM = "TIMFileElem";
public final static String TIM_VIDEOFILE_ELEM = "TIMVideoFileElem";
/**
* 微信响应消息类型
* WX_MSG_TYPE_EVENT:事件类型,事件类型对应"user_enter_tempsession"表示建立会话
* WX_MSG_TYPE_TEXT:文本类型
* WX_MSG_TYPE_TEXT:图片类型
* WX_MSG_TYPE_TEXT:小程序卡片
*/
public final static String WX_MSG_TYPE_EVENT = "event";
public final static String WX_MSG_TYPE_TEXT = "text";
public final static String WX_MSG_TYPE_IMAGE = "image";
public final static String WX_MSG_TYPE_APPLET_CARD = "miniprogrampage";
}
再创建腾讯IM的API常量类TencentImApiConstant
package com.example.demo.im.constant;
/**
* @author xiaochi
* @date 2022/5/8 17:36
* @desc TencentImApiConstant
*/
public class TencentImApiConstant {
/**
* 账号管理
*/
public static class AccountManage {
/**导入单个帐号*/
public static final String ACCOUNT_IMPORT = "v4/im_open_login_svc/account_import";
/**导入多个帐号*/
public static final String MULTI_ACCOUNT_IMPORT = "v4/im_open_login_svc/multiaccount_import";
/**删除帐号*/
public static final String ACCOUNT_DELETE = "v4/im_open_login_svc/account_delete";
/**查询帐号*/
public static final String ACCOUNT_CHECK = "v4/im_open_login_svc/account_check";
/**失效帐号登录状态*/
public static final String ACCOUNT_KICK = "v4/im_open_login_svc/kick";
/**查询账号在线状态*/
public static final String ACCOUNT_QUERY_STATE = "v4/openim/query_online_status";
}
/**
* 单聊消息
*/
public static class SingleChatManage {
/**单发单聊消息*/
public static final String SEND_MSG = "v4/openim/sendmsg";
/**批量发单聊消息*/
public static final String BATCH_SEND_MSG = "v4/openim/batchsendmsg";
/**导入单聊消息*/
public static final String IMPORT_MSG = "v4/openim/importmsg";
/**查询单聊消息*/
public static final String ADMIN_GET_ROAM_MSG = "v4/openim/admin_getroammsg";
/**撤回单聊消息*/
public static final String ADMIN_MSG_WITH_DRAW = "v4/openim/admin_msgwithdraw";
/**设置单聊消息已读*/
public static final String ADMIN_SET_MSG_READ = "v4/openim/admin_set_msg_read";
/**查询单聊未读消息计数*/
public static final String ADMIN_SET_MSG_UNREAD_SUM = "v4/openim/get_c2c_unread_msg_num";
}
/**
* 全员推送
*/
public static class AllPushManage {
/**全员推送*/
public static final String IM_PUSH = "v4/all_member_push/im_push";
/**设置应用属性名称*/
public static final String IM_SET_ATTR_NAME = "v4/all_member_push/im_set_attr_name";
/**获取应用属性名称*/
public static final String IM_GET_ATTR_NAME = "v4/all_member_push/im_get_attr_name";
/**获取用户属性*/
public static final String IM_GET_ATTR = "v4/all_member_push/im_get_attr";
/**设置用户属性*/
public static final String IM_SET_ATTR = "v4/all_member_push/im_set_attr";
/**删除用户属性*/
public static final String IM_REMOVE_ATTR = "v4/all_member_push/im_remove_attr";
/**获取用户标签*/
public static final String IM_GET_TAG = "v4/all_member_push/im_get_tag";
/**添加用户标签*/
public static final String IM_ADD_TAG = "v4/all_member_push/im_add_tag";
/**删除用户标签*/
public static final String IM_REMOVE_TAG = "v4/all_member_push/im_remove_tag";
/**删除用户所有标签*/
public static final String IM_REMOVE_ALL_TAGS = "v4/all_member_push/im_remove_all_tags";
}
/**
* 资料管理
*/
public static class PortraitManage {
/**设置资料*/
public static final String PORTRAIT_SET = "v4/profile/portrait_set";
/**拉取资料*/
public static final String PORTRAIT_GET = "v4/profile/portrait_get";
}
/**
* 关系链管理
*/
public static class RelationManage {
/**添加好友*/
public static final String FRIEND_ADD = "v4/sns/friend_add";
/**导入好友*/
public static final String FRIEND_IMPORT = "v4/sns/friend_import";
/**更新好友*/
public static final String FRIEND_UPDATE = "v4/sns/friend_update";
/**删除好友*/
public static final String FRIEND_DELETE = "v4/sns/friend_delete";
/**删除所有好友*/
public static final String FRIEND_DELETE_ALL = "v4/sns/friend_delete_all";
/**校验好友*/
public static final String FRIEND_CHECK = "v4/sns/friend_check";
/**拉取好友*/
public static final String FRIEND_GET = "v4/sns/friend_get";
/**拉取指定好友*/
public static final String FRIEND_GET_LIST = "v4/sns/friend_get_list";
/**添加黑名单*/
public static final String BLACK_LIST_ADD = "v4/sns/black_list_add";
/**删除黑名单*/
public static final String BLACK_LIST_DELETE = "v4/sns/black_list_delete";
/**拉取黑名单*/
public static final String BLACK_LIST_GET = "v4/sns/black_list_get";
/**校验黑名单*/
public static final String BLACK_LIST_CHECK = "v4/sns/black_list_check";
/**添加分组*/
public static final String GROUP_ADD = "v4/sns/group_add";
/**删除分组*/
public static final String GROUP_DELETE = "v4/sns/group_delete";
/**拉取分组*/
public static final String GROUP_GET = "v4/sns/group_get";
}
/**
* 最近联系人
*/
public static class RecentContactManage{
/**拉取会话列表*/
public static final String GET_LIST = "v4/recentcontact/get_list";
/**删除单个会话*/
public static final String DELETE = "v4/recentcontact/delete";
}
/**
* 群组管理
*/
public static class GroupManage {
/**App 管理员可以通过该接口获取 App 中所有群组的 ID。*/
public static final String GET_ALL_GROUP_ID = "v4/group_open_http_svc/get_appid_group_list";
/**创建群组*/
public static final String CREATE_GROUP = "v4/group_open_http_svc/create_group";
/**获取群详细资料*/
public static final String GET_GROUP_INFO = "v4/group_open_http_svc/get_group_info";
/**获取群成员详细资料*/
public static final String GET_GROUP_MEMBER_INFO = "v4/group_open_http_svc/get_group_member_info";
/**修改群基础资料*/
public static final String MODIFY_GROUP_BASE_INFO = "v4/group_open_http_svc/modify_group_base_info";
/**增加群成员*/
public static final String ADD_GROUP_MEMBER = "v4/group_open_http_svc/add_group_member";
/**删除群成员*/
public static final String DELETE_GROUP_MEMBER = "v4/group_open_http_svc/delete_group_member";
/**修改群成员资料*/
public static final String MODIFY_GROUP_MEMBER_INFO = "v4/group_open_http_svc/modify_group_member_info";
/**解散群组*/
public static final String DESTROY_GROUP = "v4/group_open_http_svc/destroy_group";
/**获取用户所加入的群组*/
public static final String GET_JOINED_GROUP_LIST = "v4/group_open_http_svc/get_joined_group_list";
/**查询用户在群组中的身份*/
public static final String GET_ROLE_IN_GROUP = "v4/group_open_http_svc/get_role_in_group";
/**批量禁言和取消禁言*/
public static final String FORBID_SEND_MSG = "v4/group_open_http_svc/forbid_send_msg";
/**获取被禁言群成员列表*/
public static final String GET_GROUP_SHUT_UIN = "v4/group_open_http_svc/get_group_shutted_uin";
/**在群组中发送普通消息*/
public static final String SEND_GROUP_MSG = "v4/group_open_http_svc/send_group_msg";
/**在群组中发送系统通知*/
public static final String SEND_GROUP_SYSTEM_NOTIFICATION = "v4/group_open_http_svc/send_group_system_notification";
/**撤回群消息*/
public static final String GROUP_MSG_RECALL = "v4/group_open_http_svc/group_msg_recall";
/**转让群主*/
public static final String CHANGE_GROUP_OWNER = "v4/group_open_http_svc/change_group_owner";
/**导入群基础资料*/
public static final String IMPORT_GROUP = "v4/group_open_http_svc/import_group";
/**导入群消息*/
public static final String IMPORT_GROUP_MSG = "v4/group_open_http_svc/import_group_msg";
/**导入群成员*/
public static final String IMPORT_GROUP_MEMBER = "v4/group_open_http_svc/import_group_member";
/**设置成员未读消息计数*/
public static final String SET_UNREAD_MSG_NUM = "v4/group_open_http_svc/set_unread_msg_num";
/**删除指定用户发送的消息*/
public static final String DELETE_GROUP_MSG_BY_SENDER = "v4/group_open_http_svc/delete_group_msg_by_sender";
/**拉取群历史消息*/
public static final String GROUP_MSG_GET_SIMPLE = "v4/group_open_http_svc/group_msg_get_simple";
/**获取直播群在线人数*/
public static final String GET_ONLINE_MEMBER_NUM = "v4/group_open_http_svc/get_online_member_num";
}
/**
* 全局禁言管理
*/
public static class AllSinentManage {
/**设置全局禁言*/
public static final String SET_NO_SPEAKING = "v4/openconfigsvr/setnospeaking";
/**查询全局禁言*/
public static final String GET_NO_SPEAKING = "v4/openconfigsvr/getnospeaking";
}
/**
* 运营管理
*/
public static class OperationManage {
/**拉取运营数据*/
public static final String GET_APP_INFO = "v4/openconfigsvr/getappinfo";
/**下载消息记录*/
public static final String GET_HISTORY = "v4/open_msg_svc/get_history";
/**获取服务器 IP 地址*/
public static final String GET_IP_LIST = "v4/ConfigSvc/GetIPList";
}
}
再创建腾讯IM的工具类 TencentImUtil
package com.example.demo.im.util;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.im.constant.TencentImApiConstant;
import com.example.demo.im.constant.TencentImConstant;
import com.tencentyun.TLSSigAPIv2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author xiaochi
* @date 2022/5/8 18:53
* @desc TencentImUtil
*/
@Slf4j
@Component
public class TencentImUtil {
private static final String HTTPS_URL_PREFIX = "https://console.tim.qq.com/";
private static final String APP_MANAGER = "administrator";// 请求腾讯im的地址中usersig签名生成必须是管理员userId
private static final String REDIS_IM_USER_SIG = "silence:im_user_sig:";
private static final Integer SIGN_EXPIRED = 86400;
@Value("${im.appid}")
private long appid;
@Value("${im.secret}")
private String key;
@Autowired
private RedisUtil redisUtil;
/**
* 前端获取签名(接口返回签名)
* @param username
* @return
*/
public String getTxCloudUserSig(String username) {
String userSig = RedisUtil.get(REDIS_IM_USER_SIG + username);
if (StringUtils.isEmpty(userSig)) {
TLSSigAPIv2 tlsSigApi = new TLSSigAPIv2(appid, key);
userSig = tlsSigApi.genUserSig(username, SIGN_EXPIRED);
RedisUtil.set(REDIS_IM_USER_SIG + username, userSig, SIGN_EXPIRED);
}
return userSig;
}
/**
* 请求腾讯云地址usersig签名生成
*/
private String createUsersig() {
String userSig = RedisUtil.get(REDIS_IM_USER_SIG + APP_MANAGER);
if (StringUtils.isEmpty(userSig)) {
TLSSigAPIv2 tlsSigApi = new TLSSigAPIv2(appid, key);
userSig = tlsSigApi.genUserSig(APP_MANAGER, SIGN_EXPIRED);
RedisUtil.set(REDIS_IM_USER_SIG + APP_MANAGER, userSig, SIGN_EXPIRED);
}
return userSig;
}
/**
* 获取腾讯im请求路径
*/
private String getHttpsUrl(String imServiceApi, Integer random) {
return String.format("%s%s?sdkappid=%s&identifier=%s&usersig=%s&random=%s&contenttype=json",
HTTPS_URL_PREFIX, imServiceApi, appid, APP_MANAGER, this.createUsersig(), random);
}
/**
* 导入单个账号
* @param userId 用户id
*/
public void accountImport(String userId) {
accountImport(userId, null);
}
/**
* 添加账号
* @param userId
* @param userName
*/
public void accountImport(String userId, String userName) {
accountImport(userId, userName, null);
}
/**
* 添加账号
* @param userId
* @param userName
* @param faceUrl
*/
public void accountImport(String userId, String userName, String faceUrl) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.AccountManage.ACCOUNT_IMPORT, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Identifier", userId);
if (StringUtils.isNotEmpty(userName)) {
jsonObject.put("Nick", userName);
}
if (StringUtils.isNotEmpty(faceUrl)) {
jsonObject.put("FaceUrl", faceUrl);
}
log.info("腾讯云im导入单个账号,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im导入单个账号,返回结果:{}", result);
}
/**
* 导入多个账号
* @param userIds 用户id集合
*/
public void multiAccountImport(List userIds) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.AccountManage.MULTI_ACCOUNT_IMPORT, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Accounts", userIds);
log.info("腾讯云im导入多个账号,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im导入单个账户,返回结果:{}", result);
}
/**
* 删除账号
* @param userIds 用户id集合
*/
public void accountDelete(List userIds) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.AccountManage.ACCOUNT_DELETE, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("DeleteItem", getUserIdJsonList(userIds));
log.info("腾讯云im删除账号,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im删除账户,返回结果:{}", result);
}
/**
* 查询账号是否已经导入im
* @param userIds 用户id集合
*/
public String accountCheck(List userIds) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.AccountManage.ACCOUNT_CHECK, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("CheckItem", getUserIdJsonList(userIds));
log.info("腾讯云im查询账号,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im查询账号,返回结果:{}", result);
return result;
}
private List getUserIdJsonList(List userIds) {
return userIds.stream().map(v -> {
JSONObject userIdJson = new JSONObject();
userIdJson.put("UserID", v);
return userIdJson;
}).collect(Collectors.toList());
}
/**
* 单发单聊消息
* @param syncOtherMachine 是否同步消息到发送方(1-同步,2-不同步)
* @param fromUserId 发送方用户id
* @param toUserId 接收方用户id
* @param msgType 消息对象类型
* @param msgContent 消息内容
*/
public String sendMsg(Integer syncOtherMachine, String fromUserId, String toUserId, String msgType, String msgContent) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.SingleChatManage.SEND_MSG, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("SyncOtherMachine", syncOtherMachine);
if (StringUtils.isNotEmpty(fromUserId)) {
// 发送方不为空表示指定发送用户,为空表示为管理员发送消息
jsonObject.put("From_Account", fromUserId);
}
jsonObject.put("To_Account", toUserId);
jsonObject.put("MsgRandom", random);
List msgBody = getMsgBody(msgType, msgContent);
jsonObject.put("MsgBody", msgBody);
log.info("腾讯云im单发单聊消息,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im单发单聊消息,返回结果:{}", result);
return result;
}
/**
* 批量发单聊消息
* @param syncOtherMachine 是否同步消息到发送方(1-同步,2-不同步)
* @param fromUserId 发送方用户id
* @param toUserIds 接收方用户id集合
* @param msgType 消息对象类型
* @param msgContent 消息内容
*/
public String batchSendMsg(Integer syncOtherMachine, String fromUserId, List toUserIds, String msgType, String msgContent) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.SingleChatManage.BATCH_SEND_MSG, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("SyncOtherMachine", syncOtherMachine);
if (StringUtils.isNotEmpty(fromUserId)) {
// 发送方不为空表示指定发送用户,为空表示为管理员发送消息
jsonObject.put("From_Account", fromUserId);
}
jsonObject.put("To_Account", toUserIds);
jsonObject.put("MsgRandom", random);
List msgBody = getMsgBody(msgType, msgContent);
jsonObject.put("MsgBody", msgBody);
log.info("腾讯云im批量发单聊消息,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im批量发单聊消息,返回结果:{}", result);
return result;
}
/**
* 拼接发送消息内容
* @param msgType 消息类型
* @param msgContent 发送消息内容
* @return 消息内容
*/
private List getMsgBody(String msgType, String msgContent) {
List msgBody = new ArrayList<>();
if (msgType.equals(TencentImConstant.TIM_TEXT_ELEM)) {
// 文本类型
JSONObject msgBodyJson = new JSONObject();
msgBodyJson.put("MsgType", msgType);
JSONObject msgContentObj = new JSONObject();
msgContentObj.put("Text", msgContent);
msgBodyJson.put("MsgContent", msgContentObj);
msgBody.add(msgBodyJson);
}
return msgBody;
}
/**
* 查询单聊消息
* @param fromUserId 发送方用户id
* @param toUserId 接收方用户id
* @param maxCnt 查询条数
* @param startTime 起始时间(单位:秒)
* @param endTime 结束时间(单位:秒)
* @param lastMsgKey 最后一条消息的 MsgKey
* @return 单聊消息列表
*/
public String adminGetRoamMsg(String fromUserId, String toUserId, Integer maxCnt, Long startTime, Long endTime, String lastMsgKey) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.SingleChatManage.ADMIN_GET_ROAM_MSG, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("From_Account", fromUserId);
jsonObject.put("To_Account", toUserId);
jsonObject.put("MaxCnt", maxCnt);
jsonObject.put("MinTime", startTime);
jsonObject.put("MaxTime", endTime);
if (StringUtils.isNotEmpty(lastMsgKey)){
jsonObject.put("LastMsgKey", lastMsgKey);
}
log.info("腾讯云im查询单聊消息,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im查询单聊消息,返回结果:{}", result);
return result;
}
/**
* 撤回单聊消息
* @param fromUserId 发送方用户id
* @param toUserId 接收方用户id
* @param msgKey MsgKey
*/
public void adminMsgWithDraw(String fromUserId, String toUserId, String msgKey) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.SingleChatManage.ADMIN_MSG_WITH_DRAW, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("From_Account", fromUserId);
jsonObject.put("To_Account", toUserId);
jsonObject.put("MsgKey", msgKey);
log.info("腾讯云im撤回单聊消息,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im撤回单聊消息,返回结果:{}", result);
}
/**
* 设置单聊消息已读
* @param reportUserId 读取消息的用户
* @param peerUserId 发送消息的用户
*/
public void adminSetMsgRead(String reportUserId, String peerUserId) {
Integer random = RandomUtils.nextInt(0, 999999999);
String httpsUrl = getHttpsUrl(TencentImApiConstant.SingleChatManage.ADMIN_SET_MSG_READ, random);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Report_Account", reportUserId);
jsonObject.put("Peer_Account", peerUserId);
log.info("腾讯云im设置单聊消息已读,请求参数:{}", jsonObject.toString());
String result = HttpUtil.doPost2(httpsUrl, jsonObject);
log.info("腾讯云im设置单聊消息已读,返回结果:{}", result);
}
}
好了,完成了,接下来就是测试了,appid
与 secret
请自行配置,创建测试控制器 IMController
package com.example.demo.im.controller;
import com.example.demo.R;
import com.example.demo.im.config.IMConfig;
import com.example.demo.im.constant.TencentImConstant;
import com.example.demo.im.util.TencentImUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Collections;
/**
* @author xiaochi
* @date 2022/5/8 17:15
* @desc IMController
*/
@RestController
@RequestMapping("/im")
public class IMController {
@Autowired
private IMConfig imConfig;
@Autowired
private TencentImUtil tencentImUtil;
private String sendUserId01 = "test01";// 发送方
private String sendUserId02 = "ceshi01";// 发送方
private String adminUserId = "chichengyu";// 管理员Id
/*@GetMapping("/usersig")
public R usersig(){
TLSSigAPIv2 apIv2 = new TLSSigAPIv2(imConfig.getAppid(),imConfig.getSecret());
return R.ok(apIv2.genUserSig(UUID.randomUUID().toString(),84600));
}*/
/**
* 导入账号
* @return
*/
@GetMapping("/add")
public R accountImport(){
tencentImUtil.accountImport(sendUserId01,"测试01");
tencentImUtil.accountImport(sendUserId02,"测试02");
return R.ok(tencentImUtil.accountCheck(Collections.singletonList(sendUserId01)));
}
/**
* 发送消息
* @param msg
* @return
*/
@GetMapping("/send/{msg}")
public R send(@PathVariable String msg){
String result = tencentImUtil.sendMsg(1,sendUserId01,adminUserId, TencentImConstant.TIM_TEXT_ELEM,msg);
return R.ok(result);
}
/**
* 管理员发送消息
* @param msg
* @return
*/
@GetMapping("/send1/{msg}")
public R send1(@PathVariable String msg){
String result = tencentImUtil.sendMsg(1,adminUserId,sendUserId01, TencentImConstant.TIM_TEXT_ELEM,msg);
return R.ok(result);
}
/**
* 接收消息
* @param msgKey
* @return
*/
@GetMapping("/get/{msgKey}")
public R get(@PathVariable String msgKey){
/*Calendar cale = Calendar.getInstance();
cale.setTime(new Date());
cale.set(Calendar.HOUR_OF_DAY, 0);
cale.set(Calendar.MINUTE, 0);
cale.set(Calendar.SECOND, 0);
Date beginTime = cale.getTime();
String msg = tencentImUtil.adminGetRoamMsg(sendUserId01,adminUserId,100, beginTime.getTime()/1000, System.currentTimeMillis()/1000,"");
*/
int second = LocalDateTime.MIN.getSecond();
String msg = tencentImUtil.adminGetRoamMsg(sendUserId01,adminUserId,100, (long)second, System.currentTimeMillis()/1000,"");
return R.ok(msg);
}
/**
* 接收管理员发送的消息
* @param msgKey
* @return
*/
@GetMapping("/get1/{msgKey}")
public R get1(@PathVariable String msgKey){
int second = LocalDateTime.MIN.getSecond();
String msg = tencentImUtil.adminGetRoamMsg(adminUserId,sendUserId01,100, (long)second, System.currentTimeMillis()/1000,"");
return R.ok(msg);
}
}
到此完成。