@convirza/dialer-sdk 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @convirza/dialer-sdk
2
2
 
3
- Production-ready embeddable WebRTC SIP dialer widget. Auto-configures from OAuth session, handles token refresh, cross-tab logout detection. Includes call parking, call history persistence, audio device management, call quality monitoring.
3
+ A browser-based calling widget that lets users make and receive calls directly from the web app, with call history, call parking, device controls.
4
4
 
5
5
  ---
6
6
 
@@ -43,18 +43,6 @@ Production-ready embeddable WebRTC SIP dialer widget. Auto-configures from OAuth
43
43
  npm install @convirza/dialer-sdk
44
44
  ```
45
45
 
46
- **Peer dependency** — SIP.js must be loaded separately (UMD global `SIP` or `sip`):
47
-
48
- ```html
49
- <script src="https://cdn.jsdelivr.net/npm/sip.js@0.13.8/dist/sip.js"></script>
50
- ```
51
-
52
- Or install via npm and bundle it yourself:
53
-
54
- ```bash
55
- npm install sip.js@^0.13.8
56
- ```
57
-
58
46
  ---
59
47
 
60
48
  ## Quick Start
@@ -75,11 +63,10 @@ const accessToken = localStorage.getItem('access_token');
75
63
  const refreshToken = localStorage.getItem('refresh_token');
76
64
 
77
65
  // Initialize widget (auto-fetches SIP config from OAuth session endpoint)
66
+ // OAuth/API URLs hardcoded in SDK — points to staging by default
78
67
  convirzaDialer.init({
79
68
  access_token: accessToken,
80
69
  refresh_token: refreshToken,
81
- oauth_endpoint: 'https://stag-5-oauth.convirza.com/oauth/internal',
82
- api_url: 'https://stag-5-dialer-apis.convirza.com',
83
70
  dark_theme: true,
84
71
  primaryColor: '#6366f1',
85
72
  brandName: 'Acme Corp',
@@ -134,7 +121,6 @@ const refreshToken = localStorage.getItem('refresh_token');
134
121
  initDialer({
135
122
  access_token: accessToken,
136
123
  refresh_token: refreshToken,
137
- api_url: 'https://stag-5-dialer-apis.convirza.com',
138
124
  });
139
125
 
140
126
  if (isDialerInitialized()) {
@@ -157,9 +143,7 @@ Embed the dialer widget as a custom HTML element.
157
143
  dialer.setAttribute('access-token', accessToken);
158
144
  dialer.setAttribute('refresh-token', refreshToken);
159
145
  dialer.setAttribute('auto-configure', 'true');
160
- dialer.setAttribute('oauth-endpoint', 'https://stag-5-oauth.convirza.com/oauth/internal');
161
146
  dialer.setAttribute('theme', 'dark');
162
- dialer.setAttribute('api-url', 'https://stag-5-dialer-apis.convirza.com');
163
147
 
164
148
  // Listen for token refresh (only fires if access_token expires)
165
149
  dialer.addEventListener('token-refreshed', (e) => {
@@ -182,8 +166,6 @@ Embed the dialer widget as a custom HTML element.
182
166
  - `access-token` — Access token from user login (used first)
183
167
  - `refresh-token` — Refresh token (fallback if access_token expires)
184
168
  - `auto-configure="true"` — Enables auto-config flow
185
- - `oauth-endpoint` — OAuth base URL (default: `https://stag-5-oauth.convirza.com/oauth/internal`)
186
- - `api-url` — API base URL for park slots, call history
187
169
 
188
170
  **Events:**
189
171
 
@@ -222,7 +204,6 @@ localStorage.setItem('refresh_token', refresh_token);
222
204
  convirzaDialer.init({
223
205
  access_token: localStorage.getItem('access_token'),
224
206
  refresh_token: localStorage.getItem('refresh_token'),
225
- oauth_endpoint: 'https://stag-5-oauth.convirza.com/oauth/internal',
226
207
  });
227
208
  ```
228
209
 
@@ -349,28 +330,23 @@ Initialize the dialer and inject the widget into the page. **Must be called befo
349
330
  convirzaDialer.init(config: DialerInitConfig): void
350
331
  ```
351
332
 
