跳到主要内容

红包场景实践

场景说明

用户在单聊/群聊会话中向指定好友发送红包(实际货币、虚拟货币、积分等),发送人和接收人可以明确感知红包是否被领取的状态(未领取、已领取)。

效果示例

无 UI 集成,您可根据业务侧逻辑调整相关 UI。

红包消息流程

1. 准备工作

在开始之前,请确保已创建应用并完成客户端 SDK 集成

2. 定义红包消息

2.1 定义红包消息类型

您可通过 IMLib SDK 的自定义消息,创建红包类消息类型(如 RedPacketMessage),消息内容结构需根据业务需求自行定义,确保多端(Android / iOS / Web)一致。

Android / iOS 端自定义消息类参考:

Web 端示例代码:

javascript
// 1. RongIMLib.registerMessageType 必须在 connect 之前调用,否则可能造成收取消息的行为异常。
// 2. 请尽量把应用中所有涉及到的自定义消息统一一次注册,且同类型消息仅调用一次注册,便于管理。

const messageType = 'app:red_packet' // 消息类型
const isPersited = true // 是否存储
const isCounted = true // 是否计数
const searchProps = [] // 搜索字段,Web 端无需设置,搜索字段值设置为数字时取值范围为 (-Math.pow(2, 64), Math.pow(2, 64)) 且为整数
const isStatusMessage = false // 是否是状态消息。状态消息不存储、不计数,接收方在线时才能收到。
const PersonMessage = RongIMLib.registerMessageType(messageType, isPersited, isCounted, searchProps, isStatusMessage)

3. 注册并接收红包消息

Java
// 注册自定义消息类型,初始化 SDK 后注册
ArrayList<Class<? extends MessageContent>> myMessages = new ArrayList<>();
myMessages.add(CustomRedPacketMessage.class);
RongCoreClient.registerMessageType(myMessages);

// 接收消息示例:设置接收消息监听器,接收消息时会自动回调
RongCoreClient.addOnReceiveMessageListener(new OnReceiveMessageWrapperListener() {
@Override
public void onReceivedMessage(Message message, ReceivedProfile profile) {
int left = profile.getLeft();
boolean isOffline = profile.isOffline();
boolean hasPackage = profile.hasPackage();
}
});

// 返回的 `Message` 实体参考下面信息,可以使用 `objectName` 或者 `content` 来区分消息类型:

{
"conversationType": "PRIVATE",
"targetId": "userid3453",
"messageId": 70,
"channelId": "",
"messageDirection": "RECEIVE",
"senderUserId": "userid3453",
"receivedStatus": "io.rong.imlib.model.Message$ReceivedStatus @560f848",
"sentStatus": "SENT",
"receivedTime": 1739428279001,
"sentTime": 1739428279158,
"objectName": "app:red_packet",
"content": {
"content": "红包消息"
},
"extra": "",
"readReceiptInfo": "io.rong.imlib.model.ReadReceiptInfo @b8d3c06",
"messageConfig": {
"disablePushTitle": false,
"pushTitle": "",
"pushContent": "",
"pushData": "null",
"templateId": "",
"forceShowDetailContent": false,
"iOSConfig": null,
"androidConfig": null,
"harmonyConfig": null
},
"canIncludeExpansion": false,
"expansionDic": null,
"expansionDicEx": null,
"mayHasMoreMessagesBefore": false,
"UId": "CKVO-0J6T-GM26-D3E6",
"disableUpdateLastMessage": "false",
"directedUsers": "0"
}

4. 付款成功发送红包消息

在用户付款成功后,需要调用融云的发送消息方法,发送红包消息并设置消息可扩展。根据业务侧逻辑选择从哪个端发送此类消息。

Java
// 构建红包消息
CustomRedPacketMessage redPacketMessage = CustomRedPacketMessage.obtain("0.01");
io.rong.imlib.model.Message message =
io.rong.imlib.model.Message.obtain(targetId, conversationType, redPacketMessage);
// 设置消息可扩展
message.setCanIncludeExpansion(true);
HashMap<String, String> redInfo = new HashMap<>();
redInfo.put("open","false");
redInfo.put("count","1");
redInfo.put("amount","0.01");
message.setExpansion(redInfo);
// 发送消息,如果您使用的 IMLib SDK,请使用 RongCoreClient 的 sendMessage 方法
RongCoreClient.getInstance().sendMessage(message, null, null, null);

