diff --git a/images/unreal-blueprints/ConfigureAndLoginAsync.png b/images/unreal-blueprints/ConfigureAndLoginAsync.png new file mode 100644 index 000000000..9025a50b2 Binary files /dev/null and b/images/unreal-blueprints/ConfigureAndLoginAsync.png differ diff --git a/images/unreal-blueprints/ConfigureAndLoginAuthToken.png b/images/unreal-blueprints/ConfigureAndLoginAuthToken.png new file mode 100644 index 000000000..8ec3be887 Binary files /dev/null and b/images/unreal-blueprints/ConfigureAndLoginAuthToken.png differ diff --git a/images/unreal-blueprints/ExampleOnUserOnlineEvent.png b/images/unreal-blueprints/ExampleOnUserOnlineEvent.png new file mode 100644 index 000000000..6f5d89c6c Binary files /dev/null and b/images/unreal-blueprints/ExampleOnUserOnlineEvent.png differ diff --git a/images/unreal-blueprints/FetchCoversationsAsync.png b/images/unreal-blueprints/FetchCoversationsAsync.png new file mode 100644 index 000000000..2f79d761d Binary files /dev/null and b/images/unreal-blueprints/FetchCoversationsAsync.png differ diff --git a/images/unreal-blueprints/FetchGroupsAsync.png b/images/unreal-blueprints/FetchGroupsAsync.png new file mode 100644 index 000000000..c832068c8 Binary files /dev/null and b/images/unreal-blueprints/FetchGroupsAsync.png differ diff --git a/images/unreal-blueprints/FetchUsersAsync.png b/images/unreal-blueprints/FetchUsersAsync.png new file mode 100644 index 000000000..3754e50ab Binary files /dev/null and b/images/unreal-blueprints/FetchUsersAsync.png differ diff --git a/images/unreal-blueprints/FlagMessageAsync.png b/images/unreal-blueprints/FlagMessageAsync.png new file mode 100644 index 000000000..c4cc255ec Binary files /dev/null and b/images/unreal-blueprints/FlagMessageAsync.png differ diff --git a/images/unreal-blueprints/GetGroupMessagesAyync.png b/images/unreal-blueprints/GetGroupMessagesAyync.png new file mode 100644 index 000000000..23e08b826 Binary files /dev/null and b/images/unreal-blueprints/GetGroupMessagesAyync.png differ diff --git a/images/unreal-blueprints/GetLoggedInUser.png b/images/unreal-blueprints/GetLoggedInUser.png new file mode 100644 index 000000000..30f1fa243 Binary files /dev/null and b/images/unreal-blueprints/GetLoggedInUser.png differ diff --git a/images/unreal-blueprints/GetMessagesAsync.png b/images/unreal-blueprints/GetMessagesAsync.png new file mode 100644 index 000000000..02b5e9009 Binary files /dev/null and b/images/unreal-blueprints/GetMessagesAsync.png differ diff --git a/images/unreal-blueprints/JoinGroupAsync.png b/images/unreal-blueprints/JoinGroupAsync.png new file mode 100644 index 000000000..c5c52e991 Binary files /dev/null and b/images/unreal-blueprints/JoinGroupAsync.png differ diff --git a/images/unreal-blueprints/LeaveGroupAsync.png b/images/unreal-blueprints/LeaveGroupAsync.png new file mode 100644 index 000000000..43f479a3c Binary files /dev/null and b/images/unreal-blueprints/LeaveGroupAsync.png differ diff --git a/images/unreal-blueprints/LoginAsync.png b/images/unreal-blueprints/LoginAsync.png new file mode 100644 index 000000000..b6557fc23 Binary files /dev/null and b/images/unreal-blueprints/LoginAsync.png differ diff --git a/images/unreal-blueprints/LoginWithAuthTokenAsync.png b/images/unreal-blueprints/LoginWithAuthTokenAsync.png new file mode 100644 index 000000000..513319a58 Binary files /dev/null and b/images/unreal-blueprints/LoginWithAuthTokenAsync.png differ diff --git a/images/unreal-blueprints/LogoutAsync.png b/images/unreal-blueprints/LogoutAsync.png new file mode 100644 index 000000000..723fdfc3e Binary files /dev/null and b/images/unreal-blueprints/LogoutAsync.png differ diff --git a/images/unreal-blueprints/SendGroupMessageAsync.png b/images/unreal-blueprints/SendGroupMessageAsync.png new file mode 100644 index 000000000..50b230b9a Binary files /dev/null and b/images/unreal-blueprints/SendGroupMessageAsync.png differ diff --git a/images/unreal-blueprints/SendMessageAsync.png b/images/unreal-blueprints/SendMessageAsync.png new file mode 100644 index 000000000..190fb6c8a Binary files /dev/null and b/images/unreal-blueprints/SendMessageAsync.png differ diff --git a/sdk/unreal/advanced-configuration.mdx b/sdk/unreal/advanced-configuration.mdx new file mode 100644 index 000000000..ed8278fd1 --- /dev/null +++ b/sdk/unreal/advanced-configuration.mdx @@ -0,0 +1,249 @@ +--- +title: "Advanced Configuration" +description: "Fine-tune SDK settings, manage connections manually, and query authentication state." +--- + +Beyond the basic `Configure` call, the CometChat Unreal SDK offers advanced configuration for custom hosts, manual connection management, and runtime state queries. + +--- + +## ConfigureWithSettings + +Use `ConfigureWithSettings` instead of `Configure` when you need control over connection behavior, custom hosts, or presence subscription settings. + + + +1. Create an `FCometChatAppSettings` struct +2. Set the desired properties (region, custom hosts, auto-connect behavior) +3. Call **Configure With Settings** on the CometChat Subsystem with your App ID and the settings struct + + +```cpp +void AMyActor::InitCometChat() +{ + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + + FCometChatAppSettings Settings; + Settings.Region = TEXT("us"); + Settings.bAutoEstablishSocketConnection = false; // Manual connection mode + Settings.SubscriptionType = TEXT("allUsers"); + + Chat->ConfigureWithSettings(TEXT("YOUR_APP_ID"), Settings); +} +``` + + + +### FCometChatAppSettings + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Region` | `FString` | — | App region (`us` or `eu`) | +| `SubscriptionType` | `FString` | — | Presence subscription type (`allUsers`, `roles`, `friends`) | +| `Roles` | `TArray` | — | Roles to subscribe to (when `SubscriptionType` is `roles`) | +| `AdminHost` | `FString` | — | Custom admin API host URL | +| `ClientHost` | `FString` | — | Custom client/WebSocket host URL | +| `bAutoEstablishSocketConnection` | `bool` | `true` | Automatically connect WebSocket on login | + + +When `bAutoEstablishSocketConnection` is `true` (default), the SDK connects the WebSocket immediately after a successful login. Set to `false` if you want to control when the connection is established — useful for splash screens or loading flows. + + +--- + +## Manual Connection Management + +When `bAutoEstablishSocketConnection` is `false`, use the async connection nodes to control the WebSocket lifecycle. + +### Connect + +Manually establish the WebSocket connection after login. + + + +Call the **Connect Async** node after login succeeds. Handle **On Success** to know the connection is ready. + + +```cpp +void AMyActor::ManualConnect() +{ + auto* Action = UCometChatConnectAction::Connect(this); + Action->OnSuccess.AddDynamic(this, &AMyActor::HandleConnected); + Action->OnFailure.AddDynamic(this, &AMyActor::HandleError); + Action->Activate(); +} + +void AMyActor::HandleConnected() +{ + UE_LOG(LogTemp, Log, TEXT("WebSocket connected — ready to receive events")); +} +``` + + + +### Disconnect + +Manually close the WebSocket connection without logging out. + + + +Call the **Disconnect Async** node. The user remains authenticated but won't receive real-time events. + + +```cpp +void AMyActor::ManualDisconnect() +{ + auto* Action = UCometChatDisconnectAction::Disconnect(this); + Action->OnSuccess.AddDynamic(this, &AMyActor::HandleDisconnected); + Action->OnFailure.AddDynamic(this, &AMyActor::HandleError); + Action->Activate(); +} +``` + + + +### Ping + +Verify the connection is alive by sending a ping to the server. + + + +Call the **Ping Async** node. **On Success** means the server responded — connection is healthy. + + +```cpp +void AMyActor::PingServer() +{ + auto* Action = UCometChatPingAction::Ping(this); + Action->OnSuccess.AddDynamic(this, &AMyActor::HandlePingSuccess); + Action->OnFailure.AddDynamic(this, &AMyActor::HandlePingFailed); + Action->Activate(); +} +``` + + + +--- + +## Connection Status + +Query the current WebSocket connection state at any time. + + + +Call **Get Connection Status** on the CometChat Subsystem. Returns an `ECometChatConnectionState` enum. + + +```cpp +void AMyActor::CheckConnection() +{ + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + ECometChatConnectionState State = Chat->GetConnectionStatus(); + + switch (State) + { + case ECometChatConnectionState::Connected: + UE_LOG(LogTemp, Log, TEXT("Connected")); + break; + case ECometChatConnectionState::Connecting: + UE_LOG(LogTemp, Log, TEXT("Connecting...")); + break; + case ECometChatConnectionState::Disconnected: + UE_LOG(LogTemp, Warning, TEXT("Disconnected")); + break; + case ECometChatConnectionState::FeatureThrottled: + UE_LOG(LogTemp, Warning, TEXT("Feature throttled")); + break; + } +} +``` + + + +### ECometChatConnectionState + +| Value | Description | +| ----- | ----------- | +| `Connected` | WebSocket is active and receiving events | +| `Connecting` | SDK is attempting to establish the connection | +| `Disconnected` | WebSocket is closed | +| `FeatureThrottled` | A feature is being rate-limited by the server | + +--- + +## Authentication State + +### IsLoggedIn + +Check whether a user is currently authenticated. + + + +Call **Is Logged In** on the CometChat Subsystem. Returns a `bool`. + + +```cpp +bool bLoggedIn = Chat->IsLoggedIn(); +``` + + + +### GetLoggedInUser + +Retrieve the currently authenticated user's profile. + + + + + + + +Call **Get Logged In User** on the CometChat Subsystem. Returns an `FCometChatUser`. + + +```cpp +FCometChatUser CurrentUser = Chat->GetLoggedInUser(); +UE_LOG(LogTemp, Log, TEXT("Logged in as: %s (%s)"), *CurrentUser.Name, *CurrentUser.Uid); +``` + + + +--- + +## Connection Flow (Manual Mode) + +```mermaid +flowchart TD + A["ConfigureWithSettings
(bAutoEstablishSocketConnection = false)"] --> B["Login Async"] + B -->|"On Success"| C["User authenticated
(no WebSocket yet)"] + C --> D["Connect Async"] + D -->|"On Success"| E["WebSocket active
Real-time events flowing"] + E --> F["Disconnect Async"] + F -->|"On Success"| G["WebSocket closed
(still authenticated)"] + G --> D + + style A fill:#333,stroke:#666,color:#fff + style B fill:#444,stroke:#888,color:#fff + style C fill:#333,stroke:#666,color:#fff + style D fill:#444,stroke:#888,color:#fff + style E fill:#333,stroke:#666,color:#fff + style F fill:#444,stroke:#888,color:#fff + style G fill:#333,stroke:#666,color:#fff +``` + + +**When to use manual mode**: If your game has a loading screen or lobby where you don't need real-time events yet, configure with `bAutoEstablishSocketConnection = false`, then call `Connect` when the player enters the chat-enabled area. This saves bandwidth and server resources. + + +--- + +## Next Steps + + + + Log users in with Auth Key or Auth Token. + + + Listen for connection state changes and other events. + + diff --git a/sdk/unreal/authentication.mdx b/sdk/unreal/authentication.mdx index 00d208c81..01560fe32 100644 --- a/sdk/unreal/authentication.mdx +++ b/sdk/unreal/authentication.mdx @@ -1,5 +1,5 @@ --- -title: "Authentication" +title: "Overview" description: "Log users in and out of CometChat in your Unreal Engine project." --- @@ -41,13 +41,12 @@ flowchart LR style F fill:#333,stroke:#666,color:#fff ``` -The Login node authenticates a user with CometChat. You should call it: - -1. When the user is logging in for the first time -2. When `IsLoggedIn` returns `false` - + + + + 1. Get a reference to the **CometChat Subsystem** 2. Call the **Login Async** node 3. Wire the **On Success** and **On Failure** pins @@ -138,6 +137,10 @@ flowchart LR + + + + 1. Get a reference to the **CometChat Subsystem** 2. Call the **Login With Auth Token Async** node 3. Wire the **On Success** and **On Failure** pins @@ -192,7 +195,11 @@ Before performing operations, you can check whether a user is currently logged i -Call the **Is Logged In** node on the CometChat Subsystem. It returns a `bool`. + + + + +Call the **Get Logged In User** node on the CometChat Subsystem. It returns an `FCometChatUser` — if the `Uid` is empty, no user is logged in. ```cpp @@ -214,6 +221,10 @@ Logs the current user out and disconnects the real-time WebSocket. + + + + Call the **Logout Async** node on the CometChat Subsystem. Wire the **On Success** and **On Failure** pins. @@ -258,6 +269,9 @@ You typically don't need to call Shutdown manually — the Subsystem's `Deinitia ## Next Steps + + Return to the SDK overview and architecture. + Send your first text message after logging in. diff --git a/sdk/unreal/conversations.mdx b/sdk/unreal/conversations.mdx new file mode 100644 index 000000000..3c01cbeb7 --- /dev/null +++ b/sdk/unreal/conversations.mdx @@ -0,0 +1,130 @@ +--- +title: "Conversations" +description: "Fetch and display the user's conversation list with unread counts and last messages." +--- + +Conversations represent the chat threads a user is part of — both 1:1 and group. Use the **Fetch Conversations Async** node to retrieve the list with unread counts, last messages, and metadata. + +--- + +## Fetch Conversations + + + + + + + +1. Create an `FCometChatConversationsRequest` struct +2. Set filters (conversation type, tags, unread only, etc.) +3. Call the **Fetch Conversations Async** node +4. On Success, iterate the returned `TArray` + + +```cpp +void AMyActor::FetchConversations() +{ + FCometChatConversationsRequest Request; + Request.Limit = 20; + // Request.ConversationType = TEXT("group"); // optional filter + + auto* Action = UCometChatFetchConversationsAction::FetchConversations(this, Request); + Action->OnSuccess.AddDynamic(this, &AMyActor::HandleConversations); + Action->OnFailure.AddDynamic(this, &AMyActor::HandleError); + Action->Activate(); +} + +void AMyActor::HandleConversations(const TArray& Conversations) +{ + for (const auto& Conv : Conversations) + { + FString Name = Conv.ConversationType == TEXT("user") + ? Conv.ConversationWithUser.Name + : Conv.ConversationWithGroup.Name; + + UE_LOG(LogTemp, Log, TEXT("%s — Unread: %d — Last: %s"), + *Name, Conv.UnreadMessageCount, *Conv.LastMessage.Text); + } +} +``` + + + +--- + +## FCometChatConversationsRequest + +Configure the request to filter and paginate results. + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `30` | Max conversations per page | +| `ConversationType` | `FString` | — | Filter: `user` or `group` | +| `bWithUserAndGroupTags` | `bool` | `false` | Include user/group tags | +| `Tags` | `TArray` | — | Filter by conversation tags | +| `bWithTags` | `bool` | `false` | Include tags in response | +| `UserTags` | `TArray` | — | Filter by user tags | +| `GroupTags` | `TArray` | — | Filter by group tags | +| `bIncludeBlockedUsers` | `bool` | `false` | Include blocked users | +| `bWithBlockedInfo` | `bool` | `false` | Include blocked info | +| `SearchKeyword` | `FString` | — | Search conversations | +| `bUnread` | `bool` | `false` | Only unread conversations | +| `Page` | `int32` | `0` | Page number | +| `bHideAgentic` | `bool` | `false` | Hide AI/bot conversations | +| `bOnlyAgentic` | `bool` | `false` | Only AI/bot conversations | + +--- + +## FCometChatConversation + +The struct returned for each conversation. + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `ConversationId` | `FString` | Unique conversation identifier | +| `ConversationType` | `FString` | `user` or `group` | +| `LastMessage` | `FCometChatMessage` | Most recent message in the conversation | +| `ConversationWithUser` | `FCometChatUser` | The other user (populated for 1:1 conversations) | +| `ConversationWithGroup` | `FCometChatGroup` | The group (populated for group conversations) | +| `UnreadMessageCount` | `int32` | Number of unread messages | +| `UpdatedAt` | `int64` | Last activity timestamp | +| `Tags` | `TArray` | Conversation tags | +| `UnreadMentionsCount` | `int32` | Number of unread mentions | +| `LastReadMessageId` | `int64` | ID of last read message | +| `LatestMessageId` | `int64` | ID of latest message | + +--- + +## Conversation Flow + +```mermaid +flowchart TD + A["Fetch Conversations Async"] --> B{"ConversationType?"} + B -->|"user"| C["Show 1:1 chat
ConversationWithUser.Name"] + B -->|"group"| D["Show group chat
ConversationWithGroup.Name"] + C --> E["Display LastMessage.Text
+ UnreadMessageCount badge"] + D --> E + + style A fill:#444,stroke:#888,color:#fff + style B fill:#333,stroke:#666,color:#fff + style C fill:#333,stroke:#666,color:#fff + style D fill:#333,stroke:#666,color:#fff + style E fill:#333,stroke:#666,color:#fff +``` + + +**Pagination**: Set `Page` to fetch subsequent pages. Check if the returned array count equals `Limit` to determine if more pages exist. + + +--- + +## Next Steps + + + + Send messages in a conversation. + + + Listen for new messages to update the conversation list. + + diff --git a/sdk/unreal/groups.mdx b/sdk/unreal/groups.mdx index 75515c162..3e276c101 100644 --- a/sdk/unreal/groups.mdx +++ b/sdk/unreal/groups.mdx @@ -8,19 +8,24 @@ Groups let multiple users communicate in a shared conversation. The CometChat Un ### Group Lifecycle ```mermaid -flowchart LR - A["Create Group Async"] --> B["Group exists"] - B --> C["Join Group Async"] - C --> D["Member of group"] - D --> E["Send / Receive messages"] - D --> F["Leave Group Async"] +flowchart TD + A["Fetch Groups Async"] --> B["Browse available groups"] + C["Create Group Async"] --> D["You are the owner + member"] + B --> E["Join Group Async"] + E --> D + D --> F["Send / Receive messages"] + D --> G["Fetch Group Members"] + D --> H["Leave Group Async"] + H --> B style A fill:#444,stroke:#888,color:#fff style B fill:#333,stroke:#666,color:#fff style C fill:#444,stroke:#888,color:#fff style D fill:#333,stroke:#666,color:#fff - style E fill:#333,stroke:#666,color:#fff - style F fill:#555,stroke:#999,color:#ccc + style E fill:#444,stroke:#888,color:#fff + style F fill:#333,stroke:#666,color:#fff + style G fill:#333,stroke:#666,color:#fff + style H fill:#555,stroke:#999,color:#ccc ``` --- @@ -83,6 +88,10 @@ Join an existing group by its GUID. + + + + Call the **Join Group Async** node. | Parameter | Type | Description | @@ -124,6 +133,10 @@ Leave a group you're currently a member of. + + + + Call the **Leave Group Async** node. | Parameter | Type | Description | @@ -159,6 +172,39 @@ void AMyActor::OnLeaveFailed(const FString& Error) --- +## Fetch Groups + +Retrieve a list of groups with optional search and filters. + + + + + + + +Call the **Fetch Groups Async** node with an `FCometChatGroupsRequest` struct. Set `bJoinedOnly = true` to only fetch groups the user has joined, or leave it `false` to browse all available groups. + + +```cpp +#include "AsyncActions/CometChatFetchGroupsAction.h" + +void AMyActor::FetchGroups() +{ + FCometChatGroupsRequest Request; + Request.Limit = 20; + Request.bJoinedOnly = true; + + auto* Action = UCometChatFetchGroupsAction::FetchGroups(this, Request); + Action->OnSuccess.AddDynamic(this, &AMyActor::OnGroupsFetched); + Action->OnFailure.AddDynamic(this, &AMyActor::OnFetchFailed); + Action->Activate(); +} +``` + + + +--- + ## Send a Group Message Send a text message to all members of a group. See [Send a Message → Group Messages](/sdk/unreal/send-message#send-a-group-message) for details. diff --git a/sdk/unreal/moderation.mdx b/sdk/unreal/moderation.mdx new file mode 100644 index 000000000..ff66d1c0b --- /dev/null +++ b/sdk/unreal/moderation.mdx @@ -0,0 +1,182 @@ +--- +title: "Moderation" +description: "Flag messages for review and track moderation status." +--- + +The CometChat Unreal SDK provides moderation tools to let users report inappropriate content. You can flag messages with a reason, fetch available flag reasons, and track moderation status on messages. + +--- + +## Flag a Message + +Use the **Flag Message Async** node to report a message for moderation review. + + + + + + + +1. Create an `FCometChatFlagDetail` struct with the `ReasonId` and optional `Remark` +2. Call the **Flag Message Async** node with the message ID and flag detail +3. Handle **On Success** (message flagged) or **On Failure** (error) + + +```cpp +void AMyActor::FlagMessage(const FString& MessageId) +{ + FCometChatFlagDetail FlagDetail; + FlagDetail.ReasonId = TEXT("spam"); + FlagDetail.Remark = TEXT("This message is spam"); + + auto* Action = UCometChatFlagMessageAction::FlagMessage(this, MessageId, FlagDetail); + Action->OnSuccess.AddDynamic(this, &AMyActor::HandleFlagSuccess); + Action->OnFailure.AddDynamic(this, &AMyActor::HandleError); + Action->Activate(); +} + +void AMyActor::HandleFlagSuccess() +{ + UE_LOG(LogTemp, Log, TEXT("Message flagged successfully")); +} +``` + + + +--- + +## Get Flag Reasons + +Fetch the list of available reasons a user can select when flagging a message. + + + +1. Call the **Get Flag Reasons Async** node (no parameters needed) +2. On Success, iterate the returned `TArray` +3. Display the reasons in a UI picker for the user to select from + + +```cpp +void AMyActor::FetchFlagReasons() +{ + auto* Action = UCometChatGetFlagReasonsAction::GetFlagReasons(this); + Action->OnSuccess.AddDynamic(this, &AMyActor::HandleFlagReasons); + Action->OnFailure.AddDynamic(this, &AMyActor::HandleError); + Action->Activate(); +} + +void AMyActor::HandleFlagReasons(const TArray& Reasons) +{ + for (const auto& Reason : Reasons) + { + UE_LOG(LogTemp, Log, TEXT("Reason: %s — %s"), *Reason.Name, *Reason.Description); + } +} +``` + + + +--- + +## Moderation Status on Messages + +Every `FCometChatMessage` includes a `ModerationStatus` field of type `ECometChatModerationStatus`. Use this to filter or visually indicate moderated content in your UI. + +```mermaid +flowchart LR + A["Message Sent"] --> B["Unmoderated"] + B --> C{"Auto-moderation
or manual review"} + C -->|"Approved"| D["Approved ✓"] + C -->|"Flagged"| E["Pending Review"] + E -->|"Reviewer approves"| D + E -->|"Reviewer rejects"| F["Disapproved ✗"] + + style A fill:#333,stroke:#666,color:#fff + style B fill:#444,stroke:#888,color:#fff + style C fill:#555,stroke:#999,color:#ccc + style D fill:#333,stroke:#666,color:#fff + style E fill:#444,stroke:#888,color:#fff + style F fill:#333,stroke:#666,color:#fff +``` + +### ECometChatModerationStatus + +| Value | Description | +| ----- | ----------- | +| `Unmoderated` | Message has not been moderated | +| `Pending` | Message is pending moderation review | +| `Approved` | Message has been approved by moderation | +| `Disapproved` | Message has been rejected by moderation | + +### Real-Time Moderation Updates + +Listen to the `OnMessageModerated` delegate to receive real-time updates when a message's moderation status changes: + + + +Bind to **On Message Moderated** on the CometChat Subsystem. The event provides the updated `FCometChatMessage` with the new `ModerationStatus`. + + +```cpp +void AMyActor::BeginPlay() +{ + Super::BeginPlay(); + + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + Chat->OnMessageModerated.AddDynamic(this, &AMyActor::HandleMessageModerated); +} + +void AMyActor::HandleMessageModerated(const FCometChatMessage& Message) +{ + switch (Message.ModerationStatus) + { + case ECometChatModerationStatus::Approved: + UE_LOG(LogTemp, Log, TEXT("Message %s approved"), *Message.Id); + break; + case ECometChatModerationStatus::Disapproved: + UE_LOG(LogTemp, Log, TEXT("Message %s disapproved — hiding"), *Message.Id); + HideMessage(Message.Id); + break; + default: + break; + } +} +``` + + + +--- + +## FCometChatFlagDetail + +The struct you provide when flagging a message. + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `ReasonId` | `FString` | ID of the flag reason (from `GetFlagReasons`) | +| `Remark` | `FString` | Optional free-text remark from the reporter | + +## FCometChatFlagReason + +The struct returned when fetching available flag reasons. + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Id` | `FString` | Unique reason identifier | +| `Name` | `FString` | Display name (e.g., "Spam", "Harassment") | +| `Description` | `FString` | Detailed description of the reason | +| `CreatedAt` | `int64` | Creation timestamp | +| `UpdatedAt` | `int64` | Last update timestamp | + +--- + +## Next Steps + + + + Listen for moderation status changes in real time. + + + Complete reference of all structs and enums. + + diff --git a/sdk/unreal/overview.mdx b/sdk/unreal/overview.mdx index 269f7d238..ce61ee92b 100644 --- a/sdk/unreal/overview.mdx +++ b/sdk/unreal/overview.mdx @@ -138,9 +138,14 @@ All callbacks fire on the **Game Thread** — safe to update UI directly. | -------- | ------------ | | **Authentication** | Login with Auth Key, Login with Auth Token, Logout, session check | | **Messaging** | Send & receive text messages (1:1 and group), message history with pagination | -| **Users** | Fetch user profiles, real-time presence | -| **Groups** | Create, join, leave groups, group messaging | -| **Real-Time Events** | Message received, presence changed, typing indicators, read receipts, connection state | +| **Users** | Fetch user profiles, real-time presence (online/offline) | +| **Groups** | Create, join, leave groups, group messaging, member management | +| **Conversations** | Fetch conversations list with unread counts, last message, tags | +| **Real-Time Events** | 40+ delegates: messages, typing, receipts, reactions, presence, groups, calls, connection, login, AI | +| **Moderation / Flagging** | Flag messages, get flag reasons, moderation status tracking | +| **AI Assistant** | AI assistant events, tool results, tool arguments | +| **Transient Messages** | Send ephemeral messages that aren't persisted | +| **UI Components** | Ready-to-use `CometChatPanel` (tabbed chat) and `CometChatButton` (floating toggle) | --- diff --git a/sdk/unreal/real-time-events.mdx b/sdk/unreal/real-time-events.mdx index cd7c43fa8..f0af0c37e 100644 --- a/sdk/unreal/real-time-events.mdx +++ b/sdk/unreal/real-time-events.mdx @@ -1,9 +1,9 @@ --- title: "Real-Time Events" -description: "Listen for incoming messages, presence changes, typing indicators, receipts, and connection state." +description: "Listen for incoming messages, presence changes, typing indicators, receipts, group events, and connection state." --- -The `UCometChatSubsystem` exposes five multicast delegates that fire whenever the server pushes a real-time update. All delegates are guaranteed to fire on the **Game Thread**, so you can safely update UI directly. +The `UCometChatSubsystem` exposes 40+ multicast delegates organized by listener type. All delegates fire on the **Game Thread**, so you can safely update UI directly. ### Event Flow @@ -30,7 +30,7 @@ flowchart LR 1. Get a reference to the **CometChat Subsystem** -2. Drag off the Subsystem pin and search for the delegate name (e.g., **On Message Received**) +2. Drag off the Subsystem pin and search for the delegate name (e.g., **On Text Message Received**) 3. Select **Bind Event** to wire it to a custom event node 4. The custom event automatically gets the correct parameter type @@ -42,11 +42,19 @@ void AMyActor::BeginPlay() UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); - Chat->OnMessageReceived.AddDynamic(this, &AMyActor::HandleMessage); - Chat->OnPresenceChanged.AddDynamic(this, &AMyActor::HandlePresence); - Chat->OnTypingChanged.AddDynamic(this, &AMyActor::HandleTyping); - Chat->OnReceiptReceived.AddDynamic(this, &AMyActor::HandleReceipt); - Chat->OnConnectionStateChanged.AddDynamic(this, &AMyActor::HandleConnection); + // Message events + Chat->OnTextMessageReceived.AddDynamic(this, &AMyActor::HandleTextMessage); + Chat->OnTypingStarted.AddDynamic(this, &AMyActor::HandleTypingStarted); + + // User events + Chat->OnUserOnline.AddDynamic(this, &AMyActor::HandleUserOnline); + + // Group events + Chat->OnGroupMemberJoined.AddDynamic(this, &AMyActor::HandleMemberJoined); + + // Connection events + Chat->OnConnected.AddDynamic(this, &AMyActor::HandleConnected); + Chat->OnDisconnected.AddDynamic(this, &AMyActor::HandleDisconnected); } ```
@@ -54,26 +62,45 @@ void AMyActor::BeginPlay() --- -## OnMessageReceived - -Fires when a new message arrives in any conversation (1:1 or group). - -| Payload | Type | -| ------- | ---- | -| `Message` | `FCometChatMessage` | +## MessageListener Events + +These fire when messages, typing indicators, receipts, or reactions arrive. + +| Delegate | Payload | Fires When | +| -------- | ------- | ---------- | +| `OnTextMessageReceived` | `FCometChatMessage` | A text message arrives | +| `OnMediaMessageReceived` | `FCometChatMessage` | A media (image/video/audio/file) message arrives | +| `OnCustomMessageReceived` | `FCometChatMessage` | A custom message arrives | +| `OnInteractiveMessageReceived` | `FCometChatMessage` | An interactive message arrives | +| `OnInteractionGoalCompleted` | `FCometChatInteractionReceipt` | An interaction goal is completed | +| `OnTypingStarted` | `FCometChatTypingIndicator` | A user starts typing | +| `OnTypingEnded` | `FCometChatTypingIndicator` | A user stops typing | +| `OnMessagesDelivered` | `FCometChatMessageReceipt` | Messages delivered to recipient | +| `OnMessagesRead` | `FCometChatMessageReceipt` | Messages read by recipient | +| `OnMessagesDeliveredToAll` | `FCometChatMessageReceipt` | Messages delivered to all group members | +| `OnMessagesReadByAll` | `FCometChatMessageReceipt` | Messages read by all group members | +| `OnMessageEdited` | `FCometChatMessage` | A message is edited | +| `OnMessageDeleted` | `FCometChatMessage` | A message is deleted | +| `OnTransientMessageReceived` | `FCometChatTransientMessage` | A transient (ephemeral) message arrives | +| `OnMessageReactionAdded` | `FCometChatReactionEvent` | A reaction is added to a message | +| `OnMessageReactionRemoved` | `FCometChatReactionEvent` | A reaction is removed from a message | +| `OnMessageModerated` | `FCometChatMessage` | A message moderation status changes | +| `OnAIAssistantMessageReceived` | `FCometChatMessage` | An AI assistant message arrives | +| `OnAIToolResultReceived` | `FCometChatMessage` | An AI tool result arrives | +| `OnAIToolArgumentsReceived` | `FCometChatMessage` | AI tool arguments arrive | -The custom event receives an `FCometChatMessage`. Use `ReceiverType` to check if it's a `user` (1:1) or `group` message, and `ConversationId` to route it to the right chat window. +Bind to **On Text Message Received**. The custom event receives an `FCometChatMessage`. Use `ReceiverType` to check if it's a `user` (1:1) or `group` message. ```cpp -void AMyActor::HandleMessage(const FCometChatMessage& Message) +void AMyActor::HandleTextMessage(const FCometChatMessage& Message) { if (Message.ReceiverType == TEXT("group")) { UE_LOG(LogTemp, Log, TEXT("[Group %s] %s: %s"), - *Message.ConversationId, *Message.SenderName, *Message.Text); + *Message.ReceiverUid, *Message.SenderName, *Message.Text); } else { @@ -87,151 +114,279 @@ void AMyActor::HandleMessage(const FCometChatMessage& Message) --- -## OnPresenceChanged +## UserListener Events + +These fire when a user's online status changes. -Fires when a user's online status changes. + + + -| Payload | Type | -| ------- | ---- | -| `Presence` | `FCometChatPresence` | +| Delegate | Payload | Fires When | +| -------- | ------- | ---------- | +| `OnUserOnline` | `FCometChatUser` | A user comes online | +| `OnUserOffline` | `FCometChatUser` | A user goes offline | -The custom event receives an `FCometChatPresence` with `Uid`, `Status` (an `ECometChatPresenceStatus` enum), and `LastActiveAt`. +Bind to **On User Online** / **On User Offline**. The custom event receives an `FCometChatUser` with the user's full profile. ```cpp -void AMyActor::HandlePresence(const FCometChatPresence& Presence) +void AMyActor::HandleUserOnline(const FCometChatUser& User) { - FString StatusStr; - switch (Presence.Status) - { - case ECometChatPresenceStatus::Online: StatusStr = TEXT("Online"); break; - case ECometChatPresenceStatus::Offline: StatusStr = TEXT("Offline"); break; - case ECometChatPresenceStatus::Away: StatusStr = TEXT("Away"); break; - } + UE_LOG(LogTemp, Log, TEXT("%s is now online"), *User.Name); +} - UE_LOG(LogTemp, Log, TEXT("%s is now %s"), *Presence.Uid, *StatusStr); +void AMyActor::HandleUserOffline(const FCometChatUser& User) +{ + UE_LOG(LogTemp, Log, TEXT("%s went offline"), *User.Name); } ``` -For more details, see [Users → User Presence](/sdk/unreal/users#user-presence). - --- -## OnTypingChanged +## GroupListener Events -Fires when a user starts or stops typing in a conversation. +These fire when group membership changes occur. -| Payload | Type | -| ------- | ---- | -| `Event` | `FCometChatTypingEvent` | +| Delegate | Payload | Fires When | +| -------- | ------- | ---------- | +| `OnGroupMemberJoined` | `FCometChatAction`, `FCometChatUser`, `FCometChatGroup` | A user joins a group | +| `OnGroupMemberLeft` | `FCometChatAction`, `FCometChatUser`, `FCometChatGroup` | A user leaves a group | +| `OnGroupMemberKicked` | `FCometChatAction`, `FCometChatUser`, `FCometChatUser`, `FCometChatGroup` | A member is kicked (includes who kicked) | +| `OnGroupMemberBanned` | `FCometChatAction`, `FCometChatUser`, `FCometChatUser`, `FCometChatGroup` | A member is banned (includes who banned) | +| `OnGroupMemberUnbanned` | `FCometChatAction`, `FCometChatUser`, `FCometChatUser`, `FCometChatGroup` | A member is unbanned | +| `OnGroupMemberScopeChanged` | `FCometChatScopeChangeEvent` | A member's role/scope changes | +| `OnMemberAddedToGroup` | `FCometChatAction`, `FCometChatUser`, `FCometChatUser`, `FCometChatGroup` | A member is added by another user | -The custom event receives an `FCometChatTypingEvent` with `Uid`, `ConversationId`, and `bIsTyping`. +Bind to **On Group Member Joined**. The custom event receives the action, the user who joined, and the group. ```cpp -void AMyActor::HandleTyping(const FCometChatTypingEvent& Event) +void AMyActor::HandleMemberJoined(const FCometChatAction& Action, + const FCometChatUser& JoinedUser, const FCometChatGroup& Group) { - if (Event.bIsTyping) - { - UE_LOG(LogTemp, Log, TEXT("%s is typing in %s..."), - *Event.Uid, *Event.ConversationId); - } - else - { - UE_LOG(LogTemp, Log, TEXT("%s stopped typing in %s"), - *Event.Uid, *Event.ConversationId); - } + UE_LOG(LogTemp, Log, TEXT("%s joined group %s"), *JoinedUser.Name, *Group.Name); } ``` -For more details, see [Typing Indicators](/sdk/unreal/typing-indicators). +--- + +## ConnectionListener Events + +These fire when the WebSocket connection state changes. + +| Delegate | Payload | Fires When | +| -------- | ------- | ---------- | +| `OnConnected` | — | WebSocket connection established | +| `OnConnecting` | — | SDK is attempting to connect | +| `OnDisconnected` | — | WebSocket connection lost | +| `OnFeatureThrottled` | — | A feature is being rate-limited | +| `OnConnectionError` | `FCometChatError` | A connection error occurred | + + + +Bind to **On Connected**, **On Disconnected**, etc. These are parameterless events (except `OnConnectionError` which provides an `FCometChatError`). + + +```cpp +void AMyActor::HandleConnected() +{ + UE_LOG(LogTemp, Log, TEXT("Connected to CometChat")); +} + +void AMyActor::HandleDisconnected() +{ + UE_LOG(LogTemp, Warning, TEXT("Disconnected from CometChat")); +} + +void AMyActor::HandleConnectionError(const FCometChatError& Error) +{ + UE_LOG(LogTemp, Error, TEXT("Connection error: %s — %s"), *Error.Code, *Error.Message); +} +``` + + --- -## OnReceiptReceived +## LoginListener Events -Fires when a message is delivered to or read by the recipient. +These fire on login/logout lifecycle events. -| Payload | Type | -| ------- | ---- | -| `Event` | `FCometChatReceiptEvent` | +| Delegate | Payload | Fires When | +| -------- | ------- | ---------- | +| `OnLoginSuccess` | `FCometChatUser` | Login succeeds | +| `OnLoginFailure` | `FCometChatError` | Login fails | +| `OnLogoutSuccess` | — | Logout succeeds | +| `OnLogoutFailure` | `FCometChatError` | Logout fails | -The custom event receives an `FCometChatReceiptEvent` with `MessageId`, `Uid`, `Status` (`delivered` or `read`), and `Timestamp`. +Bind to **On Login Success** to receive the logged-in `FCometChatUser` after authentication completes. ```cpp -void AMyActor::HandleReceipt(const FCometChatReceiptEvent& Event) +void AMyActor::HandleLoginSuccess(const FCometChatUser& User) +{ + UE_LOG(LogTemp, Log, TEXT("Logged in as %s (%s)"), *User.Name, *User.Uid); +} + +void AMyActor::HandleLoginFailure(const FCometChatError& Error) { - UE_LOG(LogTemp, Log, TEXT("Message %s was %s by %s"), - *Event.MessageId, *Event.Status, *Event.Uid); + UE_LOG(LogTemp, Error, TEXT("Login failed: %s"), *Error.Message); } ``` -For more details, see [Delivery & Read Receipts](/sdk/unreal/delivery-read-receipts). +--- + +## AIAssistantListener Events + +These fire when AI assistant interactions occur. + +| Delegate | Payload | Fires When | +| -------- | ------- | ---------- | +| `OnAIAssistantEvent` | `FCometChatAIAssistantEvent` | An AI assistant event occurs | + + + +Bind to **On AI Assistant Event**. The custom event receives an `FCometChatAIAssistantEvent` with event type, data, conversation ID, and sender UID. + + +```cpp +void AMyActor::HandleAIAssistantEvent(const FCometChatAIAssistantEvent& Event) +{ + UE_LOG(LogTemp, Log, TEXT("AI event [%s] in conversation %s: %s"), + *Event.EventType, *Event.ConversationId, *Event.Data); +} +``` + + --- -## OnConnectionStateChanged +## Error Handling — FCometChatError + +Many delegates and failure callbacks provide an `FCometChatError` struct with details about what went wrong. Always handle errors gracefully in your game. -Fires when the WebSocket connection state changes. +### FCometChatError -| Payload | Type | -| ------- | ---- | -| `State` | `ECometChatConnectionState` | +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Code` | `FString` | Machine-readable error code (e.g., `"ERR_AUTH_FAILED"`, `"ERR_NETWORK"`) | +| `Message` | `FString` | Human-readable error description | +| `Details` | `FString` | Additional context (may be empty) | -| Value | Meaning | -| ----- | ------- | -| `Connected` | WebSocket is active and receiving events | -| `Disconnected` | Connection lost | -| `Reconnecting` | SDK is attempting to reconnect automatically | +### Handling Errors -The custom event receives an `ECometChatConnectionState` enum value. +All async nodes have an **On Failure** pin. Wire it to a custom event that receives an `FString` error message. Connection and login listener events provide the full `FCometChatError` struct. ```cpp -void AMyActor::HandleConnection(ECometChatConnectionState State) +// Async node failure handler (simple string) +void AMyActor::HandleError(const FString& Error) { - switch (State) - { - case ECometChatConnectionState::Connected: - UE_LOG(LogTemp, Log, TEXT("Connected to CometChat")); - break; - case ECometChatConnectionState::Disconnected: - UE_LOG(LogTemp, Warning, TEXT("Disconnected from CometChat")); - break; - case ECometChatConnectionState::Reconnecting: - UE_LOG(LogTemp, Warning, TEXT("Reconnecting...")); - break; - } + UE_LOG(LogTemp, Error, TEXT("Operation failed: %s"), *Error); + // Show error in UI, retry, or fallback +} + +// Connection/Login listener error handler (full struct) +void AMyActor::HandleConnectionError(const FCometChatError& Error) +{ + UE_LOG(LogTemp, Error, TEXT("Error [%s]: %s — %s"), + *Error.Code, *Error.Message, *Error.Details); + + // Common patterns: + // - "ERR_NETWORK": Show "No internet" banner, retry with backoff + // - "ERR_AUTH_FAILED": Redirect to login screen + // - "ERR_RATE_LIMIT": Wait and retry after delay } ``` -For more details, see [Connection Status](/sdk/unreal/connection-status). + +**Best practice**: Always bind `OnConnectionError` and `OnLoginFailure` delegates early. Network issues are common in games — show a reconnection banner rather than silently failing. + + +--- + +## Manual Connection + +By default, the SDK auto-connects the WebSocket after login. For games with loading screens or lobbies where real-time events aren't needed immediately, you can manage the connection manually. + +### Setup Manual Mode + +Set `bAutoEstablishSocketConnection = false` in `FCometChatAppSettings` when configuring: + +```cpp +FCometChatAppSettings Settings; +Settings.Region = TEXT("us"); +Settings.bAutoEstablishSocketConnection = false; +Chat->ConfigureWithSettings(TEXT("YOUR_APP_ID"), Settings); +``` + +### Connect / Disconnect / Ping + + + +- **Connect Async** — Establish the WebSocket after login +- **Disconnect Async** — Close the WebSocket (user stays authenticated) +- **Ping Async** — Verify the connection is alive + + +```cpp +// Connect when entering chat area +auto* Connect = UCometChatConnectAction::Connect(this); +Connect->OnSuccess.AddDynamic(this, &AMyActor::OnConnected); +Connect->OnFailure.AddDynamic(this, &AMyActor::HandleError); +Connect->Activate(); + +// Disconnect when leaving chat area +auto* Disconnect = UCometChatDisconnectAction::Disconnect(this); +Disconnect->OnSuccess.AddDynamic(this, &AMyActor::OnDisconnected); +Disconnect->Activate(); + +// Health check +auto* Ping = UCometChatPingAction::Ping(this); +Ping->OnSuccess.AddDynamic(this, &AMyActor::OnPingOk); +Ping->OnFailure.AddDynamic(this, &AMyActor::OnPingFailed); +Ping->Activate(); +``` + + + +### Query Connection State + +```cpp +ECometChatConnectionState State = Chat->GetConnectionStatus(); +// Connected, Connecting, Disconnected, or FeatureThrottled +``` + + +For full details on manual connection management, see [Advanced Configuration](/sdk/unreal/advanced-configuration). + --- -## Delegate Summary +## Next Steps -| Delegate | Payload | Use Case | -| -------- | ------- | -------- | -| `OnMessageReceived` | `FCometChatMessage` | Display new messages in chat UI | -| `OnPresenceChanged` | `FCometChatPresence` | Update online/offline indicators | -| `OnTypingChanged` | `FCometChatTypingEvent` | Show "typing..." animations | -| `OnReceiptReceived` | `FCometChatReceiptEvent` | Show delivery/read checkmarks | -| `OnConnectionStateChanged` | `ECometChatConnectionState` | Show connection status banners | + + + Send and receive typing state. + + + Drop-in chat panel and button widgets. + + diff --git a/sdk/unreal/receive-messages.mdx b/sdk/unreal/receive-messages.mdx index 699388b8e..b339bbc0b 100644 --- a/sdk/unreal/receive-messages.mdx +++ b/sdk/unreal/receive-messages.mdx @@ -41,6 +41,10 @@ Retrieve the message history for a 1:1 conversation. + + + + Call the **Get Messages Async** node. | Parameter | Type | Description | @@ -90,6 +94,10 @@ Retrieve the message history for a group conversation, with pagination support. + + + + Call the **Get Group Messages Async** node. | Parameter | Type | Description | diff --git a/sdk/unreal/reference.mdx b/sdk/unreal/reference.mdx index 0533b3d7a..6906f30d1 100644 --- a/sdk/unreal/reference.mdx +++ b/sdk/unreal/reference.mdx @@ -14,7 +14,13 @@ These are called directly on `UCometChatSubsystem`. | Method | Category | Parameters | Returns | Description | | ------ | -------- | ---------- | ------- | ----------- | | `Configure` | Config | `AppId: FString`, `Region: FString` | `void` | Initialize the SDK with your CometChat credentials. Must be called before Login. | +| `ConfigureWithSettings` | Config | `AppId: FString`, `Settings: FCometChatAppSettings` | `void` | Initialize with advanced settings (custom hosts, subscription type, manual connection). | | `IsLoggedIn` | Auth | — | `bool` | Returns `true` if a user is currently authenticated. | +| `GetLoggedInUser` | Auth | — | `FCometChatUser` | Returns the currently logged-in user's profile. | +| `GetConnectionStatus` | Connection | — | `ECometChatConnectionState` | Returns the current WebSocket connection state. | +| `StartTyping` | Typing | `Indicator: FCometChatTypingIndicator` | `void` | Notify that the local user started typing. | +| `EndTyping` | Typing | `Indicator: FCometChatTypingIndicator` | `void` | Notify that the local user stopped typing. | +| `SendTransientMessage` | Messaging | `Message: FCometChatTransientMessage` | `void` | Send an ephemeral message that is not persisted. | | `Shutdown` | Lifecycle | — | `void` | Tear down the SDK and release all resources. | --- @@ -27,7 +33,8 @@ Each node is a latent Blueprint action with **On Success** and **On Failure** ou | Node | Parameters | Success Output | Description | | ---- | ---------- | -------------- | ----------- | -| **Login Async** | `Uid: FString`, `AuthKey: FString` | — | Authenticate a user with CometChat. | +| **Login Async** | `Uid: FString`, `AuthKey: FString` | — | Authenticate a user with Auth Key. | +| **Login With Auth Token Async** | `AuthToken: FString` | — | Authenticate a user with a pre-generated Auth Token. | | **Logout Async** | — | — | Log out the current user and disconnect. | ### Messaging @@ -38,12 +45,14 @@ Each node is a latent Blueprint action with **On Success** and **On Failure** ou | **Send Group Message Async** | `Guid: FString`, `Text: FString` | `FCometChatMessage` | Send a text message to a group. | | **Get Messages Async** | `Uid: FString`, `Limit: int32` | `TArray` | Fetch message history for a 1:1 conversation. | | **Get Group Messages Async** | `Guid: FString`, `Limit: int32`, `BeforeMessageId: int32` | `TArray`, `FCometChatPagination` | Fetch paginated message history for a group. | +| **Fetch Messages Async** | `Request: FCometChatMessagesRequest` | `TArray` | Fetch messages with full filter/pagination control. | ### Users | Node | Parameters | Success Output | Description | | ---- | ---------- | -------------- | ----------- | | **Get User Async** | `Uid: FString` | `FCometChatUser` | Fetch a user's profile. | +| **Fetch Users Async** | `Request: FCometChatUsersRequest` | `TArray` | Fetch users with search, filters, and pagination. | ### Groups @@ -52,6 +61,29 @@ Each node is a latent Blueprint action with **On Success** and **On Failure** ou | **Create Group Async** | `Name: FString`, `MemberIds: TArray` | `FCometChatGroup` | Create a new group with initial members. | | **Join Group Async** | `Guid: FString` | — | Join an existing group. | | **Leave Group Async** | `Guid: FString` | — | Leave a group. | +| **Fetch Groups Async** | `Request: FCometChatGroupsRequest` | `TArray` | Fetch groups with search, filters, and pagination. | + +### Conversations + +| Node | Parameters | Success Output | Description | +| ---- | ---------- | -------------- | ----------- | +| **Fetch Conversations Async** | `Request: FCometChatConversationsRequest` | `TArray` | Fetch conversations with filters and pagination. | + +### Connection + +| Node | Parameters | Success Output | Description | +| ---- | ---------- | -------------- | ----------- | +| **Connect Async** | — | — | Manually establish the WebSocket connection. | +| **Disconnect Async** | — | — | Manually close the WebSocket connection. | +| **Ping Async** | — | — | Ping the server to verify connectivity. | + +### Moderation + +| Node | Parameters | Success Output | Description | +| ---- | ---------- | -------------- | ----------- | +| **Flag Message Async** | `MessageId: FString`, `FlagDetail: FCometChatFlagDetail` | — | Flag a message for moderation. | +| **Get Flag Reasons Async** | — | `TArray` | Fetch available flag/report reasons. | + --- @@ -59,13 +91,74 @@ Each node is a latent Blueprint action with **On Success** and **On Failure** ou All delegates are `UPROPERTY(BlueprintAssignable)` on `UCometChatSubsystem`. They fire on the **Game Thread**. +### MessageListener + +| Delegate | Payload Type | Fires When | +| -------- | ------------ | ---------- | +| `OnTextMessageReceived` | `FCometChatMessage` | Text message arrives | +| `OnMediaMessageReceived` | `FCometChatMessage` | Media message arrives | +| `OnCustomMessageReceived` | `FCometChatMessage` | Custom message arrives | +| `OnInteractiveMessageReceived` | `FCometChatMessage` | Interactive message arrives | +| `OnInteractionGoalCompleted` | `FCometChatInteractionReceipt` | Interaction goal completed | +| `OnTypingStarted` | `FCometChatTypingIndicator` | User starts typing | +| `OnTypingEnded` | `FCometChatTypingIndicator` | User stops typing | +| `OnMessagesDelivered` | `FCometChatMessageReceipt` | Messages delivered | +| `OnMessagesRead` | `FCometChatMessageReceipt` | Messages read | +| `OnMessagesDeliveredToAll` | `FCometChatMessageReceipt` | Messages delivered to all | +| `OnMessagesReadByAll` | `FCometChatMessageReceipt` | Messages read by all | +| `OnMessageEdited` | `FCometChatMessage` | Message edited | +| `OnMessageDeleted` | `FCometChatMessage` | Message deleted | +| `OnTransientMessageReceived` | `FCometChatTransientMessage` | Transient message arrives | +| `OnMessageReactionAdded` | `FCometChatReactionEvent` | Reaction added | +| `OnMessageReactionRemoved` | `FCometChatReactionEvent` | Reaction removed | +| `OnMessageModerated` | `FCometChatMessage` | Message moderation status changes | +| `OnAIAssistantMessageReceived` | `FCometChatMessage` | AI assistant message | +| `OnAIToolResultReceived` | `FCometChatMessage` | AI tool result | +| `OnAIToolArgumentsReceived` | `FCometChatMessage` | AI tool arguments | + +### UserListener + +| Delegate | Payload Type | Fires When | +| -------- | ------------ | ---------- | +| `OnUserOnline` | `FCometChatUser` | User comes online | +| `OnUserOffline` | `FCometChatUser` | User goes offline | + +### GroupListener + +| Delegate | Payload Type | Fires When | +| -------- | ------------ | ---------- | +| `OnGroupMemberJoined` | `FCometChatAction, FCometChatUser, FCometChatGroup` | Member joins | +| `OnGroupMemberLeft` | `FCometChatAction, FCometChatUser, FCometChatGroup` | Member leaves | +| `OnGroupMemberKicked` | `FCometChatAction, FCometChatUser, FCometChatUser, FCometChatGroup` | Member kicked | +| `OnGroupMemberBanned` | `FCometChatAction, FCometChatUser, FCometChatUser, FCometChatGroup` | Member banned | +| `OnGroupMemberUnbanned` | `FCometChatAction, FCometChatUser, FCometChatUser, FCometChatGroup` | Member unbanned | +| `OnGroupMemberScopeChanged` | `FCometChatScopeChangeEvent` | Member scope changed | +| `OnMemberAddedToGroup` | `FCometChatAction, FCometChatUser, FCometChatUser, FCometChatGroup` | Member added | + +### ConnectionListener + +| Delegate | Payload Type | Fires When | +| -------- | ------------ | ---------- | +| `OnConnected` | — | WebSocket connected | +| `OnConnecting` | — | Attempting to connect | +| `OnDisconnected` | — | WebSocket disconnected | +| `OnFeatureThrottled` | — | Feature rate-limited | +| `OnConnectionError` | `FCometChatError` | Connection error | + +### LoginListener + | Delegate | Payload Type | Fires When | | -------- | ------------ | ---------- | -| `OnMessageReceived` | `FCometChatMessage` | A new message arrives (1:1 or group) | -| `OnPresenceChanged` | `FCometChatPresence` | A user goes online, offline, or away | -| `OnTypingChanged` | `FCometChatTypingEvent` | A user starts or stops typing | -| `OnReceiptReceived` | `FCometChatReceiptEvent` | A message is delivered or read | -| `OnConnectionStateChanged` | `ECometChatConnectionState` | WebSocket connection state changes | +| `OnLoginSuccess` | `FCometChatUser` | Login succeeds | +| `OnLoginFailure` | `FCometChatError` | Login fails | +| `OnLogoutSuccess` | — | Logout succeeds | +| `OnLogoutFailure` | `FCometChatError` | Logout fails | + +### AIAssistantListener + +| Delegate | Payload Type | Fires When | +| -------- | ------------ | ---------- | +| `OnAIAssistantEvent` | `FCometChatAIAssistantEvent` | AI assistant event | --- @@ -79,23 +172,52 @@ All delegates are `UPROPERTY(BlueprintAssignable)` on `UCometChatSubsystem`. The | `Name` | `FString` | Display name | | `AvatarUrl` | `FString` | URL to avatar image | | `Status` | `FString` | Current status text | +| `Role` | `FString` | User role | +| `Metadata` | `FString` | Custom metadata JSON | +| `Link` | `FString` | Profile link | +| `StatusMessage` | `FString` | Status message | +| `LastActiveAt` | `int64` | Unix timestamp of last activity | +| `bHasBlockedMe` | `bool` | Whether this user has blocked the logged-in user | +| `bBlockedByMe` | `bool` | Whether the logged-in user has blocked this user | +| `Tags` | `TArray` | User tags | +| `DeactivatedAt` | `int64` | Unix timestamp of deactivation (0 if active) | ### FCometChatMessage | Property | Type | Description | | -------- | ---- | ----------- | | `Id` | `FString` | Unique message identifier | +| `Muid` | `FString` | Client-generated unique ID | | `SenderUid` | `FString` | UID of the sender | | `ReceiverUid` | `FString` | UID of the receiver (user or group) | | `Text` | `FString` | Message body | | `SentAt` | `int64` | Unix timestamp when sent | -| `Type` | `FString` | `text`, `image`, `file`, `custom` | +| `Type` | `FString` | `text`, `image`, `video`, `audio`, `file`, `custom` | | `Category` | `FString` | `message`, `action`, `call`, `custom` | | `ReceiverType` | `FString` | `user` or `group` | | `ConversationId` | `FString` | Conversation identifier | | `SenderName` | `FString` | Sender's display name | | `SenderAvatar` | `FString` | Sender's avatar URL | | `UpdatedAt` | `int64` | Unix timestamp of last update | +| `Metadata` | `FString` | Custom metadata JSON | +| `DeliveredAt` | `int64` | Delivery timestamp | +| `ReadAt` | `int64` | Read timestamp | +| `DeletedAt` | `int64` | Deletion timestamp | +| `EditedAt` | `int64` | Edit timestamp | +| `DeletedBy` | `FString` | UID of user who deleted | +| `EditedBy` | `FString` | UID of user who edited | +| `ParentMessageId` | `int64` | Parent message ID (for threads) | +| `ReplyCount` | `int32` | Number of replies | +| `UnreadRepliesCount` | `int32` | Number of unread replies | +| `MentionedUsers` | `TArray` | Users mentioned in this message | +| `bHasMentionedMe` | `bool` | Whether the logged-in user is mentioned | +| `Reactions` | `TArray` | Reaction counts | +| `Attachment` | `FCometChatAttachment` | File attachment (if media message) | +| `Caption` | `FString` | Media caption | +| `CustomData` | `FString` | Custom data JSON | +| `SubType` | `FString` | Message sub-type | +| `Tags` | `TArray` | Message tags | +| `ModerationStatus` | `ECometChatModerationStatus` | Moderation status | ### FCometChatGroup @@ -104,44 +226,300 @@ All delegates are `UPROPERTY(BlueprintAssignable)` on `UCometChatSubsystem`. The | `Guid` | `FString` | Unique group identifier | | `Name` | `FString` | Group display name | | `Description` | `FString` | Group description | -| `MemberIds` | `TArray` | UIDs of group members | +| `Type` | `FString` | `public`, `private`, or `password` | +| `Icon` | `FString` | Group icon URL | +| `Owner` | `FString` | UID of the group owner | +| `Metadata` | `FString` | Custom metadata JSON | +| `CreatedAt` | `int64` | Creation timestamp | +| `UpdatedAt` | `int64` | Last update timestamp | +| `bHasJoined` | `bool` | Whether the logged-in user has joined | +| `JoinedAt` | `int64` | When the logged-in user joined | +| `Scope` | `FString` | Logged-in user's scope (`admin`, `moderator`, `participant`) | +| `MembersCount` | `int32` | Number of members | +| `Tags` | `TArray` | Group tags | +| `bIsBannedFromGroup` | `bool` | Whether the logged-in user is banned | + +### FCometChatConversation -### FCometChatPagination +| Property | Type | Description | +| -------- | ---- | ----------- | +| `ConversationId` | `FString` | Unique conversation identifier | +| `ConversationType` | `FString` | `user` or `group` | +| `LastMessage` | `FCometChatMessage` | Most recent message | +| `ConversationWithUser` | `FCometChatUser` | The other user (if 1:1) | +| `ConversationWithGroup` | `FCometChatGroup` | The group (if group conversation) | +| `UnreadMessageCount` | `int32` | Number of unread messages | +| `UpdatedAt` | `int64` | Last update timestamp | +| `Tags` | `TArray` | Conversation tags | +| `UnreadMentionsCount` | `int32` | Number of unread mentions | +| `LastReadMessageId` | `int64` | ID of last read message | +| `LatestMessageId` | `int64` | ID of latest message | + +### FCometChatTransientMessage | Property | Type | Description | | -------- | ---- | ----------- | -| `Total` | `int32` | Total messages available | -| `Count` | `int32` | Messages returned in this page | -| `PerPage` | `int32` | Page size requested | -| `CurrentPage` | `int32` | Current page number | -| `TotalPages` | `int32` | Total pages available | -| `HasMore` | `bool` | Whether more pages exist | -| `NextCursor` | `int32` | Message ID for next page (`BeforeMessageId`) | +| `ReceiverId` | `FString` | Receiver UID or GUID | +| `ReceiverType` | `FString` | `user` or `group` | +| `Data` | `FString` | Custom data payload (JSON) | +| `Sender` | `FCometChatUser` | The sender | -### FCometChatPresence +### FCometChatMessageReceipt | Property | Type | Description | | -------- | ---- | ----------- | -| `Uid` | `FString` | User identifier | -| `Status` | `ECometChatPresenceStatus` | `Online`, `Offline`, or `Away` | -| `LastActiveAt` | `int64` | Unix timestamp of last activity | +| `MessageId` | `FString` | The message this receipt is for | +| `Sender` | `FCometChatUser` | User who triggered the receipt | +| `ReceiverType` | `FString` | `user` or `group` | +| `ReceiverId` | `FString` | Receiver UID or GUID | +| `Timestamp` | `int64` | Receipt timestamp | +| `ReceiptType` | `FString` | `delivered` or `read` | +| `DeliveredAt` | `int64` | Delivery timestamp | +| `ReadAt` | `int64` | Read timestamp | -### FCometChatTypingEvent +### FCometChatTypingIndicator | Property | Type | Description | | -------- | ---- | ----------- | -| `Uid` | `FString` | User who is typing | -| `ConversationId` | `FString` | Conversation where typing occurs | -| `bIsTyping` | `bool` | `true` = started, `false` = stopped | +| `ReceiverId` | `FString` | Receiver UID or GUID | +| `ReceiverType` | `FString` | `user` or `group` | +| `Metadata` | `FString` | Optional metadata JSON | +| `Sender` | `FCometChatUser` | The user who is typing | -### FCometChatReceiptEvent +### FCometChatReactionEvent | Property | Type | Description | | -------- | ---- | ----------- | -| `MessageId` | `FString` | The message this receipt is for | -| `Uid` | `FString` | User who triggered the receipt | -| `Status` | `FString` | `delivered` or `read` | -| `Timestamp` | `int64` | Unix timestamp of the receipt | +| `Reaction` | `FString` | The reaction emoji/string | +| `ReceiverId` | `FString` | Receiver UID or GUID | +| `ReceiverType` | `FString` | `user` or `group` | +| `ConversationId` | `FString` | Conversation identifier | +| `ParentMessageId` | `int64` | Parent message ID | +| `Message` | `FCometChatMessage` | The message that was reacted to | + +### FCometChatReactionCount + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Reaction` | `FString` | The reaction emoji/string | +| `Count` | `int32` | Number of times this reaction was used | +| `bReactedByMe` | `bool` | Whether the logged-in user reacted | + +### FCometChatAttachment + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Extension` | `FString` | File extension | +| `MimeType` | `FString` | MIME type | +| `Name` | `FString` | File name | +| `Size` | `int64` | File size in bytes | +| `Url` | `FString` | Download URL | + +### FCometChatAction + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `BaseMessage` | `FCometChatMessage` | Underlying message | +| `Action` | `FString` | Action type | +| `ActionBy` | `FCometChatUser` | User who performed the action | +| `ActionOn` | `FCometChatUser` | User the action was performed on | +| `ActionFor` | `FString` | Target identifier | +| `OldScope` | `FString` | Previous scope (for scope changes) | +| `NewScope` | `FString` | New scope (for scope changes) | + +### FCometChatGroupMember + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `User` | `FCometChatUser` | The member's user profile | +| `Scope` | `FString` | Member scope (`admin`, `moderator`, `participant`) | +| `JoinedAt` | `int64` | When the member joined | + +### FCometChatScopeChangeEvent + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Action` | `FCometChatAction` | The action details | +| `UpdatedBy` | `FCometChatUser` | User who changed the scope | +| `UpdatedUser` | `FCometChatUser` | User whose scope was changed | +| `ScopeChangedTo` | `FString` | New scope value | +| `ScopeChangedFrom` | `FString` | Previous scope value | +| `Group` | `FCometChatGroup` | The group where scope changed | + +### FCometChatInteractionReceipt + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `MessageId` | `FString` | Message ID | +| `Sender` | `FCometChatUser` | User who interacted | +| `ReceiverType` | `FString` | `user` or `group` | +| `ReceiverId` | `FString` | Receiver UID or GUID | +| `ElementId` | `FString` | Interactive element ID | +| `InteractedAt` | `int64` | Interaction timestamp | + +### FCometChatFlagDetail + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `ReasonId` | `FString` | ID of the flag reason | +| `Remark` | `FString` | Optional remark from the reporter | + +### FCometChatFlagReason + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Id` | `FString` | Unique reason identifier | +| `Name` | `FString` | Display name | +| `Description` | `FString` | Detailed description | +| `CreatedAt` | `int64` | Creation timestamp | +| `UpdatedAt` | `int64` | Last update timestamp | + +### FCometChatAIAssistantEvent + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `EventType` | `FString` | Type of AI event | +| `Data` | `FString` | Event data payload | +| `ConversationId` | `FString` | Conversation identifier | +| `SenderUid` | `FString` | Sender UID | + +### FCometChatError + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Code` | `FString` | Error code | +| `Message` | `FString` | Human-readable error message | +| `Details` | `FString` | Additional error details | + +### FCometChatAppSettings + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Region` | `FString` | App region (`us` or `eu`) | +| `SubscriptionType` | `FString` | Subscription type for presence | +| `Roles` | `TArray` | Roles for presence subscription | +| `AdminHost` | `FString` | Custom admin host URL | +| `ClientHost` | `FString` | Custom client host URL | +| `bAutoEstablishSocketConnection` | `bool` | Auto-connect WebSocket on login (default: `true`) | + +### FCometChatPagination + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `Total` | `int32` | Total items available | +| `Count` | `int32` | Items returned in this page | +| `PerPage` | `int32` | Page size requested | +| `CurrentPage` | `int32` | Current page number | +| `TotalPages` | `int32` | Total pages available | +| `HasMore` | `bool` | Whether more pages exist | +| `NextCursor` | `int32` | Cursor for next page | + +--- + +## Request Builder Structs + +### FCometChatUsersRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `30` | Max results per page | +| `SearchKeyword` | `FString` | — | Search by name/UID | +| `SearchIn` | `TArray` | — | Fields to search in | +| `UserStatus` | `FString` | — | Filter by status (`online`, `offline`) | +| `bHideBlockedUsers` | `bool` | `false` | Exclude blocked users | +| `bFriendsOnly` | `bool` | `false` | Only show friends | +| `Roles` | `TArray` | — | Filter by roles | +| `Tags` | `TArray` | — | Filter by tags | +| `bWithTags` | `bool` | `false` | Include tags in response | +| `UIDs` | `TArray` | — | Fetch specific UIDs | +| `SortBy` | `FString` | — | Sort field | +| `SortOrder` | `FString` | — | `asc` or `desc` | +| `Page` | `int32` | `0` | Page number | + +### FCometChatGroupsRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `30` | Max results per page | +| `SearchKeyword` | `FString` | — | Search by group name | +| `bJoinedOnly` | `bool` | `false` | Only groups the user has joined | +| `Tags` | `TArray` | — | Filter by tags | +| `bWithTags` | `bool` | `false` | Include tags in response | +| `Page` | `int32` | `0` | Page number | + +### FCometChatMessagesRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `30` | Max results per page | +| `UID` | `FString` | — | Fetch messages for this user (1:1) | +| `GUID` | `FString` | — | Fetch messages for this group | +| `MessageId` | `int64` | `-1` | Fetch messages before this ID | +| `Timestamp` | `int64` | `-1` | Fetch messages before this timestamp | +| `bUnread` | `bool` | `false` | Only unread messages | +| `bHideMessagesFromBlockedUsers` | `bool` | `false` | Hide blocked user messages | +| `SearchKeyword` | `FString` | — | Search message text | +| `Categories` | `TArray` | — | Filter by categories | +| `Types` | `TArray` | — | Filter by types | +| `ParentMessageId` | `int64` | `-1` | Fetch thread replies | +| `bHideReplies` | `bool` | `false` | Hide thread replies | +| `bHideDeleted` | `bool` | `false` | Hide deleted messages | +| `Tags` | `TArray` | — | Filter by tags | +| `bWithTags` | `bool` | `false` | Include tags in response | + +### FCometChatConversationsRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `30` | Max results per page | +| `ConversationType` | `FString` | — | `user` or `group` | +| `bWithUserAndGroupTags` | `bool` | `false` | Include user/group tags | +| `Tags` | `TArray` | — | Filter by conversation tags | +| `bWithTags` | `bool` | `false` | Include tags in response | +| `UserTags` | `TArray` | — | Filter by user tags | +| `GroupTags` | `TArray` | — | Filter by group tags | +| `bIncludeBlockedUsers` | `bool` | `false` | Include blocked users | +| `SearchKeyword` | `FString` | — | Search conversations | +| `bUnread` | `bool` | `false` | Only unread conversations | +| `Page` | `int32` | `0` | Page number | + +### FCometChatGroupMembersRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `GUID` | `FString` | — | Group to fetch members for | +| `Limit` | `int32` | `30` | Max results per page | +| `SearchKeyword` | `FString` | — | Search by member name | +| `Scopes` | `TArray` | — | Filter by scope | +| `Status` | `FString` | — | Filter by status | +| `Page` | `int32` | `0` | Page number | + +### FCometChatBannedMembersRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `GUID` | `FString` | — | Group to fetch banned members for | +| `Limit` | `int32` | `30` | Max results per page | +| `SearchKeyword` | `FString` | — | Search by name | +| `Scopes` | `TArray` | — | Filter by scope | +| `Page` | `int32` | `0` | Page number | + +### FCometChatBlockedUsersRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `30` | Max results per page | +| `SearchKeyword` | `FString` | — | Search by name | +| `Direction` | `FString` | — | `blockedByMe` or `hasBlockedMe` | +| `Page` | `int32` | `0` | Page number | + +### FCometChatReactionsRequest + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `Limit` | `int32` | `10` | Max results per page | +| `MessageId` | `int64` | `-1` | Message to fetch reactions for | +| `Reaction` | `FString` | — | Filter by specific reaction | --- @@ -152,8 +530,9 @@ All delegates are `UPROPERTY(BlueprintAssignable)` on `UCometChatSubsystem`. The | Value | Description | | ----- | ----------- | | `Connected` | WebSocket is active | +| `Connecting` | SDK is attempting to connect | | `Disconnected` | WebSocket is closed | -| `Reconnecting` | SDK is attempting to reconnect | +| `FeatureThrottled` | A feature is being rate-limited | ### ECometChatPresenceStatus @@ -163,6 +542,15 @@ All delegates are `UPROPERTY(BlueprintAssignable)` on `UCometChatSubsystem`. The | `Offline` | User is not connected | | `Away` | User is connected but idle | +### ECometChatModerationStatus + +| Value | Description | +| ----- | ----------- | +| `Unmoderated` | Message has not been moderated | +| `Pending` | Message is pending moderation review | +| `Approved` | Message has been approved | +| `Disapproved` | Message has been rejected | + --- ## C++ Header Includes @@ -170,11 +558,12 @@ All delegates are `UPROPERTY(BlueprintAssignable)` on `UCometChatSubsystem`. The When working in C++, here are the headers you'll need: ```cpp -// Subsystem (always needed) +// Subsystem (always needed — includes all struct/enum definitions) #include "CometChatSubsystem.h" // Async action nodes (include as needed) #include "AsyncActions/CometChatLoginAction.h" +#include "AsyncActions/CometChatLoginWithAuthTokenAction.h" #include "AsyncActions/CometChatLogoutAction.h" #include "AsyncActions/CometChatSendMessageAction.h" #include "AsyncActions/CometChatSendGroupMessageAction.h" @@ -184,6 +573,15 @@ When working in C++, here are the headers you'll need: #include "AsyncActions/CometChatCreateGroupAction.h" #include "AsyncActions/CometChatJoinGroupAction.h" #include "AsyncActions/CometChatLeaveGroupAction.h" +#include "AsyncActions/CometChatFetchUsersAction.h" +#include "AsyncActions/CometChatFetchGroupsAction.h" +#include "AsyncActions/CometChatFetchConversationsAction.h" +#include "AsyncActions/CometChatFetchMessagesAction.h" +#include "AsyncActions/CometChatConnectAction.h" +#include "AsyncActions/CometChatDisconnectAction.h" +#include "AsyncActions/CometChatPingAction.h" +#include "AsyncActions/CometChatFlagMessageAction.h" +#include "AsyncActions/CometChatGetFlagReasonsAction.h" ``` All types (`FCometChatUser`, `FCometChatMessage`, `FCometChatGroup`, etc.) are defined in `CometChatSubsystem.h`. diff --git a/sdk/unreal/send-message.mdx b/sdk/unreal/send-message.mdx index d8b6c36ee..0ce4bc25e 100644 --- a/sdk/unreal/send-message.mdx +++ b/sdk/unreal/send-message.mdx @@ -30,6 +30,10 @@ Send a text message to a specific user by their UID. + + + + 1. Get a reference to the **CometChat Subsystem** 2. Call the **Send Message Async** node 3. Wire the **On Success** and **On Failure** pins @@ -78,6 +82,10 @@ Send a text message to a group by its GUID. + + + + Call the **Send Group Message Async** node. | Parameter | Type | Description | diff --git a/sdk/unreal/setup.mdx b/sdk/unreal/setup.mdx index bb9e774ec..05b17899f 100644 --- a/sdk/unreal/setup.mdx +++ b/sdk/unreal/setup.mdx @@ -26,8 +26,8 @@ description: "Install the CometChat plugin in your Unreal Engine project." | Engine Version | Platforms | | -------------- | --------- | -| UE 5.5.4 | Mac, Windows | -| UE 5.7.2 | Mac | +| UE 5.5.4 | Mac, Windows, iOS, Android | +| UE 5.7.2+ | Mac, Windows, iOS, Android | --- @@ -146,28 +146,61 @@ The plugin loads at the **PreDefault** phase, so it's available before your game ## Initialize CometChat -The `CometChatSubsystem` is a `UGameInstanceSubsystem` — it's created automatically when your game starts. You just need to call **Configure** with your App ID and Region before using any other SDK methods. +The `CometChatSubsystem` is a `UGameInstanceSubsystem` — it's created automatically when your game starts. You need to call the **Configure Async** node with your App ID and Region before using any other SDK methods. This is a latent async node with **On Success** and **On Failure** pins. -1. In any Blueprint, get a reference to the **CometChat Subsystem** via `Get Game Instance` → `Get Subsystem` → select `CometChatSubsystem` -2. Call the **Configure** node with your **App ID** and **Region** +1. In any Blueprint, search for the **CometChat Configure Async** node +2. Pass your **App ID** and **Region** +3. Wire the **On Success** and **On Failure** pins | Parameter | Type | Description | | --------- | ---- | ----------- | | App Id | `FString` | Your CometChat App ID | | Region | `FString` | Your app region (`us` or `eu`) | + +**On Success** returns an `FCometChatUser`: +- If a saved session was restored, the user details are populated (auto-login) +- If no saved session exists, `Uid` will be empty — you need to call Login next + +**On Failure** returns an `FCometChatError` with error details. ```cpp #include "CometChatSubsystem.h" +#include "AsyncActions/CometChatConfigureAction.h" void AMyActor::BeginPlay() { Super::BeginPlay(); - UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); - Chat->Configure(TEXT("YOUR_APP_ID"), TEXT("us")); + auto* Action = UCometChatConfigureAction::CometChatConfigureAsync( + this, + TEXT("YOUR_APP_ID"), + TEXT("us") + ); + Action->OnSuccess.AddDynamic(this, &AMyActor::OnConfigureSuccess); + Action->OnFailure.AddDynamic(this, &AMyActor::OnConfigureFailed); + Action->Activate(); +} + +void AMyActor::OnConfigureSuccess(const FCometChatUser& LoggedInUser) +{ + if (LoggedInUser.Uid.IsEmpty()) + { + UE_LOG(LogTemp, Log, TEXT("SDK configured — no saved session, need to login")); + // Proceed to Login + } + else + { + UE_LOG(LogTemp, Log, TEXT("SDK configured — session restored for %s"), *LoggedInUser.Name); + // User is already logged in, ready to use SDK + } +} + +void AMyActor::OnConfigureFailed(const FCometChatError& Error) +{ + UE_LOG(LogTemp, Error, TEXT("Configure failed: %s"), *Error.Message); } ``` @@ -177,6 +210,10 @@ void AMyActor::BeginPlay() **Configure must be called before Login.** Calling Login without configuring first will result in a failure callback. + +**Session restoration**: If the user was previously logged in, Configure will automatically restore the session — you don't need to call Login again. Check if the returned `FCometChatUser.Uid` is non-empty to determine if a session was restored. + + Make sure you replace `YOUR_APP_ID` with your actual CometChat **App ID**. --- @@ -186,9 +223,10 @@ Make sure you replace `YOUR_APP_ID` with your actual CometChat **App ID**. The plugin provides: - **`UCometChatSubsystem`** — Game instance subsystem for CometChat operations -- **Async Blueprint actions** — for login, logout, send message, fetch messages, groups -- **`CometChatEventBridge`** — Real-time event callbacks -- **`CometChatGroupChatBox`** — Ready-to-use group chat UI widget +- **Async Blueprint actions** — for login, logout, send/fetch messages, groups, conversations, moderation, and more +- **`CometChatEventBridge`** — Real-time event callbacks (40+ delegates organized by listener type) +- **`UCometChatPanel`** — Ready-to-use tabbed chat panel widget (My Groups, Personal, Browse Groups) +- **`UCometChatButton`** — Floating button widget that toggles the chat panel - **Native C++ chat SDK** via `ThirdParty/chatsdk/` (prebuilt static libraries) --- diff --git a/sdk/unreal/transient-messages.mdx b/sdk/unreal/transient-messages.mdx new file mode 100644 index 000000000..741df8a95 --- /dev/null +++ b/sdk/unreal/transient-messages.mdx @@ -0,0 +1,176 @@ +--- +title: "Transient Messages" +description: "Send ephemeral messages that are delivered in real time but not persisted on the server." +--- + +Transient messages are fire-and-forget messages that are delivered to online recipients in real time but **never stored** on the CometChat server. They're ideal for ephemeral interactions like game state updates, cursor positions, or temporary notifications. + +--- + +## When to Use Transient Messages + +| Use Case | Why Transient? | +| -------- | -------------- | +| Live game state (player position, health) | High frequency, no need to persist | +| Cursor/pointer position in collaborative tools | Ephemeral by nature | +| "User is looking at this" indicators | Temporary UI state | +| Temporary notifications | No history needed | +| Custom signaling between clients | Low-latency, no storage overhead | + + +Transient messages are **not delivered to offline users** and cannot be fetched from message history. If you need message persistence, use regular messages instead. + + +--- + +## Send a Transient Message + +Use `SendTransientMessage` on the Subsystem. This is a fire-and-forget call — there's no success/failure callback. + + + +1. Create an `FCometChatTransientMessage` struct +2. Set `ReceiverId` (user UID or group GUID), `ReceiverType` (`user` or `group`), and `Data` (your custom payload) +3. Call **Send Transient Message** on the CometChat Subsystem + + +```cpp +void AMyActor::SendGameState(const FString& GroupGuid, const FString& StateJson) +{ + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + + FCometChatTransientMessage Message; + Message.ReceiverId = GroupGuid; + Message.ReceiverType = TEXT("group"); + Message.Data = StateJson; // e.g., {"type":"position","x":100,"y":200} + + Chat->SendTransientMessage(Message); +} +``` + + + +--- + +## Receive Transient Messages + +Bind to the `OnTransientMessageReceived` delegate to receive transient messages from other users. + + + +1. Get a reference to the **CometChat Subsystem** +2. Bind to **On Transient Message Received** +3. The custom event receives an `FCometChatTransientMessage` with the sender, receiver info, and data payload + + +```cpp +void AMyActor::BeginPlay() +{ + Super::BeginPlay(); + + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + Chat->OnTransientMessageReceived.AddDynamic(this, &AMyActor::HandleTransientMessage); +} + +void AMyActor::HandleTransientMessage(const FCometChatTransientMessage& Message) +{ + UE_LOG(LogTemp, Log, TEXT("Transient from %s: %s"), + *Message.Sender.Name, *Message.Data); + + // Parse the Data JSON and handle accordingly + // e.g., update another player's cursor position +} +``` + + + +--- + +## FCometChatTransientMessage + +| Property | Type | Description | +| -------- | ---- | ----------- | +| `ReceiverId` | `FString` | Receiver UID (1:1) or GUID (group) | +| `ReceiverType` | `FString` | `"user"` or `"group"` | +| `Data` | `FString` | Custom data payload (typically JSON) | +| `Sender` | `FCometChatUser` | The user who sent the message (populated on receive) | + +--- + +## Message Flow + +```mermaid +sequenceDiagram + participant A as Sender + participant S as CometChat Cloud + participant B as Online Recipient + participant C as Offline User + + A->>S: SendTransientMessage + S->>B: OnTransientMessageReceived + Note over S,C: NOT delivered (offline) + Note over S: NOT stored in history + + style A fill:#333,stroke:#666,color:#fff + style S fill:#555,stroke:#999,color:#ccc + style B fill:#333,stroke:#666,color:#fff + style C fill:#333,stroke:#666,color:#fff +``` + + +**Data format**: The `Data` field is a free-form string. We recommend using JSON so receivers can parse it easily. Define a schema for your transient message types (e.g., `{"type":"cursor","x":100,"y":200}`) so handlers can route by type. + + +--- + +## Example: Player Position Sync + +A common game pattern — broadcast player position to group members at high frequency: + + + +1. On a Timer (e.g., every 0.1s), get the player's world location +2. Serialize to JSON: `{"type":"pos","x":...,"y":...,"z":...}` +3. Call **Send Transient Message** to the game's group GUID +4. On receive, parse the JSON and update the remote player's position + + +```cpp +// Send position every 100ms +void AMyActor::BroadcastPosition() +{ + FVector Pos = GetActorLocation(); + FString Json = FString::Printf( + TEXT("{\"type\":\"pos\",\"x\":%.1f,\"y\":%.1f,\"z\":%.1f}"), + Pos.X, Pos.Y, Pos.Z); + + FCometChatTransientMessage Msg; + Msg.ReceiverId = GameGroupGuid; + Msg.ReceiverType = TEXT("group"); + Msg.Data = Json; + + GetGameInstance()->GetSubsystem()->SendTransientMessage(Msg); +} + +// Receive and apply remote player position +void AMyActor::HandleTransientMessage(const FCometChatTransientMessage& Message) +{ + // Parse JSON, update remote player actor position + // (implementation depends on your game's player management) +} +``` + + + +--- + +## Next Steps + + + + See all real-time delegates including transient messages. + + + Control connection lifecycle for optimal performance. + + diff --git a/sdk/unreal/typing-indicators.mdx b/sdk/unreal/typing-indicators.mdx index 692418233..3e9437ba3 100644 --- a/sdk/unreal/typing-indicators.mdx +++ b/sdk/unreal/typing-indicators.mdx @@ -3,20 +3,64 @@ title: "Typing Indicators" description: "Show real-time typing indicators when users are composing messages." --- -Typing indicators let you show a "user is typing..." animation in your chat UI. The CometChat Unreal SDK delivers these as real-time events through the `OnTypingChanged` delegate. +Typing indicators let you show a "user is typing..." animation in your chat UI. The CometChat Unreal SDK provides two separate delegates — `OnTypingStarted` and `OnTypingEnded` — plus methods to send typing state from the local user. + +--- + +## Send Typing Indicators + +Use `StartTyping` and `EndTyping` on the Subsystem to notify other users that the local user is composing a message. + + + +1. Get a reference to the **CometChat Subsystem** +2. Create an `FCometChatTypingIndicator` struct with the receiver info +3. Call **Start Typing** when the user begins typing +4. Call **End Typing** when the user stops (or after a timeout) + + +```cpp +void AMyActor::NotifyTypingStarted(const FString& ReceiverId, const FString& ReceiverType) +{ + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + + FCometChatTypingIndicator Indicator; + Indicator.ReceiverId = ReceiverId; + Indicator.ReceiverType = ReceiverType; // "user" or "group" + + Chat->StartTyping(Indicator); +} + +void AMyActor::NotifyTypingEnded(const FString& ReceiverId, const FString& ReceiverType) +{ + UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); + + FCometChatTypingIndicator Indicator; + Indicator.ReceiverId = ReceiverId; + Indicator.ReceiverType = ReceiverType; + + Chat->EndTyping(Indicator); +} +``` + + + + +**Auto-end pattern**: Start a 5-second timer when the user begins typing. Reset it on each keystroke. When the timer fires without a reset, call `EndTyping`. This prevents stale typing indicators if the user walks away mid-message. + --- ## Listen for Typing Events -Bind to the `OnTypingChanged` delegate on the Subsystem to receive typing start/stop notifications. +Bind to `OnTypingStarted` and `OnTypingEnded` delegates on the Subsystem to receive typing notifications from other users. 1. Get a reference to the **CometChat Subsystem** -2. Drag off and search for **On Typing Changed** -3. Use **Bind Event** to connect it to a custom event -4. The custom event receives an `FCometChatTypingEvent` parameter +2. Drag off and search for **On Typing Started** / **On Typing Ended** +3. Use **Bind Event** to connect each to a custom event +4. The custom event receives an `FCometChatTypingIndicator` parameter ```cpp @@ -25,21 +69,20 @@ void AMyActor::BeginPlay() Super::BeginPlay(); UCometChatSubsystem* Chat = GetGameInstance()->GetSubsystem(); - Chat->OnTypingChanged.AddDynamic(this, &AMyActor::HandleTyping); + Chat->OnTypingStarted.AddDynamic(this, &AMyActor::HandleTypingStarted); + Chat->OnTypingEnded.AddDynamic(this, &AMyActor::HandleTypingEnded); } -void AMyActor::HandleTyping(const FCometChatTypingEvent& Event) +void AMyActor::HandleTypingStarted(const FCometChatTypingIndicator& Indicator) { - if (Event.bIsTyping) - { - // Show typing indicator for this user/conversation - ShowTypingBubble(Event.Uid, Event.ConversationId); - } - else - { - // Hide typing indicator - HideTypingBubble(Event.Uid, Event.ConversationId); - } + // Show typing indicator for this user in the conversation + ShowTypingBubble(Indicator.Sender.Uid, Indicator.ReceiverId); +} + +void AMyActor::HandleTypingEnded(const FCometChatTypingIndicator& Indicator) +{ + // Hide typing indicator + HideTypingBubble(Indicator.Sender.Uid, Indicator.ReceiverId); } ``` @@ -47,27 +90,50 @@ void AMyActor::HandleTyping(const FCometChatTypingEvent& Event) --- -## FCometChatTypingEvent +## FCometChatTypingIndicator | Property | Type | Description | | -------- | ---- | ----------- | -| `Uid` | `FString` | The user who started or stopped typing | -| `ConversationId` | `FString` | The conversation where typing is happening | -| `bIsTyping` | `bool` | `true` when the user starts typing, `false` when they stop | +| `ReceiverId` | `FString` | The user UID or group GUID where typing is happening | +| `ReceiverType` | `FString` | `"user"` for 1:1 or `"group"` for group conversations | +| `Metadata` | `FString` | Optional metadata JSON string | +| `Sender` | `FCometChatUser` | The user who started or stopped typing | -**UI pattern**: When `bIsTyping` is `true`, show a typing animation (e.g., three bouncing dots). When `false`, hide it. Consider adding a timeout (e.g., 5 seconds) to auto-hide the indicator in case the stop event is missed. +**UI pattern**: When `OnTypingStarted` fires, show a typing animation (e.g., three bouncing dots). When `OnTypingEnded` fires, hide it. Consider adding a local timeout (e.g., 5 seconds) to auto-hide the indicator in case the end event is missed due to network issues. --- +## Event Flow + +```mermaid +sequenceDiagram + participant A as User A (Sender) + participant S as CometChat Cloud + participant B as User B (Receiver) + + A->>S: StartTyping(Indicator) + S->>B: OnTypingStarted fires + Note over B: Show "User A is typing..." + A->>S: EndTyping(Indicator) + S->>B: OnTypingEnded fires + Note over B: Hide typing indicator + + style A fill:#333,stroke:#666,color:#fff + style S fill:#555,stroke:#999,color:#ccc + style B fill:#333,stroke:#666,color:#fff +``` + +--- + ## Next Steps Track when messages are delivered and read. - - Monitor the WebSocket connection state. + + See all 40+ real-time delegates available. diff --git a/sdk/unreal/ui-components.mdx b/sdk/unreal/ui-components.mdx new file mode 100644 index 000000000..c68a88473 --- /dev/null +++ b/sdk/unreal/ui-components.mdx @@ -0,0 +1,211 @@ +--- +title: "UI Components" +description: "Drop-in chat UI widgets: CometChatPanel (tabbed chat) and CometChatButton (floating toggle)." +--- + +The CometChat Unreal SDK includes two ready-to-use UMG widgets that provide a complete chat experience out of the box. Both are fully styleable and configurable via Blueprint properties. + +--- + +## UCometChatPanel + +A game-style tabbed chat panel with a dark translucent HUD aesthetic. It provides: + +- **Three tabs**: My Groups, Personal, Browse Groups +- **Search**: Filter conversations and groups by name +- **Inline chat view**: Select a conversation to open the chat within the panel +- **Typing indicators**: Shows who is typing in the active chat +- **Avatar loading**: Async avatar image loading with fallback initials +- **Message filters**: Configurable filters for message types and categories + +```mermaid +flowchart LR + A["CometChatPanel"] --> B["Tab: My Groups"] + A --> C["Tab: Personal"] + A --> D["Tab: Browse Groups"] + B --> E["Chat View"] + C --> E + D --> E + + style A fill:#444,stroke:#888,color:#fff + style B fill:#333,stroke:#666,color:#fff + style C fill:#333,stroke:#666,color:#fff + style D fill:#333,stroke:#666,color:#fff + style E fill:#333,stroke:#666,color:#fff +``` + +### Adding to Viewport + + + +1. Create a Widget Blueprint with parent class **CometChat Panel** +2. Set the **App Id**, **Region**, **Auth Key**, and **User Uid** properties +3. Add to viewport via **Create Widget** → **Add to Viewport** + +Or use the `UCometChatButton` widget which manages the panel automatically. + + +```cpp +void AMyHUD::BeginPlay() +{ + Super::BeginPlay(); + + UCometChatPanel* Panel = CreateWidget(GetWorld()); + Panel->AppId = TEXT("YOUR_APP_ID"); + Panel->Region = TEXT("us"); + Panel->AuthKey = TEXT("YOUR_AUTH_KEY"); + Panel->UserUid = TEXT("cometchat-uid-1"); + Panel->AddToViewport(); +} +``` + + + +### Configuration Properties + +#### SDK Config + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `AppId` | `FString` | — | Your CometChat App ID | +| `Region` | `FString` | `"us"` | App region (`us` or `eu`) | +| `AuthKey` | `FString` | — | Your CometChat Auth Key | +| `UserUid` | `FString` | — | UID of the user to log in as | + +#### Panel Style + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `PanelWidth` | `float` | `650` | Panel width in pixels | +| `PanelHeight` | `float` | `450` | Panel height in pixels | +| `PanelBackground` | `FLinearColor` | Dark translucent | Background color | +| `AccentColor` | `FLinearColor` | Blue | Primary accent color | +| `TabActiveColor` | `FLinearColor` | Blue | Active tab color | +| `TabInactiveColor` | `FLinearColor` | Dark gray | Inactive tab color | +| `TextColor` | `FLinearColor` | Light gray | Primary text color | +| `SubTextColor` | `FLinearColor` | Medium gray | Secondary text color | +| `FontSize` | `float` | `12` | Base font size | +| `SmallFontSize` | `float` | `10` | Small text font size | +| `CornerRadius` | `float` | `8` | Border corner radius | +| `SidebarWidth` | `float` | `220` | Sidebar/list width | + +#### Message Style + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `ChatMessageFontSize` | `float` | `10` | Message text size | +| `ChatAvatarSize` | `float` | `24` | Avatar image size | +| `ChatUsernameOwnColor` | `FLinearColor` | Blue | Own username color | +| `ChatUsernameOtherColor` | `FLinearColor` | Gold | Other username color | + +#### Message Filters + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `bShowTextMessages` | `bool` | `true` | Show text messages | +| `bShowImageMessages` | `bool` | `true` | Show image messages | +| `bShowVideoMessages` | `bool` | `true` | Show video messages | +| `bShowAudioMessages` | `bool` | `true` | Show audio messages | +| `bShowFileMessages` | `bool` | `true` | Show file messages | +| `bShowCustomMessages` | `bool` | `true` | Show custom messages | +| `bShowActionMessages` | `bool` | `false` | Show action messages (join/leave) | +| `bShowCallMessages` | `bool` | `false` | Show call messages | +| `bHideBlockedUserMessages` | `bool` | `false` | Hide messages from blocked users | +| `bHideDeletedMessages` | `bool` | `true` | Hide deleted messages | +| `bHideReplies` | `bool` | `true` | Hide thread replies from main chat | +| `bOnlyWithAttachments` | `bool` | `false` | Only show messages with attachments | +| `bOnlyWithMentions` | `bool` | `false` | Only show messages with mentions | +| `bOnlyWithReactions` | `bool` | `false` | Only show messages with reactions | +| `bOnlyUnread` | `bool` | `false` | Only show unread messages | + +--- + +## UCometChatButton + +A floating circular button that toggles the `UCometChatPanel` open and closed. Add it to your HUD for a one-click chat experience. + +### Adding to Viewport + + + +1. Create a Widget Blueprint with parent class **CometChat Button** +2. Set the **App Id**, **Region**, **Auth Key**, and **User Uid** properties +3. Add to viewport — the button appears as a floating circle +4. Clicking the button opens/closes the full chat panel + + +```cpp +void AMyHUD::BeginPlay() +{ + Super::BeginPlay(); + + UCometChatButton* ChatButton = CreateWidget(GetWorld()); + ChatButton->AppId = TEXT("YOUR_APP_ID"); + ChatButton->Region = TEXT("us"); + ChatButton->AuthKey = TEXT("YOUR_AUTH_KEY"); + ChatButton->UserUid = TEXT("cometchat-uid-1"); + ChatButton->AddToViewport(); +} +``` + + + +### Configuration Properties + +| Property | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| `AppId` | `FString` | — | Your CometChat App ID | +| `Region` | `FString` | `"us"` | App region | +| `AuthKey` | `FString` | — | Your CometChat Auth Key | +| `UserUid` | `FString` | — | UID of the user to log in as | +| `ButtonSize` | `float` | `56` | Button diameter in pixels | +| `ButtonColor` | `FLinearColor` | Blue | Button background color | +| `ButtonHoverColor` | `FLinearColor` | Light blue | Button hover color | +| `IconColor` | `FLinearColor` | White | Icon/text color | +| `IconFontSize` | `float` | `20` | Icon font size | + +### Blueprint Methods + +| Method | Returns | Description | +| ------ | ------- | ----------- | +| `ToggleChatPanel()` | `void` | Open or close the chat panel programmatically | +| `IsPanelOpen()` | `bool` | Check if the panel is currently visible | + +--- + +## Usage Pattern + +The typical setup is to add `UCometChatButton` to your HUD. It handles creating and managing the `UCometChatPanel` internally: + +```mermaid +flowchart TD + A["Add CometChatButton to Viewport"] --> B["User clicks button"] + B --> C["Panel opens (auto-login + fetch data)"] + C --> D["User chats"] + D --> E["User clicks button again"] + E --> F["Panel closes"] + + style A fill:#333,stroke:#666,color:#fff + style B fill:#444,stroke:#888,color:#fff + style C fill:#333,stroke:#666,color:#fff + style D fill:#333,stroke:#666,color:#fff + style E fill:#444,stroke:#888,color:#fff + style F fill:#333,stroke:#666,color:#fff +``` + + +The panel handles SDK initialization, login, and data fetching automatically when opened. You only need to provide the configuration properties. + + +--- + +## Next Steps + + + + Install the plugin and configure your project. + + + Fine-tune SDK settings and connection management. + + diff --git a/sdk/unreal/users.mdx b/sdk/unreal/users.mdx index 17b4d7031..d8a73e874 100644 --- a/sdk/unreal/users.mdx +++ b/sdk/unreal/users.mdx @@ -9,6 +9,10 @@ Retrieve a user's profile by their UID. + + + + Call the **Get User Async** node. | Parameter | Type | Description |