このページは現在英語版のみで提供されており、日本語版も近日中に提供される予定です。ご利用いただきありがとうございます。

ヒント

Overview

The sender listens for the characters in the input box. When the user enters @, the group member selection UI will pop up. After the target group members are selected, the message will be displayed in the input box in the format of "@A @B @C......", which can be further edited before sent. In the group chat list of the receiver's conversation UI, the identifier "someone@me" or "@ all" will be displayed to remind the user that the user was mentioned by someone in the group chat.
Note
Currently, only text @ messages are supported.

Feature Demonstration

Listening for the @ character for group member selection
Editing and sending the group @ message
Receiving the group @ message









Figure 1: When the @ character is detected in the input box on the chat UI, the user is redirected to the group member selection UI to select the target group members. Figure 2: After selecting the target group members, the user goes back to the chat UI to edit and send the group @ message. Figure 3: If a user is mentioned, the user receives the conversation update, and the "someone@me" information is displayed in the conversation Cell.

Sending a Group @ Message

1. The sender listens for the text input box on the chat UI and launches the group member selection UI. After group members are selected, the ID and nickname information of the members is called back. The ID is used to create the V2TIMMessage object, while the nickname is to be displayed in the text box.
2. The sender calls the createAtSignedGroupMessage API (Android / iOS & Mac / Windows) to create a group @ message, get the V2TIMMessage object, and specify the target group members.
3. The sender calls sendMessage (Android / iOS and macOS / Windows) to send the created @ message object.
Sample code:
Android
iOS and macOS
Windows
// Create a original text message
V2TIMMessage textMsg = V2TIMManager.getMessageManager().createTextMessage("text");
// Create a group @ message using the original text message, @ group members `user1` and `user2`
List<String> atUserList = new ArrayList<>();
atUserList.add("user1");
atUserList.add("user2");
V2TIMMessage atMsg = V2TIMManager.getMessageManager().createAtSignedGroupMessage(textMsg, atUserList);
// Send the group @ message
V2TIMManager.getMessageManager().sendMessage(atMsg, null, "toGroupID", V2TIMMessage.V2TIM_PRIORITY_DEFAULT, false, null, new V2TIMSendCallback<V2TIMMessage>() {
@Override
public void onError(int code, String desc) {
// The group @ message failed to be sent
}
@Override
public void onSuccess(V2TIMMessage v2TIMMessage) {
// Group @ message sent successfully
}
@Override
public void onProgress(int progress) {
}
});
// Create a original text message
V2TIMMessage *textMsg = [[V2TIMManager sharedInstance] createTextMessage:@"text"];
// Create a group @ message using the original text message, @ group members `user1` and `user2`
V2TIMMessage *atMsg = [[V2TIMManager sharedInstance] createAtSignedGroupMessage:textMsg atUserList:@[@"xixi", @"yahaha"]];
// Send the group @ message
[[V2TIMManager sharedInstance] sendMessage:atMsg receiver:nil groupID:@"groupA" priority:V2TIM_PRIORITY_NORMAL onlineUserOnly:NO offlinePushInfo:nil progress:nil succ:nil fail:nil];
class SendCallback final : public V2TIMSendCallback {
public:
using SuccessCallback = std::function<void(const V2TIMMessage&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;
using ProgressCallback = std::function<void(uint32_t)>;

SendCallback() = default;
~SendCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback,
ProgressCallback progress_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
progress_callback_ = std::move(progress_callback);
}

void OnSuccess(const V2TIMMessage& message) override {
if (success_callback_) {
success_callback_(message);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}
void OnProgress(uint32_t progress) override {
if (progress_callback_) {
progress_callback_(progress);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
ProgressCallback progress_callback_;
};

V2TIMStringVector atUserList;
atUserList.PushBack("user1");
atUserList.PushBack("user2");
V2TIMMessage message = V2TIMManager::GetInstance()->GetMessageManager()->CreateTextMessage(u8"text");
V2TIMMessage at_message = V2TIMManager::GetInstance()->GetMessageManager()->CreateAtSignedGroupMessage(message, atUserList);

auto callback = new SendCallback{};
callback->SetCallback(
[=](const V2TIMMessage& message) {
// The group @ message failed to be sent
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Group @ message sent successfully
delete callback;
},
[=](uint32_t progress) {});

V2TIMManager::GetInstance()->GetMessageManager()->SendMessage(
at_message, "denny", {}, V2TIMMessagePriority::V2TIM_PRIORITY_NORMAL, false, {}, callback);

Receiving a Group @ Message

1. When the conversation is loaded and updated, call the groupAtInfolist API (Android / iOS and macOS / Windows) of V2TIMConversation to get the @ data list of the conversation.
2. Call the atType API (Android / iOS and macOS / Windows) of the V2TIMGroupAtInfo object in the list to get the @ data type and update it to the @ information of the conversation.
Sample code:
Android
iOS and macOS
Windows
// Obtain the group @ data list
List<V2TIMGroupAtInfo> atInfoList = conversation.getGroupAtInfoList();
// Parse the @ type (@me, @all members, @me and @all members)
boolean atMe = false;
boolean atAll = false;
String atTips = "";
for(V2TIMGroupAtInfo atInfo : atInfoList){
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ME){
atMe = true;
continue;
}
if (atInfo.getAtType() == V2TIMGroupAtInfo.TIM_AT_ALL){
atAll = true;
continue;
}
}

// Based on the @ type, prompt:
if (atMe && !atAll) {
atTips = "[Someone@me]";
} else if (!atMe && atAll) {
atTips = "[@all]";
} else if (atMe && atAll) {
atTips = "[someone@me][@all members]";
}
// Obtain the group @ data list
NSArray<V2TIMGroupAtInfo *> *atInfoList = conversation.groupAtInfolist;

// Parse the @ type (@me, @all members, @me and @all members)
BOOL atMe = NO; // Whether it's @me
BOOL atAll = NO; // Whether it's @all members
NSString *atTipsStr = @"";
for (V2TIMGroupAtInfo *atInfo in atInfoList) {
switch (atInfo.atType) {
case V2TIM_AT_ME:
atMe = YES;
break;
case V2TIM_AT_ALL:
atAll = YES;
break;
case V2TIM_AT_ALL_AT_ME:
atMe = YES;
atAll = YES;
break;
default:
break;
}
}

// Based on the @ type, prompt:
if (atMe && !atAll) {
atTipsStr = @"[someone@me]";
}
if (!atMe && atAll) {
atTipsStr = @"[@all members]";
}
if (atMe && atAll) {
atTipsStr = @"[someone@me][@all members]";
}
// Obtain the group @ data list
V2TIMGroupAtInfoVector groupAtInfolist = conversation.groupAtInfolist;
// Parse the @ type (@me, @all members, @me and @all members)
bool atMe = false;
bool atAll = false;
std::string atTips = "";

for (size_t i = 0; i < groupAtInfolist.Size(); ++i) {
const V2TIMGroupAtInfo& atInfo = groupAtInfolist[i];
switch (atInfo.atType) {
case V2TIM_AT_ME:
atMe = true;
break;
case V2TIM_AT_ALL:
atAll = true;
break;
case V2TIM_AT_ALL_AT_ME:
atMe = true;
atAll = true;
break;
default:
break;
}
}

// Based on the @ type, prompt:
if (atMe && !atAll) {
atTips = u8"[someone@me]";
} else if (!atMe && atAll) {
atTips = u8"[@all members]";
} else if (atMe && atAll) {
atTips = u8"[someone@me][@all members]";
}