352
- | Field | Type | Required | Description |
353
- | ---------------- | --------- | -------- | -------------------------------------------- |
354
- | `access_token` | `string` | Yes | Access token from user login session |
355
- | `refresh_token` | `string` | Yes | Refresh token (used if access_token expires) |
356
- | `oauth_endpoint` | `string` | No | OAuth base URL (default: internal) |
357
- | `api_url` | `string` | No | API base URL for park slots, call history |
358
- | `brandName` | `string` | No | Brand name shown in widget header |
359
- | `brandLogo` | `string` | No | URL of brand logo image |
360
- | `dark_theme` | `boolean` | No | Use dark theme (default `false`) |
361
- | `showPopup` | `boolean` | No | Start with widget expanded |
362
- | `primaryColor` | `string` | No | CSS color for primary UI elements (hex/rgb) |
363
- | `accentColor` | `string` | No | CSS color for accent elements |
364
-
365
- OAuth response provides SIP credentials automatically. User never sees SIP details.
333
+ | Field | Type | Required | Description |
334
+ | --------------- | --------- | -------- | -------------------------------------------- |
335
+ | `access_token` | `string` | Yes | Access token from user login session |
336
+ | `refresh_token` | `string` | Yes | Refresh token (used if access_token expires) |
337
+ | `brandName` | `string` | No | Brand name shown in widget header |
338
+ | `brandLogo` | `string` | No | URL of brand logo image |
339
+ | `dark_theme` | `boolean` | No | Use dark theme (default `false`) |
340
+ | `showPopup` | `boolean` | No | Start with widget expanded |
341
+ | `primaryColor` | `string` | No | CSS color for primary UI elements (hex/rgb) |
342
+ | `accentColor` | `string` | No | CSS color for accent elements |
366
343
 
367
344
  **Example:**
368
345
 
369
346
  ```js
370
347
  convirzaDialer.init({
371
- oauth_endpoint: 'https://api.example.com/oauth/token',
372
- username: 'user@example.com',
373
- password: 'userpassword',
348
+ access_token: 'eyJhbGc...',
349
+ refresh_token: 'eyJhbGc...',
374
350
  dark_theme: true,
375
351
  primaryColor: '#6366f1',
376
352
  brandName: 'Acme Corp',
@@ -1208,48 +1184,6 @@ const result = await api.fetchOrderedNumbers({
1208
1184
 
1209
1185
  ---
1210
1186
 
1211
- ### `CallHistoryAPI`
1212
-
1213
- REST client for persisting and querying call history.
1214
-
1215
- ```ts
1216
- import { CallHistoryAPI } from '@convirza/dialer-sdk';
1217
-
1218
- const api = new CallHistoryAPI('https://api.convirza.com', 'Bearer-token');
1219
-
1220
- const history = await api.fetchHistory({
1221
- userId: 'user-123',
1222
- sipDomain: 'sip.example.com',
1223
- limit: 50,
1224
- offset: 0,
1225
- });
1226
- // history: { calls: CallRecord[], total: number, hasMore: boolean }
1227
-
1228
- const saved = await api.saveCall({
1229
- callId: 'abc-123',
1230
- userId: 'user-123',
1231
- sipDomain: 'sip.example.com',
1232
- callerIdNumber: '+15551234567',
1233
- phoneNumber: '+19876543210',
1234
- direction: 'outbound',
1235
- disposition: 'answered',
1236
- startedAt: Date.now(),
1237
- durationSeconds: 42,
1238
- createdAt: Date.now(),
1239
- });
1240
-
1241
- const updated = await api.updateCall(saved.callId, { disposition: 'missed' });
1242
- ```
1243
-
1244
- | Method | Description |
1245
- | ----------------------------- | -------------------------------- |
1246
- | `setAuthToken(token)` | Update the bearer token |
1247
- | `fetchHistory(params)` | Fetch paginated call history |
1248
- | `saveCall(record)` | Create a new call history record |
1249
- | `updateCall(callId, updates)` | Patch an existing call record |
1250
-
1251
- ---
1252
-
1253
1187
  ## Web Component Reference
1254
1188
 
1255
1189
  ### Web Component Attributes
@@ -1261,8 +1195,6 @@ The `<convirza-dialer>` custom element accepts the following HTML attributes:
1261
1195
  | `access-token` | `string` | Yes\* | Access token from user login |
1262
1196
  | `refresh-token` | `string` | Yes\* | Refresh token (fallback if access_token expires) |
1263
1197
  | `auto-configure` | `'true' \| 'false'` | Yes\* | Enable auto-config from OAuth session |
1264
- | `oauth-endpoint` | `string` | No | OAuth base URL (default: stag-5 internal) |
1265
- | `api-url` | `string` | No | API base URL for park/history |
1266
1198
  | `brand-name` | `string` | No | Brand name in header |
1267
1199
  | `brand-logo` | `string` | No | URL for brand logo |
1268
1200
  | `theme` | `'light' \| 'dark'` | No | UI theme (default: dark) |
@@ -1273,8 +1205,6 @@ The `<convirza-dialer>` custom element accepts the following HTML attributes:
1273
1205
  | `z-index` | `number` | No | CSS z-index of the widget |
1274
1206
  | `park-poll-interval` | `number` | No | Park slots polling interval in ms (default 5000) |
1275
1207
 
1276
- **Required only for auto-configure mode.** Widget fetches SIP credentials from OAuth session endpoint automatically.
1277
-
1278
1208
  ### Web Component Public Methods
1279
1209
 
1280
1210
  All methods can be called on the element reference.
@@ -1420,7 +1350,7 @@ element.setTheme({
1420
1350
 
1421
1351
  #### `element.clearCallHistoryCache()`
1422
1352
 
1423
- Clear IndexedDB call history cache and reload from backend.
1353
+ Clear IndexedDB call history.
1424
1354
 
1425
1355
  ```ts
