互动消息聊天指南
本文介绍互动消息相关功能的使用方法,包括消息收发、历史消息、消息撤回和私聊。
发送消息
文本消息
typescript
const result = await classroom.sendTextMessage('大家好!');
if (!result.ok) {
console.error('发送失败:', result.message);
}图片消息
typescript
// 选择文件后发送(自动上传 COS)
const fileInput = document.querySelector<HTMLInputElement>('#image-input');
const file = fileInput?.files?.[0];
if (file) {
const result = await classroom.sendImageMessage(file);
if (!result.ok) console.error('图片发送失败:', result.message);
}文件消息
typescript
const file = fileInput.files[0];
const result = await classroom.sendFileMessage(file);
if (!result.ok) {
console.error('文件发送失败:', result.message);
}自定义消息
typescript
// 发送自定义消息(content 会被序列化为 JSON 字符串)
const result = await classroom.sendCustomMessage({
type: 'emoji',
emojiId: 'thumbs_up',
});私聊消息
typescript
// 发送定向私聊消息(仅目标用户可见)
const result = await classroom.sendDirectedMessage('user_002', '你好,有问题想请教');
if (!result.ok) {
console.error('私聊发送失败:', result.message);
}接收消息
通过响应式状态订阅消息列表
订阅完整消息列表(包含历史消息 + 实时新消息)
typescript
classroom.state.messageList$.subscribe(messages => {
renderMessageList(messages);
});通过事件监听新消息
监听新消息(用于触发通知/滚动等 UI 操作)
typescript
import { TEvent } from '@tencent-classroom/sdk';
classroom.on(TEvent.RECV_MESSAGE, (message) => {
console.log('新消息:', message.content);
scrollToBottom();
showNotification(message);
});解析展示私聊消息标识
messageList$ 中包含公聊消息 + 与自己相关的私聊消息。
私聊消息通过 message.ext(即 IM 的 cloudCustomData)中的字段标识:
typescript
interface MessageExt {
IsPrivateMsg?: boolean; // 是否为私聊消息
PrivateInfo?: {
From: { ID: string }; // 发送者 userId
To: { ID: string }; // 接收者 userId
};
}解析示例:
typescript
classroom.state.messageList$.subscribe((messages) => {
for (const msg of messages) {
// 解析 ext 字段
const ext = typeof msg.ext === 'string' ? JSON.parse(msg.ext || '{}') : (msg.ext || {});
if (ext.IsPrivateMsg) {
// 这是一条私聊消息
const fromId = ext.PrivateInfo?.From?.ID;
const toId = ext.PrivateInfo?.To?.ID;
renderPrivateMessage(msg, fromId, toId);
} else {
// 普通公聊消息
renderPublicMessage(msg);
}
}
});messageList$ 的过滤规则
SDK 内部已确保 messageList$ 只包含:
- 所有公聊消息(Text / Image / File 类型)
- 与当前用户相关的私聊消息(自己是发送者 From 或接收者 To)
其他用户之间的私聊消息不会出现在列表中,业务层无需再做可见性判断。
历史消息
typescript
// 拉取历史消息(增量拉取,不重复)
const result = await classroom.fetchHistoryMessages(20); // 默认 20 条
if (result.ok) {
console.log('历史消息:', result.data);
}
// 继续拉取更多
const moreResult = await classroom.fetchHistoryMessages(20);提示:进房时 SDK 会自动拉取一次历史消息并写入
state.messageList$,通常无需手动调用。
消息撤回
typescript
// 撤回自己的消息(所有角色可撤回自己的消息)
const result = await classroom.revokeMessage(message.id);
if (!result.ok) {
console.error('撤回失败:', result.message);
}
// 老师/助教撤回他人消息(按 IM 序列号)
await classroom.revokeClassMessage(message.seq);监听消息撤回事件:
typescript
classroom.on(TEvent.MESSAGE_REVOKED, ({ msgId }) => {
console.log('消息已被撤回:', msgId);
});未读管理
typescript
// 订阅未读消息数
classroom.state.messageUnreadCount$.subscribe(count => {
updateBadge(count);
});
// 标记全部已读
classroom.markAllMessagesAsRead();
// 标记指定序列号以前的消息为已读
classroom.markMessageAsRead(latestSeq);聊天模式控制
老师/助教可控制课堂聊天模式:
typescript
// 设置聊天模式
await classroom.setSilenceMode('freeChat'); // 自由聊天
await classroom.setSilenceMode('publicOnly'); // 仅公开消息
await classroom.setSilenceMode('privateOnly'); // 仅私聊
await classroom.setSilenceMode('muteAll'); // 全员禁言
// 订阅禁言模式变化
classroom.state.silenceMode$.subscribe(mode => {
console.log('当前聊天模式:', mode);
});检查发送权限
typescript
// 检查当前用户是否可发送消息
if (classroom.canSendChatMessage()) {
// 可以发送
} else {
showToast('当前处于禁言状态');
}