Create custom events

Before creating your own custom chat events, learn how Unreal Chat SDK handles PubNub and chat-specific events.

Event handling

PubNub events

If you were to use a standard PubNub SDK to build a chat app, you would have to perform additional steps as part of your PubNub initialization:

  • Explicitly subscribe to the chosen channel(s) to receive messages.
  • Add event listeners for your app to receive and handle all messages, signals, and events sent to the channel(s) you are subscribed to.

Luckily, the Unreal Chat SDK does this work automatically for you as part of other methods you will run on various entities to build and work with your chat app.

All these methods also return a function you can invoke to stop receiving events of a given type and unsubscribe from the channel. Follow the links to method descriptions for details and examples.

EntityMethodEvents handled
ChannelStreamUpdates() or StreamUpdatesOn()(Un)Subscribe the current user to/from a channel and start/stop getting all objects events of type channel.
UserStreamUpdates() or StreamUpdatesOn()(Un)Subscribe the current user to/from a channel and start/stop getting all objects events of type uuid.
MessageStreamUpdates() or StreamUpdatesOn()(Un)Subscribe the current user to/from a channel and start/stop getting all messageAction events (for message and message reactions changes) of type added or removed.
MembershipStreamUpdates() or StreamUpdatesOn()(Un)Subscribe the current user to/from a channel and start/stop getting all objects events of type membership.
ChannelConnect()(Un)Subscribe the current user to/from a channel and start/stop getting all message events of type text.
ChannelGetTyping()(Un)Subscribe the current user to/from a channel and start/stop getting all signal events of type typing.
ChannelStreamPresence()(Un)Subscribe the current user to/from a channel and start/stop getting all presence events of type action (responsible for monitoring when users join, leave the channels, or when their channel connection times out and they get disconnected).

Unreal Chat SDK wraps all events returned as HTTP responses from the server into meaningful and handy entities, like Channel, Message, User. These objects contain methods you can invoke to build your chat app and parameters you can display on your app's UI.

Chat events

Events, just like messages, are separate entities in the Unreal Chat SDK that carry data as a payload. Contrary to messages, however, events are not merely data transmitters but can trigger additional business logic. For example, in the Unreal Chat SDK, the Typing Indicator feature relies on events - based on whether a user is typing or not, the typing indicator starts or stops.

Unreal Chat SDK handles a few intrinsic types of such events that get emitted automatically when a user:

  • Reports a message (report event type for messages)
  • Starts/Stops typing a message on a channel (typing event type)
  • Mentions someone else in the message (mention event type)
  • Reads a message published on a channel (receipt event type)
  • Invites another user to join a channel (invite event type)
  • Mutes a user, bans them, or removes these restrictions (moderation event type)

All event types use underneath the core PubNub Pub/Sub API and use either the Publish() or Signal() methods.

Different Unreal Chat SDK methods emit (handle) different chat event types. For example, the SendText() method called on the Channel object emits mention events because the IDs of the mentioned users are always passed as part of published messages.

To listen to those events, Unreal Chat SDK uses two methods:

  • ListenForEvents() for the current events that are emitted with the Signal() or Publish() method.
  • GetEventsHistory() to get historical events that were emitted with the Publish() method.
Events history limitations

The GetEventsHistory() method uses PubNub Message Persistence API which has limitations - you cannot filter the results by type. Calling this method would return all event types that happened on a given channel in a given timeframe as long as they were emitted with the Publish() method that stores history. Check custom events for an example showing this method.

The payload structure of the chat events is fixed and depends on the event type.

Read the subsections to get a better overview of each event type - check how they work and get some ideas on using them in your chat app to trigger additional business logic.

Events for reported messages

  • Type: report
  • PubNub method: PubNub method used to send events you listen for. Publish() (with history) is used for all events related to message reporting.
  • Target: PUBNUB_INTERNAL_ADMIN_CHANNEL
  • Trigger: Report() method on the Message object
  • Listener: ListenForEvents() (current) or GetEventsHistory() (historical) on the Chat object
  • Sample use case: Message moderation. You might want to create a UI for an operational dashboard to monitor and manage all reported messages.
  • Payload:
payload: {
// content of the flagged message
text: string;
// reason for flagging the message
reason: string;
// channel where message was flagged
reportedMessageChannelId: string;
// timetoken of the flagged message
reportedMessageTimetoken: string;
// author of the flagged message
reportedUserId: string;
}

