-
Notifications
You must be signed in to change notification settings - Fork 396
docs(calling): add sdd docs for the CallingClient, excludes the calling sub-directory #4777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ee25d15
002f153
e170ac2
fd1c55c
db33a48
9fb23de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,245 @@ | ||
| # CallingClient Module | ||
|
|
||
| ## AI Agent Routing Instructions | ||
|
|
||
| **If you are an AI assistant or automated tool:** | ||
|
|
||
| Do **not** use this file as your only entry point for reasoning or code generation. | ||
|
|
||
| - **How to proceed:** | ||
| - For changes within the `line/` subdirectory, also load [line/ai-docs/AGENTS.md](../line/ai-docs/AGENTS.md). | ||
| - For changes within the `registration/` subdirectory, also load [registration/ai-docs/AGENTS.md](../registration/ai-docs/AGENTS.md). | ||
| - For changes within the `calling/` subdirectory (Call, CallManager, CallerId), refer to the calling subdirectory source files directly. | ||
| - **Important:** Load the module-specific docs in this file first, then drill into subdirectory docs as needed. | ||
|
|
||
| --- | ||
|
|
||
| ## Overview | ||
|
|
||
| The `CallingClient` is one of the significant modules in the Webex Calling SDK, responsible for the main WebRTC call flow implementation. It manages line registration, call lifecycle coordination, Mobius server discovery, and network resilience. | ||
|
|
||
| Applications create a `CallingClient` via the `createClient()` factory function and interact with lines and calls through it. | ||
|
|
||
| **Package:** `@webex/calling` | ||
|
|
||
| **Entry point:** `packages/calling/src/CallingClient/CallingClient.ts` | ||
|
|
||
| **Factory:** `createClient(webex, config?) → ICallingClient` | ||
|
|
||
| --- | ||
|
|
||
| ### Key Capabilities | ||
|
|
||
| | Capability | Description | | ||
| | ----------- | ----------- | | ||
| | **Mobius Discovery** | Performs region-based Mobius server discovery to select optimal primary and backup endpoints for registration, calls, and media. | | ||
| | **Line Registration** | Creates and registers Lines with Mobius, establishing signaling sessions, subscribing for events, and managing registration/status. Includes Line keepalives and failover routines. | | ||
| | **Media Engine Management** | Initializes and configures the `@webex/internal-media-core` engine to negotiate, establish, and manage WebRTC media streams for audio and video calls. | | ||
| | **Call Keepalive** | Periodically sends keepalive messages for both Lines and active Calls, ensuring session continuity and timely detection of network or signaling issues. | | ||
| | **Call Control** | Orchestrates all aspects of call initiation, handling, and features. Divided into the following subcapabilities: | | ||
| | • Outbound Calls | Enables agents to initiate outbound calls using `line.makeCall()`. Handles call setup, signaling, and media path establishment, including error cases. | | ||
|
Kesari3008 marked this conversation as resolved.
|
||
| | • Inbound Calls | Receives and processes incoming calls via `LINE_EVENTS.INCOMING_CALL`, triggers session setup, and allocates resources for the new call. | | ||
| | • Supplementary Services | Provides additional in-call features including hold, resume, transfer, mute, and sending DTMF using `ICall` interface methods and underlying SIP signaling. Hold and resume suspend and reestablish the audio+video media while maintaining session context. Transfer allows the redirection of calls to alternate destinations. | | ||
| | **Active Call Monitoring** | Monitors and tracks all ongoing calls, connection state (connected, held, disconnected), participant media status, and synchronization across lines and devices. | | ||
| | **Network Resilience** | Detects network outages or Mercury channel disconnects; triggers reconnection, re-registration, and call state recovery logic to restore service with minimal interruption. | | ||
| | **Diagnostics & Logging** | Collects and uploads diagnostic logs and metrics for calls, registrations, and failures to Webex cloud for troubleshooting, monitoring, and analytics purposes. | | ||
| | **Service Indicators & Access Flows** | Supports various service flows and user types (`calling`, `guestcalling`, `contactcenter`) through the `ServiceIndicator`, enabling correct registration and feature availability based on license and context. | | ||
|
|
||
| --- | ||
|
|
||
| ## Public API | ||
|
|
||
| ### ICallingClient Interface | ||
|
|
||
| The following methods are defined on the `ICallingClient` interface and are the officially supported public API: | ||
|
|
||
| | Method | Signature | Description | | ||
| | ------------------ | ------------------------------------------ | ----------------------------------------------- | | ||
| | `getSDKConnector` | `(): ISDKConnector` | Returns the SDK connector singleton | | ||
| | `getLoggingLevel` | `(): LOGGER` | Returns the current log level | | ||
| | `getLines` | `(): Record<string, ILine>` | Returns all the lines | | ||
| | `getDevices` | `(userId?: string): Promise<DeviceType[]>` | Fetches devices from Mobius for the user | | ||
| | `getActiveCalls` | `(): Record<string, ICall[]>` | Returns active calls grouped by lineId | | ||
| | `getConnectedCall` | `(): ICall \| undefined` | Returns the currently connected (non-held) call | | ||
| | `mediaEngine` | `typeof Media` | The `@webex/internal-media-core` engine | | ||
|
|
||
| ### CallingClient Class Methods (not on ICallingClient interface) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of saying not on ICallingClient interface, we should simply talk about where its imported from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do have /**
* Uploads logs to help troubleshoot SDK issues.
*
* This method collects the current SDK logs including network requests, WebSocket
* messages, and client-side events, then securely submits them to Webex's diagnostics
* service. The returned tracking ID, feedbackID can be provided to Webex support for faster
* issue resolution.
* @returns Promise<UploadLogsResponse>
* @throws Error
*/
public async uploadLogs(): Promise<UploadLogsResponse> {
const result = await uploadLogs({}, true);
if (!result) {
throw new Error('Failed to upload logs: No response received.');
}
return result;
} |
||
|
|
||
| | Method | Signature | Description | | ||
| | ------------ | --------------------------------- | ---------------------------------------------------- | | ||
| | `uploadLogs` | `(): Promise<UploadLogsResponse>` | Uploads diagnostic logs to Webex (class method only) | | ||
|
|
||
| ### Events Emitted | ||
|
|
||
| | Event | Enum Key | Payload | Description | | ||
| | ------------------------------------ | --------------------------------------------- | -------------------- | ---------------------------- | | ||
| | `callingClient:error` | `CALLING_CLIENT_EVENT_KEYS.ERROR` | `CallingClientError` | Client-level error | | ||
| | `callingClient:outgoing_call` | `CALLING_CLIENT_EVENT_KEYS.OUTGOING_CALL` | `string` (callId) | Outbound call initiated | | ||
|
Kesari3008 marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This event is documented as emitted, but the runtime does not dispatch it: Useful? React with 👍 / 👎.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noting this point. We will need to fix the code as well |
||
| | `callingClient:user_recent_sessions` | `CALLING_CLIENT_EVENT_KEYS.USER_SESSION_INFO` | `CallSessionEvent` | User session info from Janus | | ||
| | `callingClient:all_calls_cleared` | `CALLING_CLIENT_EVENT_KEYS.ALL_CALLS_CLEARED` | _(none)_ | All active calls have ended | | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This table documents Useful? React with 👍 / 👎. |
||
|
|
||
| --- | ||
|
|
||
| ## Configuration | ||
|
|
||
| ### CallingClientConfig | ||
|
|
||
| ```typescript | ||
| interface CallingClientConfig { | ||
| logger?: {level: LOGGER}; | ||
| discovery?: {country: string; region: string}; | ||
| serviceData?: {indicator: ServiceIndicator; domain?: string}; | ||
| jwe?: string; | ||
| } | ||
| ``` | ||
|
|
||
| | Property | Required | Default | Description | | ||
| | ----------------------- | -------- | ------------- | ----------------------------------------------------------- | | ||
| | `logger.level` | No | `ERROR` | Log verbosity level | | ||
| | `discovery.country` | No | Auto-detected | Override country for Mobius discovery | | ||
| | `discovery.region` | No | Auto-detected | Override region for Mobius discovery | | ||
| | `serviceData.indicator` | No | `CALLING` | Service flow: `calling`, `guestcalling`, or `contactcenter` | | ||
| | `serviceData.domain` | No | `''` | RTMS domain required for contact center flow | | ||
| | `jwe` | No | - | JSON Web Encryption token having destination information. This is only required for guest calling flow | | ||
|
|
||
| --- | ||
|
|
||
| ## Examples and Use Cases | ||
|
|
||
| ### Getting Started | ||
|
|
||
| #### Create and Initialize a CallingClient | ||
|
|
||
| ```typescript | ||
| import {createClient, ServiceIndicator} from '@webex/calling'; | ||
|
|
||
| const callingClient = await createClient(webex, { | ||
| logger: {level: 'info'}, | ||
| serviceData: {indicator: ServiceIndicator.CALLING, domain: ''}, | ||
| }); | ||
| ``` | ||
|
|
||
| The `createClient` factory instantiates `CallingClient` and calls `init()`, which: | ||
|
|
||
| 1. Performs ICE warmup (Windows Chromium only) | ||
|
Shreyas281299 marked this conversation as resolved.
|
||
| 2. Discovers Mobius servers for the client region (via `ds.ciscospark.com`) | ||
| 3. Creates a Line object internally | ||
|
|
||
| **Note:** `init()` does NOT register the line. The application must call `line.register()` explicitly after obtaining the line via `getLines()`. | ||
|
|
||
| #### Register a Line and Listen for Events | ||
|
|
||
| ```typescript | ||
| const lines = callingClient.getLines(); | ||
| const line = Object.values(lines)[0]; | ||
|
|
||
| line.on('registered', (registeredLine) => { | ||
| console.log('Line registered:', registeredLine.lineId); | ||
| console.log('Phone number:', registeredLine.phoneNumber); | ||
| }); | ||
|
|
||
| line.on('error', (error) => { | ||
| console.error('Line error:', error.getError()); | ||
| }); | ||
|
|
||
| line.on('line:incoming_call', (call) => { | ||
| console.log('Incoming call from:', call.getCallerInfo()); | ||
| call.answer(localAudioStream); | ||
| }); | ||
|
|
||
| line.register(); | ||
| ``` | ||
|
|
||
| #### Make an Outbound Call | ||
|
|
||
| ```typescript | ||
| const callDetails = {type: 'uri', address: 'sip:user@example.com'}; | ||
| const call = line.makeCall(callDetails); | ||
|
Comment on lines
+156
to
+157
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This quick-start example uses Useful? React with 👍 / 👎.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is correct. No change required |
||
|
|
||
| call.on('connect', (callId) => { | ||
| console.log('Call connecting:', callId); | ||
| }); | ||
|
|
||
| call.on('established', (callId) => { | ||
| console.log('Call established:', callId); | ||
| }); | ||
|
|
||
| call.on('disconnect', (callId) => { | ||
| console.log('Call ended:', callId); | ||
| }); | ||
|
|
||
| call.dial(localAudioStream); | ||
| ``` | ||
|
|
||
| #### Handle Network Disruptions | ||
|
|
||
| ```typescript | ||
| line.on('reconnecting', () => { | ||
| console.log('Network disruption — attempting to reconnect...'); | ||
| }); | ||
|
|
||
| line.on('reconnected', () => { | ||
| console.log('Successfully reconnected to Mobius'); | ||
| }); | ||
| ``` | ||
|
|
||
| #### Upload Diagnostic Logs | ||
|
|
||
| ```typescript | ||
| try { | ||
| const response = await callingClient.uploadLogs(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This example calls Useful? React with 👍 / 👎. |
||
| console.log('Logs uploaded:', response); | ||
| } catch (error) { | ||
| console.error('Log upload failed:', error); | ||
| } | ||
| ``` | ||
|
|
||
| #### Query Active Calls and Devices | ||
|
|
||
| ```typescript | ||
| const activeCalls = callingClient.getActiveCalls(); | ||
| const connectedCall = callingClient.getConnectedCall(); | ||
| const devices = await callingClient.getDevices(); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Dependencies | ||
|
|
||
| ### Runtime Dependencies | ||
|
|
||
| | Package | Purpose | | ||
| | -------------------------------- | ------------------------------------------- | | ||
| | `@webex/internal-media-core` | WebRTC, ROAP media connections | | ||
| | `@webex/media-helpers` | Microphone stream, noise reduction | | ||
| | `@webex/internal-plugin-metrics` | Telemetry and metrics | | ||
| | `async-mutex` | Concurrency control for registration | | ||
| | `xstate` | State machines for call and media lifecycle | | ||
| | `uuid` | Unique identifier generation | | ||
|
|
||
| ### Internal Dependencies | ||
|
|
||
| | Module | Purpose | | ||
| | --------------- | --------------------------------------------------- | | ||
| | `SDKConnector` | Singleton bridge to Webex SDK and Mercury WebSocket | | ||
| | `CallManager` | Singleton managing all active Call instances | | ||
| | `MetricManager` | Singleton for telemetry submission | | ||
| | `Logger` | Structured logging with file/method context | | ||
| | `Eventing<T>` | Typed event emitter base class | | ||
|
|
||
| --- | ||
|
|
||
| ## Subdirectory Documentation | ||
|
|
||
| For detailed documentation on specific subsystems: | ||
|
|
||
| | Subdirectory | AGENTS.md | ARCHITECTURE.md | Description | | ||
| | --------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------ | | ||
| | `line/` | [line/ai-docs/AGENTS.md](../line/ai-docs/AGENTS.md) | [line/ai-docs/ARCHITECTURE.md](../line/ai-docs/ARCHITECTURE.md) | Line management, registration orchestration, call initiation | | ||
| | `registration/` | [registration/ai-docs/AGENTS.md](../registration/ai-docs/AGENTS.md) | [registration/ai-docs/ARCHITECTURE.md](../registration/ai-docs/ARCHITECTURE.md) | Device registration, keepalive, failover, web worker | | ||
|
|
||
| --- | ||
|
|
||
| ## Related Documentation | ||
|
|
||
| - [Architecture](./ARCHITECTURE.md) — Component overview, data flows, sequence diagrams | ||
|
Kesari3008 marked this conversation as resolved.
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something we could add in README.md or root AGENTS.md and we do not need to add this every AGENTS.md file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have simplified it a bit. This will be a bit redundant for now. We can groom it once we have all the spec files in place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel this is not needed