1426
1356
  async clearCallHistoryCache(): Promise<void>
@@ -1514,17 +1444,14 @@ Call parking allows transferring an active call to a shared "parking lot" where
1514
1444
  **HTML Attributes:**
1515
1445
 
1516
1446
  ```html
1517
- <convirza-dialer
1518
- api-url="https://stag-5-dialer-apis.convirza.com"
1519
- auth-token="Bearer xyz"
1520
- park-poll-interval="5000"
1521
- ></convirza-dialer>
1447
+ <convirza-dialer auth-token="Bearer xyz" park-poll-interval="5000"></convirza-dialer>
1522
1448
  ```
1523
1449
 
1524
- - `api-url`: Base API URL — park endpoint is `{api-url}/v3/park-slots`
1525
1450
  - `auth-token`: JWT or API key for backend auth
1526
1451
  - `park-poll-interval`: Poll interval in ms (default: 5000)
1527
1452
 
1453
+ **Note:** API URL hardcoded in SDK — park endpoint auto-detected as `{API_URL}/v3/park-slots`
1454
+
1528
1455
  #### Backend API
1529
1456
 
1530
1457
  **Required endpoint:**
@@ -1578,81 +1505,30 @@ element.addEventListener('call-park-failed', (e) => {
1578
1505
 
1579
1506
  ### Call History Persistence
1580
1507
 
1581
- Call history is saved to **two tiers**:
1582
-
1583
- 1. **IndexedDB** (local cache) — instant load, offline support
1584
- 2. **Backend API** (source of truth) — multi-device sync, compliance
1585
-
1586
- Widget saves to IndexedDB immediately (non-blocking), then syncs to backend async.
1508
+ Call history saved to **IndexedDB** (browser-local storage). No backend sync.
1587
1509
 
1588
1510
  #### Data Flow
1589
1511
 
1590
1512
  **On call end:**
1591
1513
 
1592
1514
  1. Widget generates UUID `callId`
1593
- 2. Saves to IndexedDB (instant)
1594
- 3. POSTs to `/api/call-history` (async, retries on failure)
1595
- 4. Reloads history from IndexedDB to update UI
1515
+ 2. Saves to IndexedDB
1516
+ 3. Reloads history to update UI
1596
1517
 
1597
1518
  **On SIP registration:**
1598
1519
 
1599
1520
  1. Initialize `CallHistoryService`
1600
- 2. Load from IndexedDB (fast)
1601
- 3. Background-sync from backend (replaces IndexedDB cache)
1521
+ 2. Load from IndexedDB
1602
1522
 
1603
1523
  **On page reload:**
1604
1524
 
1605
1525
  - IndexedDB persists → history visible immediately
1606
- - Backend sync refreshes on reconnect
1607
-
1608
- #### Configuration
1609
1526
 
1610
- **HTML Attributes:**
1527
+ #### Storage Scope
1611
1528
 
1612
- ```html
1613
- <convirza-dialer api-url="https://api.example.com" auth-token="Bearer xyz"></convirza-dialer>
1614
- ```
1615
-
1616
- - `api-url`: Base API URL — history endpoint = `{api-url}/api/call-history`
1617
- - `auth-token`: JWT or API key for backend auth
1618
-
1619
- **If `api-url` not set:**
1620
-
1621
- - IndexedDB-only mode (no backend sync)
1622
- - History persists locally but not across devices
1623
-
1624
- #### Backend API
1625
-
1626
- **Required endpoints:**
1627
-
1628
- ```
1629
- GET /api/call-history?userId={id}&sipDomain={domain}&limit=100&offset=0
1630
- POST /api/call-history
1631
- PATCH /api/call-history/{callId}
1632
- ```
1633
-
1634
- **Database schema (PostgreSQL):**
1635
-
1636
- ```sql
1637
- CREATE TABLE call_history (
1638
- id BIGSERIAL PRIMARY KEY,
1639
- call_id VARCHAR(100) UNIQUE NOT NULL,
1640
- user_id VARCHAR(50) NOT NULL,
1641
- sip_domain VARCHAR(100) NOT NULL,
1642
- phone_number VARCHAR(50) NOT NULL,
1643
- direction VARCHAR(10) NOT NULL CHECK (direction IN ('inbound', 'outbound')),
1644
- status VARCHAR(20) NOT NULL CHECK (status IN ('answered', 'missed', 'rejected', 'failed')),
1645
- started_at TIMESTAMPTZ NOT NULL,
1646
- ended_at TIMESTAMPTZ,
1647
- duration_seconds INTEGER DEFAULT 0,
1648
- recording_url VARCHAR(500),
1649
- created_at TIMESTAMPTZ DEFAULT NOW(),
1650
- INDEX idx_user_domain_started (user_id, sip_domain, started_at DESC),
1651
- INDEX idx_call_id (call_id)
1652
- );
1653
- ```
1654
-
1655
- See `docs/CALL_HISTORY_API.md` for full spec, Node.js examples, security notes.
1529
+ - **Per-browser only** — not synced across devices
1530
+ - **Offline support** — no network dependency
1531
+ - **Privacy** — stays local, never uploaded
1656
1532
 
1657
1533
  #### Events
1658
1534
 
@@ -1664,6 +1540,13 @@ element.addEventListener('history-updated', (e) => {
1664
1540
  });
1665
1541
  ```
1666
1542
 
1543
+ #### API Methods
1544
+
1545
+ ```js
1546
+ // Clear all call history
1547
+ await dialer.clearCallHistoryCache();
1548
+ ```
1549
+
1667
1550
  ### Audio Device Management
1668
1551
 
1669
1552
  Microphone and speaker selection with hot-swapping during calls.
@@ -1686,35 +1569,6 @@ await sip.setSpeaker(deviceId);
1686
1569
  - Microphone switching: Chrome, Firefox, Safari, Edge
1687
1570
  - Speaker switching (`setSinkId`): Chrome, Edge only (silently no-ops in Firefox/Safari)
1688
1571
 
1689
- ### Call Quality Monitoring
1690
-
1691
- Polls `RTCPeerConnection.getStats()` every 2s and emits quality metrics.
1692
-
1693
- **Metrics:**
1694
-
1695
- - **Bitrate** (kbps)
1696
- - **Packet loss** (%)
1697
- - **Jitter** (ms)
1698
- - **Latency** (ms, round-trip)
1699
- - **Audio level** (0–1)
1700
- - **Quality** (`excellent` | `good` | `fair` | `poor`)
1701
-
1702
- **Usage:**
1703
-
1704
- ```js
1705
- const sip = new SipAdapter(config, {
1706
- onQualityChange: (metrics) => {
1707
- if (metrics.quality === 'poor') {
1708
- console.warn('Poor call quality:', metrics);
1709
- }
1710
- },
1711
- });
1712
-
1713
- // Or poll manually
1714
- const metrics = sip.getCallQuality();
1715
- console.log('Packet loss:', metrics.packetLoss + '%');
1716
- ```
1717
-
1718
1572
  ### Theming
1719
1573
 
1720
1574
  #### HTML Attributes (static)
@@ -1808,31 +1662,6 @@ Requires a browser with WebRTC (`RTCPeerConnection`) and WebSocket support.
1808
1662
 
1809
1663
  ---
1810
1664
 
1811
- ## Project Structure
1812
-
1813
- ```
1814
- convirza-dialer-1/
1815
- ├── packages/web-sdk/
1816
- │ ├── src/ # Source code (TypeScript)
1817
- │ │ ├── ui/ # Web component
1818
- │ │ ├── sip/ # SIP adapter
1819
- │ │ ├── api/ # REST clients
1820
- │ │ ├── media/ # Audio device management
1821
- │ │ ├── constants/ # Configuration
1822
- │ │ └── types/ # TypeScript types
1823
- │ ├── test/ # Unit tests
1824
- │ ├── dist/ # Built output (published)
1825
- │ │ ├── index.esm.js # ES modules
1826
- │ │ ├── index.cjs.js # CommonJS
1827
- │ │ ├── index.umd.js # UMD (browser)
1828
- │ │ └── types/ # TypeScript declarations
1829
- │ └── package.json # Package metadata
1830
- └── demo/ # Demo files (root level, not published)
1831
- ├── demo.html # Interactive demo
1832
- ├── sip.bundle.js # Bundled SIP.js
1833
- └── README.md # Demo instructions
1834
- ```
1835
-
1836
1665
  **For development:** Work in `src/` directory.
1837
1666
  **For users:** Import from `dist/` (handled automatically by package.json).
1838
1667
 
@@ -1,8 +1,6 @@
1
1
  export interface DialerInitConfig {
2
2
  access_token: string;
3
3
  refresh_token: string;
4
- oauth_endpoint?: string;
5
- api_url?: string;
6
4
  dark_theme?: boolean;
7
5
  showPopup?: boolean;
8
6
  primaryColor?: string;