On this page

Create custom events

Learn how Chat SDK handles events before creating your own custom chat events.

Event handling

PubNub events

With a standard PubNub SDK like the Swift SDK, building a chat app requires additional steps:

  • Subscribe to channels to receive messages
  • Add event listeners to handle messages, signals, and events

Chat SDK handles this automatically. All listener methods return a function to stop receiving events and unsubscribe from the channel.

EntityMethodEvents handled
Channel
onUpdated() / onDeleted()
Subscribe to objects events of type channel — notified on channel metadata changes or deletion.
User
onUpdated() / onDeleted()
Subscribe to objects events of type uuid — notified on user metadata changes or deletion.
Message
onUpdated()
Subscribe to messageAction events — notified on message edits, deletions, and reaction changes.
Membership
onUpdated() / onDeleted()
Subscribe to objects events of type membership — notified on membership metadata changes or deletion.
Channel
onMessageReceived()
Subscribe to message events — notified on new messages published to the channel.
Channel
onTypingChanged()
Subscribe to signal events of type Typing — notified when users start or stop typing.
Channel
onPresenceChanged()
Subscribe to presence events — notified when users join, leave, or time out from a channel.
Channel
onReadReceiptReceived()
Subscribe to read receipt signals — notified when users mark messages as read.
Channel
onMessageReported()
Subscribe to report events — notified when messages are flagged.
User
onInvited()
Subscribe to invite events — notified when the user is invited to a channel.
User
onMentioned()
Subscribe to mention events — notified when the user is mentioned in a message.
User
onRestrictionChanged()
Subscribe to moderation events — notified when user restrictions change.

Chat SDK wraps server responses into entities like Channel, Message, and User with methods and properties for building your app's UI.

Chat events

Chat SDK automatically emits these event types and delivers them via entity-level listener methods. Each event type uses the PubNub Pub/Sub API internally — either publish() (with history) or signal() (no history).

Historical events

Use getEventsHistory() to fetch past events. Results cannot be filtered by type — all events emitted via publish() on the channel are returned.

Report events

Emitted when a user reports a message. Published to PUBNUB_INTERNAL_MODERATION_{channel_id}.

1public struct Report {
2 public let reason: String
3 public let text: String?
4 public let messageTimetoken: Timetoken?
5 public let reportedMessageChannelId: String?
6 public let reportedUserId: String?
7 public let autoModerationId: String?
8}

Typing events

Emitted when a user starts or stops typing. Delivered via signal (no history).

The callback receives [String] — the array of user IDs currently typing.

Mention events

Emitted when a user is mentioned in a message. Delivered to the mentioned user's personal channel (channel ID equals the user ID).

  • Trigger: channel.sendText() with usersToMention
  • Listener: user.onMentioned(callback:)
  • History: chat.getEventsHistory(channelId: userId)
1public struct Mention {
2 public let messageTimetoken: Timetoken
3 public let channelId: String
4 public let parentChannelId: String?
5 public let mentionedByUserId: String
6}

Read receipt events

Emitted when a user marks messages as read. Delivered via signal on the channel.

1public struct ReadReceipt {
2 public let userId: String
3 public let lastReadTimetoken: Timetoken
4}

Invite events

Emitted when a user is invited to a channel. Delivered to the invited user's personal channel.

1public struct Invite {
2 public let channelId: String
3 public let channelType: ChannelType
4 public let invitedByUserId: String
5 public let invitationTimetoken: Timetoken
6}

Restriction events

Emitted when an admin changes a user's mute or ban status on a channel.

1public struct Restriction {
2 public let userId: String
3 public let channelId: String
4 public let ban: Bool
5 public let mute: Bool
6 public let reason: String?
7}

Custom events

The custom event type carries custom payloads for additional business logic. Methods:

  • channel.emitCustomEvent() — create and send custom events
  • channel.onCustomEvent() — listen for incoming channel-scoped custom events
  • chat.getEventsHistory() — retrieve historical events

Create and send events

channel.emitCustomEvent()

emitCustomEvent() sends a custom event directly on a Channel object. This is the preferred method for channel-scoped custom events.

Method signature

This method takes the following parameters:

1channel.emitCustomEvent(
2 payload: [String: JSONCodable],
3 messageType: String? = nil,
4 storeInHistory: Bool = true
5) async throws -> Timetoken
Input
* required
ParameterDescription
payload *
Type: [String: JSONCodable]
Default:
n/a
Arbitrary key-value payload to publish with the event.
messageType
Type: String?
Default:
nil
Optional custom message type used for filtering events.
storeInHistory
Type: Bool
Default:
true
If true, the event is stored in Message Persistence (if enabled in Admin Portal).
Output
ParameterDescription
Timetoken
The timetoken of the emitted event.
Sample code

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.

1

Receive current events

channel.onCustomEvent()

onCustomEvent() listens for custom events published on a specific channel, replacing the deprecated listenForEvents() for channel-scoped custom events.

Method signature

This method takes the following parameters:

1channel.onCustomEvent(
2 messageType: String? = nil,
3 callback: @escaping (CustomEvent) -> Void
4) -> AutoCloseable

The CustomEvent struct contains:

1public struct CustomEvent {
2 public let timetoken: Timetoken
3 public let userId: String
4 public let type: String?
5 public let payload: [String: JSONCodable]
6}
Input
* required
ParameterDescription
messageType
Type: String?
Default:
nil
Optional custom message type filter. If nil, all custom event types are accepted.
callback *
Type: (CustomEvent) -> Void
Default:
n/a
A closure invoked for each matching custom event received on the channel.
Output
ParameterDescription
AutoCloseable
An object you must retain. When released or closed, the listener stops. Call close() to stop receiving events.
Sample code

Monitor the CUSTOMER-SATISFACTION-CREW channel for frustrated customer events. When such an event occurs, the handleFrustratedEvent function responds to the customer.

1

Get historical events

getEventsHistory() retrieves historical events from a channel, similar to getHistory() for messages. Results cannot be filtered by type and include all events emitted via publish() in the specified timeframe.

Method signature

This method takes the following parameters:

1chat.getEventsHistory(
2 channelId: String,
3 startTimetoken: Timetoken? = nil,
4 endTimetoken: Timetoken? = nil,
5 count: Int = 100
6) async throws -> (events: [EventWrapper<EventContent>], isMore: Bool)

Input

* required
ParameterDescription
channelId *
Type: String
Default:
n/a
Channel from which you want to pull historical messages.
startTimetoken
Type: Timetoken
Default:
n/a
Timetoken delimiting the start of a time slice (exclusive) to pull events from. For details, refer to the Fetch History section.
endTimetoken
Type: Timetoken
Default:
n/a
Timetoken delimiting the end of a time slice (inclusive) to pull events from. For details, refer to the Fetch History section.
count
Type: Int
Default:
100
Number of historical events to return for the channel in a single call. You can pull a maximum number of 100 events in a single call.

Output

ParameterDescription
(events: [EventWrapper<EventContent>], isMore: Bool)
Type: object
Returned object containing two fields: events and isMore.
 → events
Type: Set<Event<EventContent>>
Array listing the requested number of historical events objects.
 → isMore
Type: Bool
Info whether there are more historical events to pull.

Sample code

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

1