flutter/lib/IM/im_message.dart
2025-09-22 14:41:47 +08:00

272 lines
9.2 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:convert';
import 'dart:io';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:loopin/IM/controller/im_user_info_controller.dart';
import 'package:loopin/IM/im_result.dart';
import 'package:loopin/utils/parse_message_summary.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_priority_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/offlinePushInfo.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_msg_create_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
class IMMessage {
final logger = Logger();
/// 1.发送消息
Future<ImResult> sendMessage({
required V2TimMessage msg,
String? toUserID,
String? groupID,
String? cloudCustomData,
String? groupName,
bool isExcludedFromUnreadCount = false,
}) async {
// 必须且只能设置一个toUserID单聊或 groupID群聊
if ((toUserID == null && groupID == null) || (toUserID == '' && groupID == '')) {
return ImResult(
success: false,
code: -1,
desc: "只能指定一个receiver:toUserID或groupID",
);
}
if (cloudCustomData != null) {
msg.cloudCustomData = cloudCustomData;
}
// 解析消息类型
V2TimValueCallback<V2TimMessage> sendRes;
// final controller = Get.find<ChatDetailController>();
// 单聊
if (toUserID != null && toUserID.isNotEmpty) {
final myInfo = Get.find<ImUserInfoController>();
logger.w('启用默认title${myInfo.nickname.value}');
OfflinePushInfo offlinePushInfo = OfflinePushInfo(
title: myInfo.nickname.value,
desc: parseMessageSummary(msg),
ext: jsonEncode({"userID": myInfo.userID.value, "title": myInfo.nickname.value}),
);
sendRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
message: msg,
receiver: toUserID,
// onSyncMsgID: (msgID) async {
// 这里立刻拿到消息ID可以提前把这条消息展示到列表中发送中状态有时间再改吧
// 根据类型创建对应的elem
// logger.w(msg.imageElem!.toLogString());
// controller.chatList.add(msg.imageElem);
// controller.scrollToBottom();
// },
groupID: "",
priority: MessagePriorityEnum.V2TIM_PRIORITY_DEFAULT,
onlineUserOnly: false, // 是否只推送在线用户,默认全推
isExcludedFromUnreadCount: isExcludedFromUnreadCount, //默认记入 不计入未读如果这里设置了那么message中设置的将失效
isExcludedFromLastMessage: false, // 不作为会话的最新消息
isSupportMessageExtension: false, // 支持消息扩展
isExcludedFromContentModeration: false, // 绕过内容审核
needReadReceipt: false, // 已读回执
offlinePushInfo: offlinePushInfo,
cloudCustomData: cloudCustomData,
localCustomData: "",
);
} else {
// 群聊
OfflinePushInfo offlinePushInfo = OfflinePushInfo(
title: groupName,
desc: parseMessageSummary(msg),
ext: jsonEncode({"groupID": groupID, "title": groupName ?? ''}),
);
sendRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().sendMessage(
message: msg,
receiver: "",
groupID: groupID!,
// onSyncMsgID: (msgID) async {
// 这里立刻拿到消息ID可以提前把这条消息展示到列表中发送中状态有时间再改吧
// 根据类型创建对应的elem
// logger.w(msg.imageElem!.toLogString());
// controller.chatList.add(msg.imageElem);
// controller.scrollToBottom();
// },
priority: MessagePriorityEnum.V2TIM_PRIORITY_DEFAULT,
onlineUserOnly: false,
isExcludedFromUnreadCount: isExcludedFromUnreadCount,
isExcludedFromLastMessage: false,
isSupportMessageExtension: false,
isExcludedFromContentModeration: false,
needReadReceipt: false,
offlinePushInfo: offlinePushInfo,
cloudCustomData: cloudCustomData,
localCustomData: "",
);
}
return ImResult(
success: sendRes.code == 0,
code: sendRes.code,
desc: sendRes.desc,
data: sendRes.data,
);
}
/// 2=创建自定义消息
Future<ImResult<V2TimMsgCreateInfoResult>> createCustomMessage({
required String data,
String desc = "",
String extension = "",
}) async {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createCustomMessage(
data: data,
desc: desc,
extension: extension,
);
return ImResult.wrap(res);
}
/// 构造单聊伪消息
Future<ImResult> insertTimeLabel(String data, String userId) async {
final customMsgRes = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createCustomMessage(
data: data,
desc: "时间标签",
extension: "",
);
if (customMsgRes.code != 0 || customMsgRes.data?.id == null) {
return ImResult(
success: false,
code: customMsgRes.code,
desc: "创建时间标签消息失败",
);
}
final timeMsg = customMsgRes.data!.messageInfo;
timeMsg!.localCustomData = 'time_label';
return ImResult(
success: true,
code: customMsgRes.code,
desc: "success",
data: timeMsg,
);
}
/// 创建文本消息==1
Future<ImResult<V2TimMsgCreateInfoResult>> createTextMessage({
required String text,
}) async {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createTextMessage(text: text);
return ImResult.wrap(res);
}
/// 创建图片消息==3
Future<ImResult<V2TimMsgCreateInfoResult>> createImageMessage({
required String imagePath,
String? imageName,
}) async {
final fileExists = await File(imagePath).exists();
if (fileExists) {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createImageMessage(
imagePath: imagePath,
imageName: imageName,
);
return ImResult.wrap(res);
} else {
// 构造失败的回调
final failed = V2TimValueCallback<V2TimMsgCreateInfoResult>.fromJson({
"code": -5,
"desc": "imagePath is not found",
"data": V2TimMsgCreateInfoResult.fromJson({}),
});
return ImResult.wrap(failed);
}
}
///创建视频消息==5
Future<ImResult<V2TimMsgCreateInfoResult>> createVideoMessage({
//最大100MB
required String videoFilePath, //视频地址
required String type, // 类型mp4/avi==
required int duration, // 时长
required String snapshotPath, // 封面图
}) async {
final videoExists = await File(videoFilePath).exists();
final snapshotExists = await File(snapshotPath).exists();
if (videoExists && snapshotExists) {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createVideoMessage(
videoFilePath: videoFilePath,
type: type,
duration: duration,
snapshotPath: snapshotPath,
);
return ImResult.wrap(res);
}
// 构造失败回调
final failed = V2TimValueCallback<V2TimMsgCreateInfoResult>.fromJson({
"code": -5,
"desc": "视频或首帧图缺失",
"data": V2TimMsgCreateInfoResult.fromJson({}),
});
return ImResult.wrap(failed);
}
/// 语音消息==4
Future<ImResult<V2TimMsgCreateInfoResult>> createSoundMessage({
required String soundPath,
required int duration,
String? path,
}) async {
final soundExists = await File(soundPath).exists();
if (soundExists) {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createSoundMessage(
soundPath: soundPath,
duration: duration,
);
return ImResult.wrap(res);
}
final failed = V2TimValueCallback<V2TimMsgCreateInfoResult>.fromJson({
"code": -5,
"desc": "音频文件缺失",
"data": V2TimMsgCreateInfoResult.fromJson({}),
});
return ImResult.wrap(failed);
}
/// 表情 == 8
Future<ImResult<V2TimMsgCreateInfoResult>> createFaceMessage({
required int index,
required String data,
}) async {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().createFaceMessage(
index: index,
data: data,
);
return ImResult.wrap(res);
}
///相当于一个被禁用了网络发送能力的 sendMessage() 接口
Future<ImResult<V2TimMessage>> insertC2CMessageToLocalStorageV2({
required String userID,
required String senderID,
V2TimMessage? message,
String? createdMsgID,
}) async {
final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().insertC2CMessageToLocalStorageV2(
userID: userID,
senderID: senderID,
message: message,
createdMsgID: createdMsgID,
);
return ImResult.wrap(res);
}
}