Mode | Description | Configuration Value |
Cloud Moderation | Uses the built-in cloud moderation engine of Tencent Cloud IM to automatically block inappropriate messages. | cloud |
Custom Moderation | Suitable for real-time interactive moderation in live rooms. Uses a pre-send interception mechanism to submit user messages to a online manual review workflow, allowing only approved messages to go to appear in the live room. | custom |

cd packages/custom-moderation-server# # Install dependenciesnpm install# # Copy configuration filecp config/example.env config/.env# # Start (port 9001)npm start
CUSTOM_MODERATION_BASE_URL.packages/server/config/.env:# # Switch to custom moderation modeMODERATION_MODE=custom# # Custom moderation server address (demo server defaults to http://localhost:9001)CUSTOM_MODERATION_BASE_URL=http://localhost:9001# # API Key (optional, demo server has none configured by default, leave empty)# CUSTOM_MODERATION_API_KEY=your_api_key
http://your-domain:9001/im-callback), and click OK.# # Simulate IM callback (message intercepted)curl -X POST http://localhost:9001/im-callback \\-H "Content-Type: application/json" \\-d '{"CallbackCommand": "Group.CallbackBeforeSendMsg","GroupId": "test_live_room","From_Account": "user_001","MsgBody": [{"MsgType": "TIMTextElem", "MsgContent": {"Text": "Hello"}}]}'# # View moderation listcurl -X POST http://localhost:9001/moderation/list \\-H "Content-Type: application/json" \\-d '{"Receiver": "test_live_room", "PageNo": 1, "PageSize": 10}'
{CUSTOM_MODERATION_BASE_URL}, configured via env.CUSTOM_MODERATION_API_KEY is configured, LiveKit Manager includes the following in all requests:X-Api-Key: {CUSTOM_MODERATION_API_KEY}
GET /moderation/toggle{"ActionStatus": "OK","ErrorCode": 0,"Enabled": true}
POST /moderation/toggle{"Enabled": true}
{"ActionStatus": "OK","ErrorCode": 0,"Enabled": true}
Enabled: true indicates full moderation enabled (all messages intercepted),false indicates disabled (messages delivered normally).POST /moderation/list{"Receiver": "live_room_id","PageNo": 1,"PageSize": 20}
Field | Type | Required | Description |
Receiver | string | Yes | Live room ID (corresponds to GroupId). |
PageNo | number | Yes | Page number (starting from 1). |
PageSize | number | Yes | Page size (max 100). |
DescribeCloudAuditRecordDetailV2.Data array format):{"TotalCount": 100,"RequestId": "req_1234567890","Data": [{"ContentId": "msg_001","From_Account": "user_alice","Content": "Intercepted message content","Time": "2026-06-30 14:30:00.000"}]}
Field | Type | Required | Description |
TotalCount | number | Yes | Total record count (for pagination calculation). |
RequestId | string | No | Request ID. |
Data[].ContentId | string | Yes | Unique message ID(for subsequent Delete/Approve). |
Data[].From_Account | string | Yes | Sender IM account. |
Data[].Content | string | Yes | Message text content. |
Data[].Time | string | Yes | Message timestamp (format YYYY-MM-DD HH:mm:ss.SSS). |
Label (moderation label) field is not needed. The corresponding column will be hidden in the frontend.POST /moderation/delete{"ContentIds": ["msg_001", "msg_002"]}
{"ActionStatus": "OK","ErrorCode": 0,"DeletedCount": 2,"RequestId": "req_1234567890"}
Field | Type | Description |
DeletedCount | number | Number of records actually deleted. |
{"ActionStatus": "FAIL","ErrorCode": 500,"ErrorInfo": "Error description"}
{"CallbackCommand": "Group.CallbackBeforeSendMsg","GroupId": "live_room_123","Type": "Public","From_Account": "user_456","Operator_Account": "","Random": 123456,"MsgBody": [{"MsgType": "TIMTextElem","MsgContent": {"Text": "Message content sent by user"}}]}
Field | Description |
GroupId | Live room ID. |
From_Account | Sender IM account. |
MsgBody[].MsgContent.Text | Text message content. |
{"ActionStatus": "OK","ErrorCode": 1,"ErrorInfo": "Message intercepted for moderation"}
{"ActionStatus": "OK","ErrorCode": 0,"ErrorInfo": ""}
ErrorCode of 0 indicates Approve,non- 0 indicates interception. Callback timeout defaults to Approve(ensuring message deliverability).send_group_msg (with NoMsgCheck to skip re-moderation) to resend the message as the original user.POST /moderation/delete delete corresponding record.POST /moderation/delete delete corresponding record.Feature | Cloud Mode | Custom Mode |
Moderation Data Source | Tencent Cloud DescribeCloudAuditRecordDetailV2 | Custom Database |
Moderation List Fields | id / User ID / Content / Recognition Type / Time | id / User ID / Content / Time |
Action Buttons | Approve / Delete / More(Correction Whitelist) | Approve / Delete |
Full Moderation Toggle | None | Yes |
Delete Implementation | IndexedDB Frontend Marker | Custom Server DELETE |
Approve Implementation | send_group_msg + IndexedDB Marker | send_group_msg + Custom Server DELETE |
Correction Whitelist | Supported | Not Supported |
MODERATION_MODE back to cloud and restart the service. Switching will not lose data — your server data remains intact.// callback.jsconst db = require('./db'); // // Database module, provides insertMessage etc. APIsconst blockedWords = ['sensitive_word_1', 'sensitive_word_2'];// // Extract text content from MsgBody (assuming only the first text message is processed)const content = req.body.MsgBody[0]?.MsgContent?.Text || '';if (content && blockedWords.some(w => content.includes(w))) {// // Intercept and store message in databasedb.insertMessage({content_id: `msg_${Date.now()}`,group_id: req.body.GroupId,from_account: req.body.From_Account,content: content,msg_body: JSON.stringify(req.body.MsgBody)});res.json({ ActionStatus: 'OK', ErrorCode: 1 });} else {// Approveres.json({ ActionStatus: 'OK', ErrorCode: 0 });}
フィードバック