How x-bees Uses Integration Applications
x-bees supports two primary integration modes for applications:
-
UI Integration: Embedding your frontend application inside the x-bees interface (info-frame) to display contextual information.
-
Non-UI Integration: Running your integration in the background without a user interface, primarily for search and contact lookups.
Below, I'll explain each variant in detail, along with flow diagrams to illustrate how they work.
UI Integration (Info-frame Application)
In this mode, your frontend application is embedded within the x-bees interface, specifically inside the info-frame. The application can access runtime context from x-bees to display detailed information about the current contact or conversation.
Key Features:
- Contextual Data Access: Your app can access real-time data about contacts and conversations.
- Interactive UI: Users can interact with your application directly within the x-bees interface.
- Event Listening: Your app can listen to events from x-bees (e.g., contact selection changes).
Sequence Diagram:
Explanation:
- Initialization:
- The user opens the x-bees interface.
- x-bees loads your embedded application inside the info-frame.
- Your app sends a
ready()
signal to indicate it's ready to receive context.
- Context Provisioning:
- x-bees provides initial context data (e.g., current contact or conversation) to your app.
- Your app subscribes to relevant events to receive updates.
- User Interaction:
- When the user selects a different contact or conversation, x-bees sends updated context data to your app.
- Your app updates the display accordingly to show detailed information.
- Interactivity:
- The user interacts with your app within the info-frame.
- Your app can perform actions via x-bees, such as starting a call or sending a message.
Technical Considerations:
- Event Handling: Implement event listeners to respond to context changes.
- Context Awareness: Use the x-bees SDK to access context data.
- UI Responsiveness: Ensure your app adjusts its UI based on the provided context.
Non-UI Integration (Background Application)
In this mode, your integration runs in the background without a user interface. It's used primarily for functionalities like real-time search results and contact lookups.
Key Features:
- Lightweight Operation: Since there's no UI, the application should be optimized for performance.
- Search Integration: Provides search results or contact matches when the user performs a search in x-bees.
- Minimal Resource Usage: Only necessary modules are loaded to keep resource usage low.
Sequence Diagram:
Explanation:
- Search Trigger:
- The user types a query into the x-bees search field.
- Query Handling:
- x-bees sends the search query to your background integration app.
- Your app processes the query using lightweight modules (no UI components).
- Returning Results:
- Your app returns relevant search results to x-bees.
- x-bees displays combined results from all integrations to the user.
Technical Considerations:
- Module Separation: Separate your application's code into modules to ensure only necessary code is loaded.
- Core Module: Contains the logic needed for background operations (e.g., search processing).
- UI Module: Contains code for the user interface, which should not be loaded in this variant.
- Optimizations:
- Avoid loading heavy libraries or UI frameworks in the background variant.
- Use lazy loading or dynamic imports to load modules only when necessary.
- Event Handling: Implement necessary event listeners to respond to x-bees requests (e.g., search queries).
Event Handling of Contacts search
Starts listen for the events of searching contacts and handle autosuggestion with the provided callback
Client.getInstance().onSuggestContacts(async (query, resolve) => {
try {
const contacts = await fetchContacts(query);
resolve(contacts);
} catch (error) {
console.log('catch', error);
}
});
Starts listen for the events of searching contact info and finds best match
Client.getInstance().onLookupAndMatchContact(async (query, resolve) => {
try {
const contact = await fetchContactAndMatch(query);
resolve(contact);
} catch (error) {
console.log('catch', error);
}
});
Efficient Application Design for Both Variants
To support both integration modes efficiently, you should architect your application to allow for conditional loading of modules based on the integration variant. xbees-connect's Client can help with serving conditional loading.
Flow Diagram for Combined Architecture:
Explanation:
- App Initialization: When the application starts, it first determines which mode it should run in.
- Determine Mode:
- The app checks for certain parameters or configuration to decide if it's in UI mode or daemon mode.
- Conditional Loading:
- UI Mode: The app loads UI modules and runs the application with the interface.
- Data Source Mode: The app loads only the necessary background modules and runs without a UI.
Example Implementing Mode-Specific Module Loading in x-bees Integration:
In this section, we'll demonstrate how to structure your integration application to efficiently support both UI Integration and Non-UI Integration modes in x-bees.
File Structure
src/
├── main.ts // Entry point of the application
├── auth.ts // Authentication logic
├── app/
│ ├── App.tsx // Root React component
│ ├── startUI.ts // UI initialization logic
│ └── ...
└── app-start/
├── StartApp.ts // Contains the StartApp class
├── startUILazy.ts // Lazy loader for the UI
└── ... // Contains the StartApp Utility functions
Code Explanation
1. main.ts
This is the entry point of your application. Initializes the app by creating a new instance of the StartApp class and calling its start() method.
// main.ts
import { StartApp } from './app-start/StartApp';
new StartApp().start();
2. StartApp.ts
This file defines the StartApp
class, which initializes the x-bees Client and handles mode determination.
// startApp.ts
import Client from '@wildix/xbees-connect';
import { startUILazy } from './startUILazy';
import Auth from './auth';
import { fetchContacts, fetchContactAndMatch } from './utils';
export class StartApp {
private initializeClient() {
Client.getInstance().onLogout(this.onLogout);
// Determines the mode (UI or Data Source) and loads UI modules if needed.
Client.initialize(startUILazy);
// Sets up event handlers for contact suggestions and lookups.
Client.getInstance().onSuggestContacts(async (query, resolve) => {
try {
const contacts = await fetchContacts(query);
resolve(contacts);
} catch (error) {
console.error('Error fetching contacts:', error);
}
});
// Handle contact lookup and matching
Client.getInstance().onLookupAndMatchContact(async (query, resolve) => {
try {
const contact = await fetchContactAndMatch(query);
resolve(contact);
} catch (error) {
console.error('Error matching contact:', error);
}
});
// Notify x-bees that the app is ready
void Client.getInstance().ready();
}
private checkIsAuthorized() {
if (!Auth.getInstance().isAuthorized()) {
Client.getInstance().isNotAuthorized();
} else {
Client.getInstance().isAuthorized();
}
}
private onLogout = () => {
Auth.getInstance().logout();
// Additional logout handling if necessary
};
// Start the application
public start() {
this.initializeClient(); // Initialize client with event listeners
this.checkIsAuthorized(); // Perform authorization check
}
}
- Key Function:
Client.initialize(startUILazy);
- Determines the integration mode based on x-bees context.
- Calls
startUILazy
to load UI modules only if in UI mode.
3. startUI.ts
This file contains the function to initialize and render your React application.
// startUI.ts
import { createElement } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
export function startUI() {
const rootContainer = document.getElementById('root')!;
const reactRoot = createRoot(rootContainer);
reactRoot.render(createElement(App));
}
- Purpose: Starts the UI by rendering the root React component
App
. - Usage: Only loaded when the application runs in UI mode.
2. startUILazy.ts
This file provides a function to lazily load the UI modules when needed.
// startUILazy.ts
export async function startUILazy() {
try {
const { startUI } = await import('./startUI');
startUI();
} catch (error) {
console.error('Error rendering UI:', error);
}
}
- Purpose: Dynamically imports
startUI
to defer loading UI modules until necessary. - Benefit: Reduces initial load time in Non-UI mode by not loading UI-related code.
How Mode Determination Works
The x-bees SDK provides the Client.initialize()
method, which can accept a callback function. This function is invoked only when the application is running in UI mode (e.g., within the infoframe). In Non-UI mode (Data Source mode), this callback is not called, preventing UI code from loading.
// Inside startApp.ts
Client.initialize(startUILazy);
-
In UI Mode:
- x-bees detects that the app should display a UI.
- Calls
startUILazy()
, which dynamically imports and executesstartUI()
. - UI modules (
startUI.ts
andApp.tsx
) are loaded and rendered.
-
In Non-UI Mode:
- x-bees does not call the callback.
- UI modules are not loaded.
- Only background functionalities (e.g., contact search) are active.
Flow Diagram
The code examples provided are for illustrative purposes. Adjustments may be necessary to fit your specific application context and requirements.