B24Frame) — it relies on the parent-window auth, channels, and member_id. It is not functional through B24Hook or B24OAuth on the server.Overview
Pull lets the front-end of your application receive events the back-end (or another front-end instance) emits via the pull.application.event.add REST method. The SDK ships a complete client (B24PullClientManager) with two connectors:
- WebSocket primary (
ConnectionType.WebSocket) - Long-polling fallback (
ConnectionType.LongPolling) - Protobuf-encoded message envelopes (decoders bundled, no extra dependency)
You normally drive Pull through useB24Helper — usePullClient / useSubscribePullClient / startPullClient are thin wrappers over the matching B24HelperManager methods.
Quick Start
import {
initializeB24Frame,
useB24Helper,
Text,
LoggerFactory,
type B24Frame,
type TypePullMessage
} from '@bitrix24/b24jssdk'
const $logger = LoggerFactory.createForBrowser('MyApp', import.meta.env?.DEV === true)
const {
initB24Helper,
getB24Helper,
usePullClient,
useSubscribePullClient,
startPullClient,
destroyB24Helper
} = useB24Helper()
let $b24: B24Frame
async function init() {
$b24 = await initializeB24Frame()
await initB24Helper($b24)
// 1. Spin up the underlying B24PullClientManager (one per helper instance)
usePullClient()
// 2. Subscribe — can be called multiple times for multiple moduleIds
useSubscribePullClient((message: TypePullMessage) => {
$logger.info(`${Text.getDateForLog()} << pull`, { message })
}, 'main')
// 3. Connect (WebSocket → long-polling fallback)
startPullClient()
}
async function emitPing(): Promise<void> {
await $b24.actions.v2.call.make({
method: 'pull.application.event.add',
params: {
COMMAND: 'ping',
PARAMS: { tick: Text.getDateForLog() },
MODULE_ID: getB24Helper().getModuleIdPullClient()
}
})
}
await init()
setInterval(emitPing, 5000)
When the host component unmounts, call destroyB24Helper() — that fully tears the Pull client down: closes the WebSocket, clears all subscriptions, removes its window listeners, and cancels all pending timers.
API via B24HelperManager
These four methods are the public Pull surface. See B24HelperManager.
usePullClient(prefix?: string, userId?: number): B24HelperManager
subscribePullClient(callback: (message: TypePullMessage) => void, moduleId?: string): B24HelperManager
startPullClient(): void
getModuleIdPullClient(): string
usePullClientconstructsB24PullClientManageronce.prefixis forwarded tob24.auth.getUniq(prefix)to deriverestApplication.userIddefaults to the loaded profile id.subscribePullClientreturns the helper for chaining; the unsubscribe handle is tracked internally and released ondestroy().startPullClienttriggersPullClient.start()and logs the failure (without throwing) if the connection cannot be established.getModuleIdPullClientreturns themoduleIdlast passed tosubscribePullClient. Use it as theMODULE_IDparameter ofpull.application.event.add.
API via B24PullClientManager Directly
If you need finer control, instantiate the client yourself:
// @check-ignore: partial snippet — B24PullClientManager SubscriptionType not exported publicly
import { B24PullClientManager } from '@bitrix24/b24jssdk'
const pull = new B24PullClientManager({
b24: $b24,
restApplication: $b24.auth.getUniq('myApp'),
userId: 1
})
const unsubscribe = pull.subscribe({
type: 'server', // 'server' | 'client' | 'online'
moduleId: 'main',
command: 'optionsChanged',
callback: (params) => console.log(params)
})
await pull.start()
// Later
unsubscribe()
pull.destroy()
subscribe() accepts either a full TypeSubscriptionOptions object (filter by type / moduleId / command) or a bare TypeSubscriptionCommandHandler function (catches any incoming command). It returns an unsubscribe callback.
Connection Types
The client picks the connector automatically:
- WebSocket — preferred when the portal exposes one.
- Long-polling — used when WebSocket is unavailable, blocked, or when the connection drops repeatedly.
ConnectionType (Undefined / WebSocket / LongPolling) and PullStatus (Online / Offline / Connecting) are exported from the package — useful if you want to reflect the connection in your UI.
Sending Messages
The Pull client only receives messages. To send, call pull.application.event.add over REST:
// @check-ignore: partial snippet — getB24Helper() not in scope
await $b24.actions.v2.call.make({
method: 'pull.application.event.add',
params: {
COMMAND: 'optionsChanged',
PARAMS: { theme: 'dark' },
MODULE_ID: getB24Helper().getModuleIdPullClient()
}
})
Subscribers attached via useSubscribePullClient(cb, 'main') will receive the matching TypePullMessage.