Stream Chat Unreal SDK
Loading...
Searching...
No Matches
ChatChannel.h
1// Copyright 2026 Stream.IO, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "ChannelProperties.h"
6#include "ChannelSortOption.h"
7#include "ChannelState.h"
8#include "ChatApi.h"
9#include "ChatSocketEvents.h"
10#include "CoreMinimal.h"
11#include "Engine/EngineTypes.h"
12#include "Engine/LatentActionManager.h"
13#include "Filter.h"
14#include "IChatSocket.h"
15#include "Message.h"
16#include "MessagePaginationOptions.h"
17#include "PaginationOptions.h"
18#include "Templates/IsInvocable.h"
19#include "User/UserPaginationOptions.h"
20#include "User/UserRef.h"
21
22#include "ChatChannel.generated.h"
23
25struct FChannelEvent;
29struct FMessageEvent;
30struct FMessageNewEvent;
39struct FTypingStopEvent;
40struct FUserBannedEvent;
42
43UENUM(BlueprintType)
44enum class ETypingIndicatorState : uint8
45{
46 StartTyping,
47 StopTyping
48};
49
50UENUM(BlueprintType, meta = (BitFlags))
51enum class EPaginationDirection : uint8
52{
53 None UMETA(Hidden),
54
56 Top = 1 << 0,
58 Bottom = 1 << 1,
59};
60ENUM_CLASS_FLAGS(EPaginationDirection);
61
62UENUM(BlueprintType)
63enum class EHttpRequestState : uint8
64{
65 Started,
66 Ended
67};
68
73UCLASS(BlueprintType)
74class STREAMCHAT_API UChatChannel final : public UObject
75{
76 GENERATED_BODY()
77
78public:
80 static UChatChannel* Create(UObject* Outer, const TSharedRef<FChatApi>, const TSharedRef<IChatSocket>, const FChannelStateResponseFieldsDto&);
82 static UChatChannel* Create(UObject* Outer, const TSharedRef<FChatApi>, const TSharedRef<IChatSocket>);
83
85 bool IsValid() const;
86
91 void Delete(TFunction<void()> Callback = {}) const;
92
99 void PartialUpdate(const TSharedRef<FJsonObject>& Set = {}, const TArray<FString>& Unset = {}, TFunction<void()> Callback = {});
100
107 void Update(const FAdditionalFields& Data, const TOptional<FMessage>& Message = {}, TFunction<void()> Callback = {});
108
117 void Truncate(
118 bool bHardDelete = false,
119 const TOptional<FDateTime>& TruncatedAt = {},
120 const TOptional<FMessage>& Message = {},
121 bool bSkipPush = false,
122 TFunction<void()> Callback = {});
123
133 void QueryMembers(
134 const FFilter& Filter = {},
135 const TArray<FUserSortOption>& Sort = {},
136 const FMessagePaginationOptions& Pagination = {},
137 TFunction<void(const TArray<FMember>&)> Callback = {});
138
145 void AddMembers(const TArray<FString>& MemberIds, const TOptional<FMessage>& Message = {}, TFunction<void()> Callback = {});
146
153 void RemoveMembers(const TArray<FString>& MemberIds, const TOptional<FMessage>& Message = {}, TFunction<void()> Callback = {});
154
161 void Hide(bool bClearHistory = false, TFunction<void()> Callback = {}) const;
162
167 void Show(TFunction<void()> Callback = {}) const;
168
173 void StopWatching(TFunction<void()> Callback = {}) const;
174
176 UPROPERTY(BlueprintReadOnly, Category = "Stream Chat|Channel")
178
180 UPROPERTY(BlueprintReadOnly, Category = "Stream Chat|Channel")
182
183private:
184 void MergeState(const FChannelStateResponseFieldsDto&);
185
186 TSharedPtr<FChatApi> Api;
187 TSharedPtr<IChatSocket> Socket;
188
189#pragma region Event
195public:
197 template <class TEvent>
198 void SendEvent(const TEvent&);
199
201 template <class TEvent>
202 FDelegateHandle On(TEventDelegate<TEvent> Callback);
203
211 template <class TEvent, class UserClass>
212 typename TEnableIf<TIsDerivedFrom<UserClass, UObject>::IsDerived, FDelegateHandle>::Type On(
213 UserClass* Obj,
214 TEventDelegateUObjectMethodPtr<TEvent, UserClass> Method);
215
224 template <class TEvent, class UserClass>
225 typename TEnableIf<!TIsDerivedFrom<UserClass, UObject>::IsDerived, FDelegateHandle>::Type On(
226 UserClass* Obj,
227 TEventDelegateSpMethodPtr<TEvent, UserClass> Method);
228
236 template <class TEvent, typename FunctorType, typename... VarTypes>
237 typename TEnableIf<TIsInvocable<FunctorType, const TEvent&, VarTypes...>::Value, FDelegateHandle>::Type On(FunctorType&& Functor, VarTypes... Vars);
238
245 template <class TEvent>
246 bool Unsubscribe(FDelegateHandle) const;
247
249#pragma endregion Event
250
251#pragma region Message
257public:
263 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Message", DisplayName = "Send Message", meta = (Latent, WorldContext = WorldContextObject, LatentInfo = LatentInfo))
264 void SendMessageBP(const FMessage& Message, const UObject* WorldContextObject, FLatentActionInfo LatentInfo, bool& bSuccess);
265 void SendMessage(const FMessage& Message, const TFunction<void(const bool& bSuccess)> = {});
266
271 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Message", DisplayName = "Get Message", meta = (Latent, WorldContext = WorldContextObject, LatentInfo = LatentInfo))
272 void GetMessageBP(const FString& MessageId, const UObject* WorldContextObject, FLatentActionInfo LatentInfo, FMessage& OutMessage);
273 void GetMessage(const FString& MessageId, const TFunction<void(const FMessage&)> Callback = {});
274
280 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Message")
281 void UpdateMessage(const FMessage& Message);
282
288 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Message")
289 void DeleteMessage(const FMessage& Message);
290
299 void QueryAdditionalMessages(EPaginationDirection Direction = EPaginationDirection::Top, int32 Limit = 20, TFunction<void()> Callback = {});
300
305 void MarkRead(const TOptional<FMessage>& Message = {});
310 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Message", meta = (AutoCreateRefTerm = Message))
311 void MarkRead(const FMessage& Message);
312
314 void MarkReadLocal();
315
325 void Query(
327 const TOptional<FMessagePaginationOptions> MessagePagination = {},
328 const TOptional<FUserPaginationOptions> MemberPagination = {},
329 const TOptional<FUserPaginationOptions> WatcherPagination = {},
330 TFunction<void()> Callback = {});
331
343 void SearchMessages(
344 const TOptional<FString>& Query = {},
345 const TOptional<FFilter>& MessageFilter = {},
346 const TArray<FMessageSortOption>& Sort = {},
347 TOptional<uint32> MessageLimit = {},
348 TFunction<void(const TArray<FMessage>&)> Callback = {}) const;
349
361 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel", meta = (Latent, WorldContext = WorldContextObject, LatentInfo = LatentInfo, AutoCreateRefTerm = "Sort,MessageFilter"))
362 void SearchMessages(
363 const FString& Query,
364 const FFilter& MessageFilter,
365 const TArray<FMessageSortOption>& Sort,
366 int32 MessageLimit,
367 const UObject* WorldContextObject,
368 FLatentActionInfo LatentInfo,
369 TArray<FMessage>& OutMessages);
370
371 DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMessagesUpdatedDelegate);
373 UPROPERTY(BlueprintAssignable, Category = "Stream Chat|Channel")
374 FMessagesUpdatedDelegate MessagesUpdated;
375
376 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMessageDelegate, const FMessage&, Messages);
378 UPROPERTY(BlueprintAssignable, Category = "Stream Chat|Channel")
379 FMessageDelegate MessageSent;
380
382 UPROPERTY(BlueprintAssignable, Category = "Stream Chat|Channel")
383 FMessageDelegate MessageReceived;
384
385 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FUnreadChangedDelegate, int32, UnreadCount);
387 UPROPERTY(BlueprintAssignable, Category = "Stream Chat|Channel")
388 FUnreadChangedDelegate UnreadChanged;
389
390private:
391 void AddMessage(const FMessage&);
392 void MarkRead(const TOptional<FString>& MessageId);
393
394 void OnMessageUpdated(const FMessageUpdatedEvent&);
395 void OnMessageDeleted(const FMessageDeletedEvent&);
396
397 void OnMessageNew(const FMessageNewEvent&);
398 void OnNotificationMessageNew(const FNotificationMessageNewEvent&);
399 void HandleNewMessageEvent(const FMessageEvent&);
400
401 void OnMessageRead(const FMessageReadEvent&);
402 void OnNotificationMessageRead(const FNotificationMarkReadEvent&);
403 void UpdateUnread(const FUserRef& User, int32 UnreadCount, const FDateTime& LastRead);
404
406#pragma endregion Message
407
408#pragma region Reaction
414public:
423 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Reaction")
424 FReaction SendReaction(const FMessage& Message, const FName& ReactionType, int32 Score = 1, bool bEnforceUnique = false);
425
433 void GetReactions(const FMessage& Message, const FPaginationOptions& Pagination = {}, TFunction<void(const TArray<FReaction>&)> Callback = {});
434
441 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Reaction")
442 void DeleteReaction(const FMessage& Message, const FReaction& Reaction);
443
444private:
445 void OnReactionNew(const FReactionNewEvent&);
446 void OnReactionUpdated(const FReactionUpdatedEvent&);
447 void OnReactionDeleted(const FReactionDeletedEvent&);
448
450#pragma endregion Reaction
451
452#pragma region Typing
457public:
462 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Typing", meta = (AdvancedDisplay = ParentMessageId))
463 void KeyStroke(const FString& ParentMessageId = TEXT(""));
464
470 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Typing", meta = (AdvancedDisplay = ParentMessageId))
471 void StopTyping(const FString& ParentMessageId = TEXT(""));
472
473 DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FTypingIndicatorDelegate, ETypingIndicatorState, TypingState, const FUserRef&, User);
475 UPROPERTY(BlueprintAssignable)
476 FTypingIndicatorDelegate OnTypingIndicator;
477
478private:
479 void SendStopTypingEvent(const FString& ParentMessageId = TEXT(""));
480 void OnTypingStart(const FTypingStartEvent&);
481 void OnTypingStop(const FTypingStopEvent&);
482
483 float TypingTimeout = 2.f;
484 TOptional<FDateTime> LastKeystrokeAt;
485 FTimerHandle TypingTimerHandle;
486
488#pragma endregion Typing
489
490#pragma region Moderation
495public:
505 UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Stream Chat|Channel|Moderation", DisplayName = "Ban Member")
506 void BanMemberBP(const FUserRef& User, FTimespan Timeout, FString Reason, bool bIpBan) const;
507 void BanMember(const FUserRef& User, const TOptional<FTimespan>& Timeout = {}, const TOptional<FString>& Reason = {}, bool bIpBan = false) const;
508
513 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Moderation")
514 void UnbanMember(const FUserRef& User) const;
515
523 UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Stream Chat|Channel|Moderation", DisplayName = "Shadow Ban Member")
524 void ShadowBanMemberBP(const FUserRef& User, FTimespan Timeout) const;
525 void ShadowBanMember(const FUserRef& User, const TOptional<FTimespan>& Timeout = {}) const;
526
531 UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Stream Chat|Channel|Moderation")
532 void ShadowUnbanMember(const FUserRef& User) const;
533
538 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Moderation", DisplayName = "Mute")
539 void MuteBP(FTimespan Timeout);
540 void Mute(const TOptional<FTimespan>& Timeout = {});
541
545 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Moderation")
546 void Unmute() const;
547
551 UFUNCTION(BlueprintPure, Category = "Stream Chat|Channel|Moderation")
552 bool IsMuted() const;
553
557 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Moderation")
558 void EnableSlowMode(FTimespan Cooldown);
559
563 UFUNCTION(BlueprintCallable, Category = "Stream Chat|Channel|Moderation")
564 void DisableSlowMode();
565
566private:
567 void OnUserBanned(const FUserBannedEvent&);
568 void OnUserUnbanned(const FUserUnbannedEvent&);
569
571#pragma endregion Moderation
572};
573
574template <class TEvent>
575void UChatChannel::SendEvent(const TEvent& Event)
576{
577 Api->SendChannelEvent(Properties.Type, Properties.Id, Event);
578}
579
580template <class TEvent>
581FDelegateHandle UChatChannel::On(TEventDelegate<TEvent> Callback)
582{
583 return Socket->Events().SubscribeLambda<TEvent>(
584 [this, Callback](const TEvent& Event)
585 {
586 // TODO static assert with nice error message
587 // https://stackoverflow.com/questions/1005476/how-to-detect-whether-there-is-a-specific-member-variable-in-class
588 if (Event.Cid == Properties.Cid)
589 {
590 Callback.ExecuteIfBound(Event);
591 }
592 });
593}
594
595template <class TEvent, class UserClass>
596typename TEnableIf<TIsDerivedFrom<UserClass, UObject>::IsDerived, FDelegateHandle>::Type UChatChannel::On(
597 UserClass* Obj,
598 TEventDelegateUObjectMethodPtr<TEvent, UserClass> Method)
599{
600 const TEventDelegate<TEvent> Delegate = TEventDelegate<TEvent>::CreateUObject(Obj, Method);
601 return On<TEvent>(Delegate);
602}
603
604template <class TEvent, class UserClass>
605typename TEnableIf<!TIsDerivedFrom<UserClass, UObject>::IsDerived, FDelegateHandle>::Type UChatChannel::On(
606 UserClass* Obj,
607 TEventDelegateSpMethodPtr<TEvent, UserClass> Method)
608{
609 const TEventDelegate<TEvent> Delegate = TEventDelegate<TEvent>::CreateSP(Obj, Method);
610 return On<TEvent>(Delegate);
611}
612
613template <class TEvent, typename FunctorType, typename... VarTypes>
614typename TEnableIf<TIsInvocable<FunctorType, const TEvent&, VarTypes...>::Value, FDelegateHandle>::Type UChatChannel::On(
615 FunctorType&& Functor,
616 VarTypes... Vars)
617{
618 const TEventDelegate<TEvent> Delegate = TEventDelegate<TEvent>::CreateLambda(Forward<FunctorType>(Functor), Vars...);
619 return On<TEvent>(Delegate);
620}
621
622template <class TEvent>
623bool UChatChannel::Unsubscribe(const FDelegateHandle Handle) const
624{
625 return Socket->Events().Unsubscribe<TEvent>(Handle);
626}
All Stream Chat REST API requests can be made via this object.
Definition ChatApi.h:63
Interface to a Stream Chat WebSocket connection.
Definition IChatSocket.h:17
The client-side representation of a Stream Chat channel.
Definition ChatChannel.h:75
FChannelProperties Properties
The local static properties of the channel.
Definition ChatChannel.h:177
TEnableIf<!TIsDerivedFrom< UserClass, UObject >::IsDerived, FDelegateHandle >::Type On(UserClass *Obj, TEventDelegateSpMethodPtr< TEvent, UserClass > Method)
Subscribe to a channel event using a shared pointer-based (fast, not thread-safe) member function del...
FDelegateHandle On(TEventDelegate< TEvent > Callback)
Subscribe to a channel event using your own delegate object.
Definition ChatChannel.h:581
bool Unsubscribe(FDelegateHandle) const
Unsubscribe from a previously subscribed channel event.
Definition ChatChannel.h:623
void SendEvent(const TEvent &)
Send a custom event on this channel.
Definition ChatChannel.h:575
A component which allows for connecting to the Stream Chat API. Should be added to a client-side acto...
Definition StreamChatClientComponent.h:43
EChannelFlags
Additional channel actions to perform when requesting channel data from API.
Definition ChannelFlags.h:15
@ State
Return channel state in response.
@ None
Do nothing.
@ Type
Type of the message.
@ Query
Matches values by performing text search with the specified value.
Represents an event that happened in a Stream channel.
Definition ChannelEvent.h:17
Encapsulates the static properties of a channel.
Definition ChannelProperties.h:21
FString Id
Definition ChannelProperties.h:69
FString Cid
The cid of this channel.
Definition ChannelProperties.h:73
FString Type
Definition ChannelProperties.h:64
Encapsulates the local state of a channel.
Definition ChannelState.h:20
#/components/schemas/ChannelStateResponse
Definition ChannelStateResponseDto.h:16
#/components/schemas/ChannelStateResponseFields
Definition ChannelStateResponseFieldsDto.h:19
A filter used for querying channels.
Definition Filter.h:75
A message was deleted.
Definition MessageDeletedEvent.h:17
A WebSocket event related to a message.
Definition MessageEvent.h:17
Represents a Stream Chat message.
Definition Message.h:66
A new message was created.
Definition MessageNewEvent.h:17
Options for pagination of messages.
Definition MessagePaginationOptions.h:17
A new message was created.
Definition MessageReadEvent.h:18
The desired sort options for message queries.
Definition ChannelSortOption.h:100
A message's content was updated.
Definition MessageUpdatedEvent.h:17
Notification when a message or entire channel was marked as read.
Definition NotificationMarkReadEvent.h:19
Notification when a new message was created.
Definition NotificationMessageNewEvent.h:17
Options for pagination.
Definition PaginationOptions.h:15
A reaction was deleted.
Definition ReactionDeletedEvent.h:17
An individual reaction to a message.
Definition Reaction.h:18
A new reaction was created.
Definition ReactionNewEvent.h:17
A reaction was updated.
Definition ReactionUpdatedEvent.h:17
A user started typing.
Definition TypingStartEvent.h:18
A user stoped typing.
Definition TypingStopEvent.h:18
#/components/schemas/UserBannedEvent
Definition UserBannedEvent.h:18
A reference to a unique User.
Definition UserRef.h:23
#/components/schemas/UserUnbannedEvent
Definition UserUnbannedEvent.h:18