实现自定义消息收发
更新时间: 2024/05/10 11:40:02
本文介绍 IM UIKit 默认支持的基本消息类型,以及如何实现自定义消息收发。
基本消息类型
IM UIKit 内置了几种基本消息类型(见下表),如果基本消息类型无法满足您的业务需求,您可自定义消息类型。
消息类型 |
显示效果 |
---|---|
文本消息 | |
图片消息 | |
文件消息 | |
表情 |
前提条件
实现自定义消息收发前,请确保已集成会话消息界面。
实现方法
发送自定义消息
发送方可以在会话界面的消息发送按钮上绑定发送消息的函数。
以“发送一条评价消息”为例:
发送时,可将“是否为评价消息”标记在附件信息 attach
字段或者其他字段中(可联系技术支持获取最贴近您业务的字段),然后在消息接收时进行判断。
- 如果是评价消息,则使用自定义渲染。
- 如果不是评价消息,则返回 null,使用默认的消息渲染逻辑。
您可以根据业务需要,决定调用 store
层的 sendCustomMsgActive
或 SDK 原生方法 sendCustomMsg
(可以传递更丰富的参数) 发送函数实现自定义消息的发送。
- 通过调用
sendCustomMsgActive
实现的示例代码:
Vue
import { compile } from "jsx-web-compiler";
// 发送评价消息
const sendEvaluationMessage = () => {
// 这里通过 uikit 实例获取 store,store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
const { store, nim } = window.__xkit_store__
const [scene, to] = store.uiStore.selectedSession.split('-')
const from = store.userStore.myUserInfo.account
//用户自定义参数
const attach = {
isEvaluation: true
}
// sence代表发送场景 form 发送方 to接收方
store.msgStore.sendCustomMsgActive({
scene,
from,
to,
attach: JSON.stringify(attach)
}).then((res) => {
console.log('=======发送成功======', res)
// 让消息滚动到可视区域
document.getElementById(res.idClient).scrollIntoView()
}).catch((err) => {
console.log('发送失败', err)
})
}
// 此部分代码为右侧发送按钮新增一个发送评价信息按钮,并绑定消息发送函数
window.$uikit.render(
ChatContainer,
{
actions: [
//...,
{
action: 'evaluation',
visible: true,
render: (props) => {
return compile(`
<button onClick={context.sendEvaluationMessage}>
评价
</button>
`, {
sendEvaluationMessage
});
},
},
]
},
this.$refs.chat
);
React
// IMUIKit store实例, store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
const { store } = useStateContext()
// 发送评价消息
const sendEvaluationMessage = () => {
const [scene, to] = store.uiStore.selectedSession.split('-')
const from = store.userStore.myUserInfo.account
//用户自定义参数
const attach = {
isEvaluation: true
}
// sence代表发送场景 form 发送方 to接收方
store.msgStore.sendCustomMsgActive({
scene,
from,
to,
attach: JSON.stringify(attach)
}).then((res) => {
console.log('=======发送成功======', res)
// 让消息滚动到可视区域
document.getElementById(res.idClient).scrollIntoView()
}).catch((err) => {
console.log('发送失败', err)
})
}
const actions = [
//...,
{
action: 'evaluation',
visible: true,
render: (props) => {
return (
<button onClick={sendEvaluationMessageBySdk}>
评价
</button>
)
},
},
]
<ChatContainer
//...
actions={actions}
/>
- 通过调用SDK 原生方法
sendCustomMsg
实现的示例代码(IM 1为例):
Vue
const sendEvaluationMessageBySdk = () => {
// 这里通过 uikit 实例获取 store,store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
const { store, nim } = window.__xkit_store__
const [scene, to] = store.uiStore.selectedSession.split('-')
const from = store.userStore.myUserInfo.account
//用户自定义参数
const attach = {
isEvaluation: true
}
nim.nim.sendCustomMsg({
scene,
to,
//接收方通过onMsg接收消息
//然后如果msg.type === 'custom',接收方通过读取msg.content,然后调用业务代码
content: JSON.stringify(attach),
done: function(err, msg) {
if (err) {
console.log('发送失败', err)
} else {
console.log('=======发送消息成功,消息为======: ', msg)
// 将自定义消息插入到消息列表中, 这里将消息的attach中添加一个canRecall字段,用于标识是否可以撤回
if (msg && msg.sessionId) {
const canRecallMsg = {
...msg,
attach: {
...JSON.parse(msg.content),
canRecall: true,
reCallTimer: setTimeout(() => {
const _msg = store.msgStore.getMsg(msg.sessionId, [msg.idClient])[0]
if (_msg) {
const _attach = _msg.attach
if (_attach) {
delete _attach.canRecall
delete _attach.reCallTimer
}
_msg.attach = _attach
store.msgStore.addMsg(msg.sessionId, [_msg])
}
}, 2 * 60 * 1000),
},
}
store.msgStore.addMsg(msg.sessionId, [canRecallMsg])
// 让消息滚动到可视区域
document.getElementById(msg.idClient).scrollIntoView()
}
}
}
})
}
window.$uikit.render(
ChatContainer,
{
actions: [
//...,
{
action: 'evaluation',
visible: true,
render: (props) => {
return compile(`
<button onClick={context.sendEvaluationMessageBySdk}>
评价
</button>
`, {
sendEvaluationMessageBySdk
});
},
},
]
},
this.$refs.chat
);
React
// IMUIKit store实例, store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
const { store, nim } = useStateContext()
const sendEvaluationMessageBySdk = () => {
// 这里通过 uikit 实例获取 store,store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
const [scene, to] = store.uiStore.selectedSession.split('-')
const from = store.userStore.myUserInfo.account
//用户自定义参数
const attach = {
isEvaluation: true
}
nim.nim.sendCustomMsg({
scene,
to,
//接收方通过onMsg接收消息
//然后如果msg.type === 'custom',接收方通过读取msg.content,然后调用业务代码
content: JSON.stringify(attach),
done: function(err, msg) {
if (err) {
console.log('发送失败', err)
} else {
console.log('=======发送消息成功,消息为======: ', msg)
// 将自定义消息插入到消息列表中, 这里将消息的attach中添加一个canRecall字段,用于标识是否可以撤回
if (msg && msg.sessionId) {
const canRecallMsg = {
...msg,
attach: {
...JSON.parse(msg.content),
canRecall: true,
reCallTimer: setTimeout(() => {
const _msg = store.msgStore.getMsg(msg.sessionId, [msg.idClient])[0]
if (_msg) {
const _attach = _msg.attach
if (_attach) {
delete _attach.canRecall
delete _attach.reCallTimer
}
_msg.attach = _attach
store.msgStore.addMsg(msg.sessionId, [_msg])
}
}, 2 * 60 * 1000),
},
}
store.msgStore.addMsg(msg.sessionId, [canRecallMsg])
// 让消息滚动到可视区域
document.getElementById(msg.idClient).scrollIntoView()
}
}
}
})
}
const actions = [
//...,
{
action: 'evaluation',
visible: true,
render: (props) => {
return (
<button onClick={sendEvaluationMessageBySdk}>
评价
</button>
)
},
},
]
<ChatContainer
//...
actions={actions}
/>
接收自定义消息并渲染
同样以“接收评价消息”为例,接收方可从如下回调函数中获取 IM UIKit 渲染一条消息的所有参数,从而自行实现任意的 UI 展示。
如果需要针对特定类型(type
)的消息进行单独的渲染处理,可以根据type
判断并返回自定义的内容,如果返回null
则使用默认渲染方式。
回调 |
类型 |
说明 |
---|---|---|
renderP2pCustomMessage |
((options: RenderP2pCustomMessageOptions) => Element | null) |
渲染单聊中的自定义消息 注: RenderP2pCustomMessageOptions.msg 的类型请参考IMMessage |
renderTeamCustomMessage |
((options: RenderTeamCustomMessageOptions) => Element | null) |
渲染群聊中的自定义消息 注: RenderTeamCustomMessageOptions.msg 的类型请参考IMMessage |
renderMessageOuterContent |
((msg: IMMessage) => JSX.Element | null | undefined) |
自定义渲染会话消息,气泡样式也需要自定义 注:msg 的类型请参考IMMessage |
renderMessageInnerContent |
((msg: IMMessage) => JSX.Element | null | undefined) |
自定义渲染会话消息,不需要自定义气泡样式 注:msg 的类型请参考IMMessage |
您可以根据你业务需要,决定调用以上自定义消息的任意一种。
示例代码:
Vue
this.$uikit.render(
ChatContainer,
{
renderMessageInnerContent:(options) => {
console.log('===========options==========', options);
let isEvaluation
if(options.attach){
isEvaluation = options.attach.isEvaluation
}
return isEvaluation ?
compile(`<div className='wrapper'>
<div className='msg-wrapper'>
<div className='text'>欢迎您进行评价</div>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
</div>
</div> `, {
options,
}) : null},
actions: [
{
action: 'emoji',
visible: true,
},
{
action: 'sendImg',
visible: true,
},
{
action: 'sendFile',
visible: true,
},
{
action: 'evaluation',
visible: true,
render: (props) => {
return compile(`
<context.Button onClick={context.sendEvaluationMessage} size="small" disabled={context.props.mute}>
<i className="iconfont icon-message_fill_light" />
</context.Button>
`, {
props,
CommonIcon,
Button,
sendEvaluationMessage
});
},
},
]
},
this.$refs.chat
);
React
<ChatContainer
actions={actions}
// renderP2pCustomMessage={renderP2pCustomMessage}
renderMessageInnerContent={(options) => {
console.log('===========options==========', options);
let isEvaluation
if(options.attach){
isEvaluation = options.attach.isEvaluation
}
return isEvaluation ?
(<div className='wrapper'>
<div className='msg-wrapper'>
<div className='text'>欢迎您进行评价</div>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
<img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
</div>
</div> ) : null}}
/>
查看在线示例
在 IMAppProps
传入正确的 appkey
、account
和 token
即可在线预览效果。
最终实现的效果参见如下 gif 动图:
常见问题
可通过哪些参数/回调自定义渲染消息的样式?
支持通过如下参数/回调自定义渲染单聊和群聊的自定义消息。
参数/回调 |
类型 | 说明 |
---|---|---|
renderP2pCustomMessage |
((options: RenderP2pCustomMessageOptions) => Element | null) |
渲染单聊中的自定义消息 |
renderTeamCustomMessage |
((options: RenderTeamCustomMessageOptions) => Element | null) |
渲染群聊中的自定义消息 |
renderMessageAvatar |
(msg: IMMessage) => JSX.Element | null | undefined |
自定义渲染消息头像 |
renderMessageOuterContent |
((msg: IMMessage) => JSX.Element | null | undefined) |
自定义渲染会话消息,气泡样式也需要自定义 |
renderMessageInnerContent |
((msg: IMMessage) => JSX.Element | null | undefined) |
自定义渲染会话消息,不需要自定义气泡样式 |
renderMessageName |
(msg: IMMessage) => JSX.Element | null | undefined |
自定义渲染消息昵称 |
此文档是否对你有帮助?