---
source_url: https://www.pubnub.com/docs/presence/receive-presence-events
title: Receive presence events
updated_at: 2026-09-30T07:20:08.000Z
---

# Receive presence events

> For AI agents: documentation index at https://www.pubnub.com/llms-full.txt

This guide shows you how to subscribe to a [channel](https://www.pubnub.com/docs/architecture/core-concepts.md#channel) with presence events enabled and register a listener that receives them. Presence must be enabled on the keyset, and new keysets have it enabled by default. Once it's running, your application learns about arrivals, departures, and state changes as they happen, instead of polling [Here Now](https://www.pubnub.com/docs/presence/get-online-users-in-channel.md) on a timer.

When [Access Manager](https://www.pubnub.com/docs/security/access-control/overview.md) is enabled, receiving presence events requires `read` permission on the channel, which also grants access to its `-pnpres` companion channel.

## Enable presence events on a subscription

Create a subscription with the presence option turned on (named `receivePresenceEvents` in most SDKs), register a handler for it, then subscribe. PubNub delivers presence events through the same [event listener](https://www.pubnub.com/docs/pub-sub/subscribe/event-listeners.md) you already use for messages and signals, with a dedicated presence handler.

### JavaScript

```javascript
const channel = pubnub.channel('chats.room1');
const subscription = channel.subscription({ receivePresenceEvents: true });

subscription.onPresence = (event) => {
  console.log('Presence event:', event.action, event.uuid);
};

subscription.subscribe();
```

### Python

```python
subscription = pubnub.channel('chats.room1').subscription(with_presence=True)

subscription.on_presence = lambda event: print('Presence event:', event.event, event.uuid)

subscription.subscribe()
```

### Java

```java
Channel channel = pubnub.channel("chats.room1");
Subscription subscription = channel.subscription(SubscriptionOptions.receivePresenceEvents());

subscription.setOnPresence(result ->
        System.out.println("Presence event: " + result.getEvent() + " " + result.getUuid()));

subscription.subscribe();
```

### Kotlin

```kotlin
val subscription = pubnub.channel("chats.room1").subscription(SubscriptionOptions.receivePresenceEvents())

subscription.onPresence = { presence -> println("Presence event: ${presence.event} ${presence.uuid}") }

subscription.subscribe()
```

### C#

```csharp
Subscription subscription = pubnub.Channel("chats.room1").Subscription(SubscriptionOptions.ReceivePresenceEvents);

subscription.onPresence += (Pubnub pn, PNPresenceEventResult e) =>
    Console.WriteLine("Presence event: " + e.Event + " " + e.Uuid);

subscription.Subscribe<object>();
```

### Go

```go
listener := pubnub.NewListener()

go func() {
	for presence := range listener.Presence {
		fmt.Println("Presence event:", presence.Event, presence.UUID)
	}
}()

pn.AddListener(listener)
pn.Subscribe().Channels([]string{"chats.room1"}).WithPresence(true).Execute()
```

### Swift

```swift
let subscription = pubnub.channel("chats.room1").subscription(options: ReceivePresenceEvents())

subscription.onPresence = { presenceChange in
    print("Presence event: \(presenceChange)")
}

subscription.subscribe()
```

Most other SDKs document the same option and handler in the Publish/Subscribe section of their API reference, for example [PHP](https://www.pubnub.com/docs/sdks/php/api-reference/publish-and-subscribe.md) or [Ruby](https://www.pubnub.com/docs/sdks/ruby/api-reference/publish-and-subscribe.md). The option name and the handler's field names both vary by SDK. Confirm both in your platform's reference before assuming the names above apply.

## Tell events apart by action

Every presence event carries an `action` (or `event`) field naming which of the five subtypes fired: `join`, `leave`, `timeout`, `state-change`, or `interval`. Branch your handler on it instead of treating every presence event the same way:

```javascript
subscription.onPresence = (event) => {
  switch (event.action) {
    case 'join':
      console.log(`${event.uuid} joined, occupancy ${event.occupancy}`);
      break;
    case 'leave':
    case 'timeout':
      console.log(`${event.uuid} left, occupancy ${event.occupancy}`);
      break;
    case 'state-change':
      console.log(`${event.uuid} changed state:`, event.data);
      break;
    case 'interval':
      console.log(`Occupancy is now ${event.occupancy}`);
      break;
  }
};
```

`leave` and `timeout` both mean the client is gone. The difference is whether it unsubscribed deliberately or stopped responding. Refer to [Presence events](https://www.pubnub.com/docs/presence/presence-events.md) for what triggers each subtype, the full payload each one carries, and how a busy channel's `interval` mode changes which of them arrive.

## If no events arrive

* **Check Presence Management.** If your keyset tracks selected channels only, the channel needs a rule that covers it and the event types you expect. Refer to [Presence Management](https://www.pubnub.com/docs/presence/overview.md).
* **Check the permission on the -pnpres channel.** Confirm the client's token includes the required channel permission. A missing grant blocks the presence subscription the same way it blocks the channel's own messages, and surfaces as an access-denied status on your [status listener](https://www.pubnub.com/docs/architecture/connection-management/monitor-and-respond-to-connection-status-changes.md).
* **Confirm the option is actually set.** A subscription created without `receivePresenceEvents` (or your SDK's equivalent) receives messages normally and no presence events at all, with no error to flag the difference.

## Related tasks

* [Presence events](https://www.pubnub.com/docs/presence/presence-events.md). Event subtypes, payloads, announce and interval modes, and heartbeat configuration.
* [Get online users in a channel](https://www.pubnub.com/docs/presence/get-online-users-in-channel.md). Seed a roster with `Here Now` before switching to events to keep it current.
* [Set and get presence state](https://www.pubnub.com/docs/presence/set-and-get-presence-state.md). Attach the state that triggers a `state-change` event.
* [Event listeners](https://www.pubnub.com/docs/pub-sub/subscribe/event-listeners.md). The listener model this handler follows, and how its lifecycle differs from the subscription's.
* [Presence](https://www.pubnub.com/docs/presence/overview.md). How presence data is enabled and delivered.

Last updated at: 2026-09-30T07:20:08.000Z