服务端示例代码

Java
 /**
* Send group gray bar message - targeted users (up to 1000 users per request)
*/
String[] targetIds = {"groupId"};
RedPacketMessage redPacketMessage =new RedPacketMessage("红包消息");
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("open", "false");
hashMap.put("count", "1");
hashMap.put("amount", "2");
GroupMessage groupMessage = new GroupMessage()
.setSenderId("fromId")
.setIsIncludeSender(1)
.setTargetId(targetIds) // Group ID
.setContent(redPacketMessage)
.setObjectName(txtMessage.getType())
.setExpansion(true)
.setExtraContent(hashMap);

ResponseResult redPackeReslut = group.send(groupMessage);
System.out.println("group info Notify message result: " + redPackeReslut.toString());

5. 开启红包更新红包扩展

用户点击开启红包后,红包消息状态需要变更为「已开启」。此时,您可通过设置消息扩展监听 updateMessageExpansion 更新此条消息的扩展信息,扩展设置开启用户 id 以及标识为已开启状态,同时更改本地显示的消息样式。

Java
// messageUid 为原红包消息唯一 Id。

RongIMClient.getInstance()
.updateMessageExpansion(
redInfo,
messageUid,
new RongIMClient.OperationCallback() {
@Override
public void onSuccess() {
// 发起者在这里处理更新扩展后的 UI 数据刷新
}

@Override
public void onError(RongIMClient.ErrorCode errorCode) {
Toast.makeText(
getApplicationContext(),
"设置失败,ErrorCode : " + errorCode.getValue(),
Toast.LENGTH_LONG)
.show();
}
});

服务端示例代码

Java
/**
*
* Set message extension
*
*/
ExpansionModel msg = new ExpansionModel();
msg.setMsgUID("BS45-NPH4-HV87-10LM");
msg.setUserId("WNYZbMqpH");
msg.setTargetId("tjw3zbMrU");
msg.setConversationType(1);
HashMap<String, String> kv = new HashMap<String, String>();
kv.put("type1", "1");
kv.put("type2", "2");
kv.put("type3", "3");
kv.put("type4", "4");
msg.setExtraKeyVal(kv);
msg.setIsSyncSender(1);
ResponseResult result = expansion.set(msg);
System.out.println("set expansion: " + result.toString());

6. 发送方更新红包消息扩展

红包消息发送方可全局设置消息扩展监听,收到消息扩展更新回调时做对应的处理。建议调用客户端服务 API 获取最新的红包领取信息。

Java
// 接收方 Android 端示例代码
RongIMClient.getInstance().setMessageExpansionListener(new RongIMClient.MessageExpansionListener() {
@Override
public void onMessageExpansionUpdate(Map<String, String> expansion, Message message) {
if (message.getContent() instanceof CustomRedPacketMessage){
// 其他自定义处理
}
}
});

7. 红包领取后操作

开启红包后,如需展示" XX 领取了红包"。可由服务端发送一条群定向消息或者红包发送者和领取者,或者监听消息扩展信息,展示对应的用户信息及领取状态。红包发送者可以监听消息扩展信息,收到监听后,主动到业务客户端获取消息领取的最新状态。

Java
// 插入小灰条消息
InformationNotificationMessage informationNotificationMessage = InformationNotificationMessage.obtain("你领取了xxx 发送的红包");

ConversationType conversationType = ConversationType.PRIVATE;
String targetId = "user1";
String senderUserId = "模拟发送方的 ID";
ReceivedStatus receivedStatus = new ReceivedStatus(0x1);
String sentTime = System.currentTimeMillis();

IMCenter.getInstance().insertIncomingMessage(conversationType, targetId, senderUserId, receivedStatus, informationNotificationMessage, sentTime, new IRongCoreCallback.ResultCallback<Message>() {
@Override
public void onSuccess(Message message) {
// 成功插入小灰条消息
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {

}
});