@wildix/xbees-connect
v1.3.19
Published
This library provides easy communication between x-bees and integrated web applications
Maintainers
Keywords
Readme
x-bees-connect client
This package is the Community plan edition of the client for UI integration applications.
Installation
Install the package in your project directory with:
pnpm add @wildix/xbees-connectnpm install @wildix/xbees-connectWork Variants
The integration can be launched in different modes via the v URL parameter:
ui- Standard UI mode (default)no-ui/daemon- Data-only mode, no UI shownd/dialog- Dialog/setup modef- Fullsize mode, integration takes full viewport dimensions
You can check the current mode using:
const client = Client.getInstance();
client.showsUi(); // Returns true for UI modes (ui, d, f)
client.isDataOnly(); // Returns true for no-ui / daemon mode
client.isSetupDialog(); // Returns true for dialog mode (d / dialog)
client.isFullsize(); // Returns true for fullsize mode (f)Usage
import Client from "@wildix/xbees-connect";
const xBeesClient = Client.getInstance();
console.log(xBeesClient.version());API
Class helpers
Client.getInstance(): ConnectClient
Returns the singleton Client instance. Prefer this over new Client() to avoid duplicate message listeners.
const client = Client.getInstance();Client.initialize(renderer: () => Promise<void>): void
Calls renderer only when the integration runs in a UI mode (showsUi() === true). Use this as the entry point to conditionally boot your React/Vue tree.
Client.initialize(async () => {
ReactDOM.render(<App />, document.getElementById('root'));
});Initialization
ready(props?: SupportedPlatformVariant | ReadyExtendedProps): Promise<ResponseMessage>
Sends the signal to x-bees that the iFrame is ready to be shown. Call this once when the application starts and is fully initialised. Accepts an optional platform variant string or an extended props object (e.g. templateId, analyticTitle).
isAuthorized(): Promise<ResponseMessage>
Sends the message to x-bees that the user is authorized and no more actions are required.
isNotAuthorized(): Promise<ResponseMessage>
Sends the message to x-bees that the user is not authorized and interaction is required.
Identity and user data
version(): string
Returns the version string of the xbees-connect package.
getUserEmail(): string
Returns the email of the currently authenticated x-bees user, taken from URL parameters at construction time.
getUserPbxToken(): string
Returns the current PBX token. The token is updated automatically whenever the PBX_TOKEN event fires. The initial value is an empty string until the first token event is received.
getPbxDomain(): string
Returns the current PBX domain. Populated after user data is fetched from x-bees.
getUserExtension(): string | null
Returns the PBX extension of the current user, or null if not available.
getXBeesUser(): XBeesUser | null
Returns a cached XBeesUser object ({ id, email, extension, domain, name }) or null if the data has not been fetched yet. Triggers a background fetch on first call.
Deprecated behaviour: this method does not wait for the fetch to complete. If you need the user data before rendering, use
getXBeesUserAsync()instead.
getXBeesUserAsync(): Promise<XBeesUser | null>
Asynchronous version of getXBeesUser. Waits for the user data to be fetched from x-bees before returning. Prefer this over the synchronous variant when the user object is required immediately.
const user = await client.getXBeesUserAsync();
if (user) {
console.log(user.name, user.email);
}getReferrer(): string
Returns the URL of the x-bees app that opened this integration, taken from URL parameters at construction time.
getBackToAppUrl(): string
Returns the deep-link URL that navigates the user back to this integration inside the x-bees app. The format differs between native and web platforms.
getStartPage(): StartPage | null
Returns the StartPage enum value parsed from the URL, or null if not present.
getProduct(): Product | null
Returns the Product enum value indicating from which x-bees product the integration was opened (e.g. contacts, conversations), or null if not specified.
Environment and platform
isPlatformNative(): boolean
Returns true when x-bees is running inside a React Native WebView.
isPlatformWeb(): boolean
Returns true when x-bees is running in a web browser (iFrame).
isOpenedFromXBees(): boolean
Returns true when the integration is running inside an x-bees iFrame or a React Native WebView. Returns false in standalone/dev mode; all send* calls will be no-ops in that case.
isVisible(): boolean
Returns true when the UI iFrame is currently active (visible to the user). Updated automatically via the VISIBILITY event.
UI state and launch mode
showsUi(): boolean
Returns true for all modes that render UI (ui, d, f). Opposite of isDataOnly().
isDataOnly(): boolean
Returns true when the integration is launched in no-ui or daemon mode (no UI rendered).
isSetupDialog(): boolean
Returns true when the integration is launched in dialog/setup mode (d or dialog).
isFullsize(): boolean
Returns true when the integration is launched in fullsize mode (f).
isActivationOnly(): boolean
Returns true when the integration is opened for activation/authorization purposes only (URL contains the authorize parameter).
isCloudBackendEnabled(): boolean
Returns true when cloud backend is enabled for this integration. Reads the cbi URL parameter at construction time (cbi=1 → true, cbi=0 or missing → false).
Context
getContext(): Promise<ResponseMessage>
Retrieves the current x-bees context data. The shape of the payload depends on the active context (e.g. contact view, conversation view).
getCurrentContact(): Promise<ResponseMessage>
Retrieves the contact data currently open in x-bees.
getCurrentConversation(): Promise<ResponseMessage>
Retrieves the conversation data ({ id, type }) currently open in x-bees. Resolves with undefined payload if the conversation is temporary.
getAvailableContactData(): Promise<ResponseMessage>
Retrieves contact data that x-bees has available for the current context (phone numbers, emails, etc.). Useful to pre-populate integration forms.
Theme
getThemeMode(): Promise<ResponseMessage>
Retrieves the current theme mode ('light' or 'dark').
getTheme(): Promise<ResponseMessage>
Retrieves the full theme object including mode and theme options (typography, palette).
onThemeChange(callback: (theme: IPayloadThemeChange) => void): RemoveEventListener
Starts listening for theme-change events. Invokes callback whenever the user changes the x-bees theme. Returns an unsubscribe function.
Token
getXBeesToken(): Promise<ResponseMessage>
Requests the current x-bees authentication token from x-bees. Use this when you need the token for API calls to x-bees services.
onPbxTokenChange(callback: (token: string) => void): RemoveEventListener
Starts listening for PBX token change events. Invokes callback with the new token value. Returns an unsubscribe function.
Calls
startCall(phoneNumber: string): Promise<ResponseMessage>
Sends a request to x-bees to initiate a call to the given phone number.
onCallStarted(callback: (info: IPayloadCallStartedInfo) => void): RemoveEventListener
Starts listening for the event fired when a call starts. Returns an unsubscribe function.
onCallEnded(callback: () => void): RemoveEventListener
Starts listening for the event fired when a call ends. Returns an unsubscribe function.
onDaemonCallStarted(callback: (info: IPayloadDaemonCallStarted) => void): RemoveEventListener
Starts listening for daemon-specific call start events. This event is independent from onCallStarted and carries daemon payload.
onDaemonCallFinished(callback: (info: IPayloadDaemonCallFinished) => void): RemoveEventListener
Starts listening for daemon-specific call finish events. This event is independent from onCallEnded and carries daemon payload.
Contacts
contactUpdated(query: ContactQuery, contact: Contact): Promise<ResponseMessage>
Notifies x-bees that a contact was created or updated. query identifies the contact ({ id?, email?, phone? }); contact contains the updated data.
contactMatchUpdated(query: ContactQuery, contact: Contact): Promise<ResponseMessage>
Notifies x-bees that a contact match was updated. Used when the integration resolves a contact lookup initiated by x-bees.
onSuggestContacts(callback: (query: string, resolve: SuggestContactsResolver, reject: Reject) => void): RemoveEventListener
Starts listening for contact auto-suggest requests from x-bees. When the user types in a contact search field, x-bees calls callback with the search string. Call resolve(contacts) to return results.
Client.getInstance().onSuggestContacts(async (query, resolve) => {
try {
const contacts = await fetchContacts(query);
resolve(contacts);
} catch (error) {
console.log('catch', error);
}
});onLookupAndMatchContact(callback: (query: ContactQuery, resolve: LookupAndMatchContactsResolver, reject: Reject) => void): RemoveEventListener
Starts listening for single-contact lookup requests. x-bees supplies a ContactQuery and expects a single matched Contact via resolve.
Client.getInstance().onLookupAndMatchContact(async (query, resolve) => {
try {
const contact = await fetchContactAndMatch(query);
resolve(contact);
} catch (error) {
console.log('catch', error);
}
});onLookupAndMatchBatchContacts(callback: (queries: ContactQuery[], returnResults: LookupAndMatchBatchContactsResolver) => void): RemoveEventListener
Starts listening for batch contact lookup requests. x-bees sends an array of ContactQuery objects. Call returnResults with a Map<ContactQuery, Contact | null | undefined> mapping each query to its result.
Client.getInstance().onLookupAndMatchBatchContacts(async (queries, returnResults) => {
const resultsMap = new Map<ContactQuery, Contact | null>();
for (const query of queries) {
resultsMap.set(query, await fetchContact(query));
}
returnResults(resultsMap);
});onIntegrationProxyRequest(callback: (request, resolve, reject) => void): RemoveEventListener
Registers a handler for read-only Salesforce REST proxy requests from x-bees. Subscribe during app startup (same pattern as contact flows). On registration, x-bees is notified that the integration supports this flow (INTEGRATION_PROXY_REQUEST_IS_SUPPORTED).
- Request (
IntegrationProxyRequest):path(relative Salesforce URL only), optionalquery, optionalrequestId. - Resolve (
IntegrationProxyRequestResolver): passIntegrationProxyResponsewithok,path, optionalrequestId/data/error, and requiredmeta: { source: 'salesforce', validated, validationWarnings? }. Structured domain errors useerror.code(e.g.NOT_AUTHORIZED,INVALID_PATH,PATH_NOT_ALLOWED,MISSING_QUERY_PARAM,INVALID_QUERY_PARAM,EXECUTION_FAILED). - If
response.error?.code === 'NOT_AUTHORIZED', the client callsisNotAuthorized()before sending the proxy response to x-bees. - Reject (
Reject): use only for unexpected runtime exceptions (string reason).
Scope (first iteration): read-only calls only. Use relative paths such as /services/data/v59.0/sobjects/Contact/003... or /services/data/v59.0/query with query: { q: 'SELECT ...' }. No composite, tooling, OAuth, create, update, or delete.
Client.getInstance().onIntegrationProxyRequest(async (request, resolve, reject) => {
try {
const response = await handleIntegrationProxyRequest(request);
resolve(response);
} catch (error) {
reject(String(error));
}
});createContactIsSupported(): Promise<ResponseMessage>
Sends a signal to x-bees indicating that this integration supports creating contacts. Call once during initialization if your integration handles contact creation.
createContactHasNoPermission(): Promise<ResponseMessage>
Sends a signal to x-bees indicating that the current user does not have permission to create contacts.
Navigation
onRedirectQuery(callback: Callback<EventType.REDIRECT_QUERY>): RemoveEventListener
Starts listening for redirect query events. Fires when the user opens the app via a deep-link that targets this integration. Returns an unsubscribe function.
onStartRedirectToEntityPage(callback: Callback<EventType.START_REDIRECT_TO_ENTITY_PAGE>): RemoveEventListener
Deprecated. Use addEventListener(EventType.START_REDIRECT_TO_ENTITY_PAGE, callback) instead.
Starts listening for the event that signals x-bees is navigating to an entity page (e.g. conversation). The payload contains { conversationId, pageName }. Returns an unsubscribe function.
onCancelRedirectToEntityPage(callback: Callback<EventType.CANCEL_REDIRECT_TO_ENTITY_PAGE>): RemoveEventListener
Deprecated. Use addEventListener(EventType.CANCEL_REDIRECT_TO_ENTITY_PAGE, callback) instead.
Starts listening for the event that signals a pending redirect to an entity page was cancelled. The payload contains { conversationId }. Returns an unsubscribe function.
Visibility and lifecycle
onVisibilityChange(callback: (isVisible: boolean) => void): RemoveEventListener
Starts listening for iframe visibility changes. callback receives true when the iFrame becomes active and false when it is hidden. Returns an unsubscribe function.
reboot(): Promise<ResponseMessage>
Sends a request to x-bees to restart the iFrame and reload it with the latest parameters and token.
onLogout(callback: Callback<EventType.LOGOUT>): RemoveEventListener
Starts listening for the logout event. Notifies x-bees that the integration supports logout. callback is invoked when x-bees requests a logout action.
Contact events
onContactWeightUpdate(callback: Callback<EventType.CONTACT_WEIGHT_UPDATE>): RemoveEventListener
Starts listening for contact weight update events. Fires when x-bees recalculates the relevance weight of a contact. The payload contains { id, query }. Returns an unsubscribe function.
onContactRefresh(callback: Callback<EventType.CONTACT_REFRESH>): RemoveEventListener
Starts listening for contact refresh events. Fires when a contact was updated in the x-bees daemon and the open integration should re-fetch its data. Returns an unsubscribe function.
UI utilities
showToast(message: string, severity?: ToastSeverity): Promise<ResponseMessage>
Displays a toast notification inside the x-bees UI. severity defaults to 'INFO'. Accepted values: 'INFO', 'WARNING', 'ERROR', 'SUCCESS', 'NOTICE'.
client.showToast('Contact saved', 'SUCCESS');setViewport(payload: { height: number | string; width: number | string }): Promise<ResponseMessage>
Sends a request to x-bees to resize the iFrame to the specified dimensions.
toClipboard(payload: string): Promise<ResponseMessage>
Sends a request to x-bees to write the given string to the user's clipboard.
Event listeners (generic)
addEventListener<T extends EventType>(eventName: T, callback: Callback<T>): RemoveEventListener
Starts listening for any x-bees event by name. Returns an unsubscribe function. Prefer the typed convenience methods (onThemeChange, onCallStarted, etc.) when available.
removeEventListener<T extends EventType>(eventName: T, callback: Callback<T>): void
Stops listening for the specified event with the given callback reference.
off(callback: Callback | StorageEventCallback): void
Removes the given callback from all event listeners, including local storage listeners registered via onStorage.
Analytics
sendAnalytics(eventName: string, params?: Record<string, string>): void
Sends an analytics event to x-bees for tracking. params is an optional map of string key-value pairs.
client.sendAnalytics('contact_viewed', { contactId: '123' });Local storage
These methods read and write to the browser's localStorage, namespaced per integration.
saveToStorage<T>(key: string, value: T): void
Saves a value to localStorage under the given key. The value is serialized to JSON automatically.
getFromStorage<T>(key: string): T | null
Retrieves and deserializes a value from localStorage. Returns null if the key does not exist.
deleteFromStorage(key: string): void
Removes the entry with the given key from localStorage.
setIntegrationStorageKey(integrationKey: string): void
Switches the localStorage namespace to the specified parent integration key. Use this when the integration inherits storage from a parent integration.
onStorage(listener: StorageEventCallback): () => void
Registers a listener for localStorage change events (native StorageEvent). Returns an unsubscribe function.
const unsubscribe = client.onStorage((event) => {
console.log('Storage changed:', event.key, event.newValue);
});x-bees storage
These methods persist data in x-bees' own server-side storage, not in the browser's localStorage. Data stored here survives browser clears and is available across devices.
saveInXbeesStorage<T>(key: string, value: T): void
Saves a value to the x-bees storage. The value is serialized to a JSON string before sending.
getFromXbeesStorage(key: string): Promise<ResponseMessage>
Requests a stored value from x-bees storage by key. Resolves with a ResponseMessage whose payload contains the stored value.
removeFromXbeesStorage(key: string): void
Removes the entry with the given key from x-bees storage.
Custom events
sendCustomEvent({ type: string, payload?: JSONValue }): void
Sends a custom event to x-bees with an arbitrary type string and optional JSON-serializable payload. Use this for integration-specific communication not covered by the built-in event types.
client.sendCustomEvent({ type: 'my_action', payload: { foo: 'bar' } });sendDropdownVisibilityEvent(dropdownVisibilityStatus: boolean): void
Legacy: prefer
sendCustomEventfor new integrations.
Notifies x-bees when a dropdown inside the integration opens or closes, which allows x-bees to enable nested scrolling on Android WebView.
Chat connections
setChatToOpen(chatId: string): void
Tells x-bees which chat or conversation should be opened (brought into focus). The integration sends ClientEventType.SET_CHAT_TO_OPEN (xBeesSetChatToOpen) with payload { chatId }. The call returns immediately; x-bees applies the navigation when it handles the message.
client.setChatToOpen('chat_id');getChannelsByEmailOrPhone(payload: IPayloadGetChannelsByEmailOrPhone): Promise<ResponseMessage>
Asks x-bees to look up chat channels for an email address or phone number. The integration sends ClientEventType.GET_CHANNELS_BY_EMAIL_OR_PHONE (xBeesGetChannelsByEmailOrPhone) with payload { value, type }, where type is 'email' or 'phone'. Resolves with a ResponseMessage whose payload contains the matching channels returned by x-bees.
const { payload } = await client.getChannelsByEmailOrPhone({ value: '[email protected]', type: 'email' });Route synchronization
sendRouteChange(route: string, options?: { replace?: boolean }): void
Sends a local route change to the connected parent or iframe. Pass the route as a full app-relative string, including path, search, and hash when needed, for example /contacts/123?tab=info#notes.
Pass { replace: true } to ask the host to update the current browser history entry instead of pushing a new one. Omit replace (or set it to false) to keep the default push behavior. Use replace for load-time sync and intermediate/tab transitions that should not appear in back/forward history.
client.sendRouteChange('/contacts/123');
client.sendRouteChange('/contacts/123?tab=info', {replace: true});onExternalRouteChange(callback: Callback<EventType.EXTERNAL_ROUTE_CHANGE>): RemoveEventListener
Starts listening for route changes from the connected parent or iframe. Returns an unsubscribe function. The callback receives IPayloadRouteChange ({ route, replace? }).
Use the same pair on both sides of the bridge:
// Parent route changed.
parentClient.sendRouteChange('/contacts/123?tab=info');
iframeClient.onExternalRouteChange(({route, replace}) => {
syncIframeRouter(route, {replace});
});
// Iframe route changed.
iframeClient.sendRouteChange('/contacts/456');
parentClient.onExternalRouteChange(({route, replace}) => {
syncParentRouter(route, {replace});
});When handling a route received through onExternalRouteChange, avoid sending the same value back with sendRouteChange. Compare it with the current local route before applying it to prevent synchronization loops.
Technical support
getTechnicalSupport(): TechnicalSupport
Returns the TechnicalSupport singleton, which provides utilities for reporting diagnostic information to x-bees support.
Known issues
The below function can fix cases when String.replaceAll() does not work in the mobile version. Most likely, this is some kind of WebView bug.
function replaceAll(str: string, search: string, replace: string) {
return str.split(search).join(replace);
}