Events for typing indicator

  • Type: typing
  • PubNub method: PubNub method used to send events you listen for. Signal() (without history) is used for all events related to typing.
  • Target: The same channel where messages are published.
  • Trigger: StartTyping() and StopTyping() methods on the Channel object
  • Listener: GetTyping() on the Channel object
  • Sample use case: Typing indicator. You might want to show graphically on the channel that another channel member is typing or has stopped typing a message.
  • Payload:
payload: {
// value showing whether someone is typing or not
value: boolean;
}

Events for mentions

  • Type: mention
  • PubNub method: PubNub method used to send events you listen for. Publish() (with history) is used for all events related to mentions.
  • Target: Unlike in other event types, a target for mention events is equal to a user ID. This ID is treated as a user-specific channel and is used to send system notifications about changes concerning a User object, such as creating, updating, or deleting that user. The channel name is equal to the ID (id) of the user and you can retrieve it by calling the currentUser method on the Chat object.
  • Trigger: SendText() method on the Channel object
  • Listener: ListenForEvents() (current) or GetEventsHistory() (historical) on the Chat object
  • Sample use case: User mentions. You might want to receive notifications for all events emitted when you are mentioned in a parent or thread channel.
  • Payload:
payload: {
// timetoken of the message where someone is mentioned
messageTimetoken: string;
// channel on which the message with mention was sent
channel: string;
}

Events for read receipts

  • Type: receipt
  • PubNub method: PubNub method used to send events you listen for. Signal() (with history persisted as the last read message on the Membership object) is used for all events related to message read receipts.
  • Target: The same channel where messages are published.
  • Trigger: MarkAllMessagesAsRead() method on the Chat object, the SetLastReadMessageTimetoken() method on the Membership object, and the SetLastReadMessage() method on the Membership object
  • Listener: StreamReadReceipts() (current) on the Chat object
  • Sample use case: Read receipts. You might want to indicate on a channel - through avatars or some other indicator - that a message was read by another user/other users.
  • Payload:
payload: {
// timetoken of the read message
messageTimetoken: string;
}

Events for channel initations

  • Type: invite
  • PubNub method: PubNub method used to send events you listen for. Publish() (with history) is used for all events related to channel invitations.
  • Target: The same channel where messages are published.
  • Trigger: Invite() and inviteMultiple methods on the Channel object
  • Listener: ListenForEvents() (current) or GetEventsHistory() (historical) on the Chat object
  • Sample use case: Channel invitations. You might want to notify users that they were invited to join a channel.
  • Payload:
payload: {
// type of a channel to which a user was invited (direct or group)
channelType: this.type || "unknown",
// ID of the channel to which a user was invited
channelId: this.id,
}

Events for user moderation

  • Type: moderation
  • PubNub method: PubNub method used to send events you listen for. Publish() (with history) is used for all events related to user restrictions.
  • Target: The same channel where messages are published.
  • Trigger: SetRestrictions() methods on the Channel, Chat, and User objects
  • Listener: ListenForEvents() (current) or GetEventsHistory() (historical) on the Chat object
  • Sample use case: User moderation. You might want to notify users when they were muted, banned, or when you remove these restrictions from them.
  • Payload:
payload: {
// ID of the channel on which the user's moderation restrictions were set or lifted
channelId: string
// type of restriction: whether a user was muted, banned, or at least one of these restrictions was removed
restriction: "muted" | "banned" | "lifted"
// reason for muting or banning the user
reason?: string
}

Custom events

Unreal Chat SDK provides an additional type of events called custom. As the type name suggests, they are meant to let you carry your custom payloads and use them to perform additional business logic in your chat app.

With Unreal Chat SDK, you can:

  • Trigger such custom events using the EmitEvent() method.
  • Listen to them with the ListenForEvents() method.
  • Get all historical events using the GetEventsHistory() method.

Create and send events

EmitEvent() handles (constructs and sends) events with your custom payload.

In its logic, you can compare this method to the SendText() method used for sending new messages.

Method signature

This method takes the following parameters:

Output

This method doesn't return any value.

Basic usage

You want to monitor a high-priority channel with a keyword spotter that identifies dissatisfaction words like "annoyed," "frustrated," or "angry." Suppose a message sent by any of the customers present on this channel contains any of these words. In that case, you want to resend it (with relevant metadata) to a separate technical channel (CUSTOMER-SATISFACTION-CREW) that's monitored by the team responsible for customer satisfaction.

#include "Kismet/GameplayStatics.h"
#include "PubnubChatSubsystem.h"
#include "JsonObjectConverter.h" // Assumed include for JSON conversion utilities.

UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(this);
UPubnubChatSubsystem* PubnubChatSubsystem = GameInstance->GetSubsystem<UPubnubChatSubsystem>();

// Initialize the chat.
UPubnubChat* Chat = PubnubChatSubsystem->InitChat("demo", "demo", "my_user");
UPubnubChannel* Channel = Chat->GetChannel("support");

// Prepare the JSON payload.
TSharedPtr<FJsonObject> JsonPayload = MakeShareable(new FJsonObject);
JsonPayload->SetStringField("chatID", "chat1234");
JsonPayload->SetStringField("timestamp", "2022-04-30T10:30:00Z");
show all 28 lines

Receive current events

ListenForEvents() lets you watch a selected channel for any new custom events emitted by your chat app. You can decide what to do with the incoming custom events and handle them using the callback function.

In its logic, you can compare this method to the Connect() method used for receiving new messages.

Method signature

icon

Handle the response

Output

This method doesn't return any value.

Basic usage

Monitor a channel for frustrated customer events. When such an event occurs, the handleFrustratedEvent function responds with a message acknowledging the customer's frustration and offering assistance.

#include "Kismet/GameplayStatics.h"
#include "PubnubChatSubsystem.h"

UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(this);
UPubnubChatSubsystem* PubnubChatSubsystem = GameInstance->GetSubsystem<UPubnubChatSubsystem>();

UPubnubChat* Chat = PubnubChatSubsystem ->InitChat("demo", "demo", "my_user");

// Create a pubnub response delegate
// you MUST implement your own callback function to handle the response
FOnPubnubEventReceived EventCallback;
EventCallback.BindDynamic(this, &AMyActor::OnMPubnubEventResponseReceived);

Chat->ListenForEvents(
FString("CUSTOMER-SATISFACTION-CREW"),
show all 18 lines
AMyActor.cpp
void AMyActor::OnPubnubEventResponseReceived(const FString& ChannelID, const FString& Payload)
{
// Parse the JSON payload
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Payload);

if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
{
FString TriggerWord;
if (JsonObject->TryGetStringField("triggerWord", TriggerWord))
{
if (TriggerWord.Equals("frustrated", ESearchCase::IgnoreCase))
{
UE_LOG(LogTemp, Log, "Frustrated customer event detected!");
// Handle the frustrated customer event
show all 25 lines

Get historical events

GetEventsHistory() lets you get historical events from a selected channel.

In its logic, you can compare this method to the GetHistory() method used for receiving historical messages. Similarly to this method, you cannot filter the results by type, so you'll get all events emitted with the Publish() method that happened on a given channel in a given timeframe (not only custom events).

Method signature

Output

ParameterTypeDescription
FPubnubEventsHistoryWrapperstructReturned object containing two fields: events and isMore.
 → EventsTArray<FPubnubEvent>Array listing the requested number of historical events objects.
 → IsMoreboolInfo whether there are more historical events to pull.
FPubnubEvent
ParameterTypeDescription
TimetokenFStringTimetoken of the event.
ChannelIDFStringChannel the event occured on.
User IDFStringUser ID associated with the event.
PayloadFStringEvent payload.
TypeEPubnubChatEventTypeType of the event.
EPubnubChatEventType

ValueDescription
PCET_TYPINGIndicates a user is typing a message. Displayed as Typing.
PCET_REPORTRepresents an event where a message has been flagged or reported for offensive content. Displayed as Report.
PCET_RECEIPTConfirms receipt of a message or event. Displayed as Receipt.
PCET_MENTIONIndicates that a user has been mentioned in a message. Displayed as Mention.
PCET_INVITERepresents an invitation event typically sent to a specific user. Displayed as Invite.
PCET_CUSTOMCustom event type for specialized behavior or use cases. Displayed as Custom.
PCET_MODERATIONRepresents an event related to content moderation actions. Displayed as Moderation.

Basic usage

Fetch the last 10 historical events from the CUSTOMER-SATISFACTION-CREW channel.

#include "Kismet/GameplayStatics.h"
#include "PubnubChatSubsystem.h"

UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(this);
UPubnubChatSubsystem* PubnubChatSubsystem = GameInstance->GetSubsystem<UPubnubChatSubsystem>();

UPubnubChat* Chat = PubnubChatSubsystem ->InitChat("demo", "demo", "my_user");

FPubnubEventsHistoryWrapper EventsHistory = Chat->GetEventsHistory("CUSTOMER-SATISFACTION-CREW", "", "", 10);
Last updated on