@app-connect/core 1.7.24 → 1.7.26

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.
Files changed (137) hide show
  1. package/.env.test +5 -5
  2. package/README.md +441 -441
  3. package/connector/developerPortal.js +31 -42
  4. package/connector/mock.js +84 -77
  5. package/connector/proxy/engine.js +164 -163
  6. package/connector/proxy/index.js +500 -500
  7. package/connector/registry.js +252 -252
  8. package/docs/README.md +50 -50
  9. package/docs/architecture.md +93 -93
  10. package/docs/connectors.md +116 -117
  11. package/docs/handlers.md +125 -125
  12. package/docs/libraries.md +101 -101
  13. package/docs/models.md +144 -144
  14. package/docs/routes.md +115 -115
  15. package/docs/tests.md +73 -73
  16. package/handlers/admin.js +523 -523
  17. package/handlers/appointment.js +193 -0
  18. package/handlers/auth.js +296 -296
  19. package/handlers/calldown.js +99 -99
  20. package/handlers/contact.js +280 -280
  21. package/handlers/disposition.js +82 -80
  22. package/handlers/log.js +984 -973
  23. package/handlers/managedAuth.js +446 -446
  24. package/handlers/plugin.js +208 -208
  25. package/handlers/user.js +142 -142
  26. package/index.js +3140 -2652
  27. package/jest.config.js +56 -56
  28. package/lib/analytics.js +54 -54
  29. package/lib/authSession.js +109 -109
  30. package/lib/cacheCleanup.js +21 -0
  31. package/lib/callLogComposer.js +898 -898
  32. package/lib/callLogLookup.js +34 -0
  33. package/lib/constants.js +8 -8
  34. package/lib/debugTracer.js +177 -177
  35. package/lib/encode.js +30 -30
  36. package/lib/errorHandler.js +218 -206
  37. package/lib/generalErrorMessage.js +41 -41
  38. package/lib/jwt.js +18 -18
  39. package/lib/logger.js +190 -190
  40. package/lib/migrateCallLogsSchema.js +116 -0
  41. package/lib/ringcentral.js +266 -266
  42. package/lib/s3ErrorLogReport.js +65 -65
  43. package/lib/sharedSMSComposer.js +471 -471
  44. package/lib/util.js +67 -67
  45. package/mcp/README.md +412 -395
  46. package/mcp/lib/validator.js +91 -91
  47. package/mcp/mcpHandler.js +425 -425
  48. package/mcp/tools/cancelAppointment.js +101 -0
  49. package/mcp/tools/checkAuthStatus.js +105 -105
  50. package/mcp/tools/confirmAppointment.js +101 -0
  51. package/mcp/tools/createAppointment.js +157 -0
  52. package/mcp/tools/createCallLog.js +327 -316
  53. package/mcp/tools/createContact.js +117 -117
  54. package/mcp/tools/createMessageLog.js +287 -287
  55. package/mcp/tools/doAuth.js +60 -60
  56. package/mcp/tools/findContactByName.js +93 -93
  57. package/mcp/tools/findContactByPhone.js +101 -101
  58. package/mcp/tools/getCallLog.js +111 -102
  59. package/mcp/tools/getGoogleFilePicker.js +99 -99
  60. package/mcp/tools/getHelp.js +43 -43
  61. package/mcp/tools/getPublicConnectors.js +94 -94
  62. package/mcp/tools/getSessionInfo.js +90 -90
  63. package/mcp/tools/index.js +51 -41
  64. package/mcp/tools/listAppointments.js +163 -0
  65. package/mcp/tools/logout.js +96 -96
  66. package/mcp/tools/rcGetCallLogs.js +65 -65
  67. package/mcp/tools/updateAppointment.js +154 -0
  68. package/mcp/tools/updateCallLog.js +130 -126
  69. package/mcp/ui/App/App.tsx +358 -358
  70. package/mcp/ui/App/components/AuthInfoForm.tsx +113 -113
  71. package/mcp/ui/App/components/AuthSuccess.tsx +22 -22
  72. package/mcp/ui/App/components/ConnectorList.tsx +82 -82
  73. package/mcp/ui/App/components/DebugPanel.tsx +43 -43
  74. package/mcp/ui/App/components/OAuthConnect.tsx +270 -270
  75. package/mcp/ui/App/lib/callTool.ts +130 -130
  76. package/mcp/ui/App/lib/debugLog.ts +41 -41
  77. package/mcp/ui/App/lib/developerPortal.ts +111 -111
  78. package/mcp/ui/App/main.css +5 -5
  79. package/mcp/ui/App/root.tsx +13 -13
  80. package/mcp/ui/index.html +13 -13
  81. package/mcp/ui/package-lock.json +6356 -6356
  82. package/mcp/ui/package.json +25 -25
  83. package/mcp/ui/tsconfig.json +26 -26
  84. package/mcp/ui/vite.config.ts +16 -16
  85. package/models/accountDataModel.js +33 -33
  86. package/models/adminConfigModel.js +35 -35
  87. package/models/cacheModel.js +30 -26
  88. package/models/callDownListModel.js +34 -34
  89. package/models/callLogModel.js +33 -27
  90. package/models/dynamo/connectorSchema.js +146 -146
  91. package/models/dynamo/lockSchema.js +24 -24
  92. package/models/dynamo/noteCacheSchema.js +29 -29
  93. package/models/llmSessionModel.js +17 -17
  94. package/models/messageLogModel.js +25 -25
  95. package/models/sequelize.js +16 -16
  96. package/models/userModel.js +45 -45
  97. package/package.json +72 -72
  98. package/releaseNotes.json +1093 -1073
  99. package/test/connector/proxy/engine.test.js +126 -93
  100. package/test/connector/proxy/index.test.js +279 -279
  101. package/test/connector/proxy/sample.json +161 -161
  102. package/test/connector/registry.test.js +415 -415
  103. package/test/handlers/admin.test.js +616 -616
  104. package/test/handlers/auth.test.js +1018 -1015
  105. package/test/handlers/contact.test.js +1014 -1014
  106. package/test/handlers/log.test.js +1298 -1160
  107. package/test/handlers/managedAuth.test.js +458 -458
  108. package/test/handlers/plugin.test.js +380 -380
  109. package/test/index.test.js +105 -105
  110. package/test/lib/cacheCleanup.test.js +42 -0
  111. package/test/lib/callLogComposer.test.js +1231 -1231
  112. package/test/lib/debugTracer.test.js +328 -328
  113. package/test/lib/jwt.test.js +176 -176
  114. package/test/lib/logger.test.js +206 -206
  115. package/test/lib/oauth.test.js +359 -359
  116. package/test/lib/ringcentral.test.js +467 -467
  117. package/test/lib/sharedSMSComposer.test.js +1084 -1084
  118. package/test/lib/util.test.js +329 -329
  119. package/test/mcp/tools/checkAuthStatus.test.js +83 -82
  120. package/test/mcp/tools/createCallLog.test.js +436 -436
  121. package/test/mcp/tools/createContact.test.js +58 -58
  122. package/test/mcp/tools/createMessageLog.test.js +595 -595
  123. package/test/mcp/tools/doAuth.test.js +113 -113
  124. package/test/mcp/tools/findContactByName.test.js +275 -275
  125. package/test/mcp/tools/findContactByPhone.test.js +296 -296
  126. package/test/mcp/tools/getCallLog.test.js +298 -298
  127. package/test/mcp/tools/getGoogleFilePicker.test.js +281 -281
  128. package/test/mcp/tools/getPublicConnectors.test.js +107 -107
  129. package/test/mcp/tools/getSessionInfo.test.js +127 -127
  130. package/test/mcp/tools/logout.test.js +233 -233
  131. package/test/mcp/tools/rcGetCallLogs.test.js +56 -56
  132. package/test/mcp/tools/updateCallLog.test.js +360 -360
  133. package/test/models/accountDataModel.test.js +98 -98
  134. package/test/models/dynamo/connectorSchema.test.js +189 -189
  135. package/test/models/models.test.js +568 -539
  136. package/test/routes/managedAuthRoutes.test.js +104 -129
  137. package/test/setup.js +178 -178
package/README.md CHANGED
@@ -1,441 +1,441 @@
1
- # App Connect Core
2
-
3
- Core package for RingCentral App Connect project providing modular APIs for CRM integration, authentication, contact management, and call logging.
4
-
5
- For maintainer-facing internal docs about the package internals, see [`docs/README.md`](./docs/README.md). That docs set covers the non-MCP code under `packages/core`.
6
-
7
- ## Features
8
-
9
- - **Modular API Design**: Flexible Express app setup with customizable middleware and routes
10
- - **CRM Connector Registry**: Centralized connector management for multiple CRM platforms
11
- - **Authentication**: OAuth and API key authentication support
12
- - **Contact Management**: Find, create, and manage contacts across CRM platforms
13
- - **Call Logging**: Comprehensive call and message logging capabilities
14
- - **Analytics**: Built-in analytics tracking for all operations
15
- - **Database Integration**: Sequelize.js ORM with automatic table management
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install @app-connect/core
21
- ```
22
-
23
- ## Quick Start
24
-
25
- ### Basic Usage
26
-
27
- ```javascript
28
- const { createCoreApp, connectorRegistry } = require('@app-connect/core');
29
- const myCRMConnector = require('./connectors/myCRM');
30
- const manifest = require('./connectors/manifest.json');
31
- // Set the default manifest for the connector registry. This ensures that all connectors
32
- // have access to the necessary configuration and metadata before registration.
33
- connectorRegistry.setDefaultManifest(manifest);
34
- // Register your CRM connectors. The default manifest must be set before registration
35
- // to ensure proper initialization of the connector with the required settings.
36
- connectorRegistry.registerConnector('myCRM', myCRMConnector, manifest);
37
-
38
- // Create Express app with all core functionality
39
- const app = createCoreApp();
40
-
41
- // Add your custom routes
42
- app.get('/my-custom-route', (req, res) => {
43
- res.send('Hello from custom route!');
44
- });
45
-
46
- exports.getServer = () => app;
47
- ```
48
-
49
- ### Connector Interface Registration
50
-
51
- The connector registry supports dynamic interface registration, allowing you to extend connector functionality without modifying the original connector:
52
-
53
- ```javascript
54
- const { connectorRegistry } = require('@app-connect/core');
55
-
56
- // Register interface functions for a platform
57
- async function customCreateCallLog({ user, contactInfo, authHeader, callLog, note }) {
58
- // Custom implementation
59
- return {
60
- logId: 'custom-log-id',
61
- returnMessage: {
62
- message: 'Call logged with custom implementation',
63
- messageType: 'success',
64
- ttl: 2000
65
- }
66
- };
67
- }
68
-
69
- async function customFindContact({ user, authHeader, phoneNumber }) {
70
- // Custom implementation
71
- return [
72
- {
73
- id: 'custom-contact-id',
74
- name: 'Custom Contact',
75
- type: 'Contact',
76
- phone: phoneNumber,
77
- additionalInfo: null
78
- }
79
- ];
80
- }
81
-
82
- // Register interface functions
83
- connectorRegistry.registerConnectorInterface('myCRM', 'createCallLog', customCreateCallLog);
84
- connectorRegistry.registerConnectorInterface('myCRM', 'findContact', customFindContact);
85
-
86
- // Register the base connector
87
- connectorRegistry.registerConnector('myCRM', myCRMConnector);
88
-
89
- // Get composed connector with interfaces
90
- const composedConnector = connectorRegistry.getConnector('myCRM');
91
- ```
92
-
93
- **Interface-Only Connectors (No Base Connector):**
94
-
95
- ```javascript
96
- // Register only interface functions, no base connector
97
- connectorRegistry.registerConnectorInterface('interfaceOnlyCRM', 'createCallLog', customCreateCallLog);
98
- connectorRegistry.registerConnectorInterface('interfaceOnlyCRM', 'findContact', customFindContact);
99
-
100
- // Get interface-only connector
101
- const interfaceOnlyConnector = connectorRegistry.getConnector('interfaceOnlyCRM');
102
- console.log('Interface-only methods:', Object.keys(interfaceOnlyConnector));
103
- // Output: ['createCallLog', 'findContact']
104
-
105
- // Later, you can add a base connector
106
- connectorRegistry.registerConnector('interfaceOnlyCRM', myCRMConnector);
107
- const fullConnector = connectorRegistry.getConnector('interfaceOnlyCRM');
108
- console.log('Full connector methods:', Object.keys(fullConnector));
109
- // Output: ['getAuthType', 'getUserInfo', 'updateCallLog', 'unAuthorize', 'createContact', 'createCallLog', 'findContact']
110
- ```
111
-
112
- ### Advanced Usage with Custom Middleware
113
-
114
- ```javascript
115
- const express = require('express');
116
- const {
117
- createCoreRouter,
118
- createCoreMiddleware,
119
- initializeCore,
120
- connectorRegistry
121
- } = require('@app-connect/core');
122
-
123
- const myCRMConnector = require('./connectors/myCRM');
124
- const manifest = require('./connectors/manifest.json');
125
- // Set manifest
126
- connectorRegistry.setDefaultManifest(manifest);
127
- // Register connectors
128
- connectorRegistry.registerConnector('myCRM', myCRMConnector, manifest);
129
-
130
- // Initialize core services
131
- initializeCore();
132
-
133
- // Create your own Express app
134
- const app = express();
135
-
136
- // Add custom middleware first
137
- app.use(express.static('public'));
138
- app.use('/api/v2', customApiMiddleware);
139
-
140
- // Apply core middleware
141
- const coreMiddleware = createCoreMiddleware();
142
- coreMiddleware.forEach(middleware => app.use(middleware));
143
-
144
- // Add core routes
145
- const coreRouter = createCoreRouter();
146
- app.use('/', coreRouter);
147
-
148
- // Add custom routes
149
- app.get('/my-custom-route', (req, res) => {
150
- res.send('Hello from custom route!');
151
- });
152
- ```
153
-
154
- ## API Reference
155
-
156
- ### Core Functions
157
-
158
- #### `createCoreApp(options)`
159
- Creates a complete Express app with all core functionality.
160
-
161
- **Parameters:**
162
- - `options` (Object, optional): Configuration options
163
- - `skipDatabaseInit` (Boolean): Skip database initialization (default: false)
164
- - `skipAnalyticsInit` (Boolean): Skip analytics initialization (default: false)
165
-
166
- **Returns:** Express application instance
167
-
168
- #### `createCoreRouter()`
169
- Creates an Express router with all core routes.
170
-
171
- **Returns:** Express router instance
172
-
173
- #### `createCoreMiddleware()`
174
- Returns an array of core middleware functions.
175
-
176
- **Returns:** Array of middleware functions
177
-
178
- #### `initializeCore(options)`
179
- Initializes core services (database, analytics).
180
-
181
- **Parameters:**
182
- - `options` (Object, optional): Configuration options
183
- - `skipDatabaseInit` (Boolean): Skip database initialization (default: false)
184
- - `skipAnalyticsInit` (Boolean): Skip analytics initialization (default: false)
185
-
186
- ### Connector Registry
187
-
188
- #### `connectorRegistry.setDefaultManifest(manifest)`
189
- Sets the default manifest for connectors.
190
-
191
- **Parameters:**
192
- - `manifest` (Object): Default manifest
193
-
194
- #### `connectorRegistry.registerConnector(name, connector, manifest)`
195
- Registers a CRM connector.
196
-
197
- **Parameters:**
198
- - `name` (String): Connector name
199
- - `connector` (Object): Connector implementation
200
- - `manifest` (Object, optional): Connector manifest
201
-
202
- #### `connectorRegistry.registerConnectorInterface(platformName, interfaceName, interfaceFunction)`
203
- Registers an interface function for a specific platform that will be composed with the connector at retrieval time.
204
-
205
- **Parameters:**
206
- - `platformName` (String): Platform identifier (e.g., 'pipedrive', 'salesforce')
207
- - `interfaceName` (String): Interface function name (e.g., 'createCallLog', 'findContact')
208
- - `interfaceFunction` (Function): The interface function to register
209
-
210
- **Example:**
211
- ```javascript
212
- async function customCreateCallLog({ user, contactInfo, authHeader, callLog, note }) {
213
- // Custom implementation
214
- return {
215
- logId: 'custom-log-id',
216
- returnMessage: {
217
- message: 'Call logged with custom implementation',
218
- messageType: 'success',
219
- ttl: 2000
220
- }
221
- };
222
- }
223
-
224
- connectorRegistry.registerConnectorInterface('myCRM', 'createCallLog', customCreateCallLog);
225
- ```
226
-
227
- #### `connectorRegistry.getConnector(name)`
228
- Retrieves a registered connector with composed interfaces.
229
-
230
- **Parameters:**
231
- - `name` (String): Connector name
232
-
233
- **Returns:** Composed connector object or interface-only object
234
-
235
- **Behavior:**
236
- - If connector exists and interfaces exist: Returns composed connector with both
237
- - If connector exists but no interfaces: Returns original connector
238
- - If no connector but interfaces exist: Returns object with just interface functions
239
- - If no connector and no interfaces: Throws error
240
-
241
- #### `connectorRegistry.getOriginalConnector(name)`
242
- Retrieves the original connector without any composed interface functions.
243
-
244
- **Parameters:**
245
- - `name` (String): Connector name
246
-
247
- **Returns:** Original connector object
248
-
249
- #### `connectorRegistry.getPlatformInterfaces(platformName)`
250
- Returns a Map of registered interface functions for a platform.
251
-
252
- **Parameters:**
253
- - `platformName` (String): Platform identifier
254
-
255
- **Returns:** Map of interface functions
256
-
257
- #### `connectorRegistry.hasPlatformInterface(platformName, interfaceName)`
258
- Checks if a specific interface function is registered for a platform.
259
-
260
- **Parameters:**
261
- - `platformName` (String): Platform identifier
262
- - `interfaceName` (String): Interface function name
263
-
264
- **Returns:** Boolean indicating if interface exists
265
-
266
- #### `connectorRegistry.unregisterConnectorInterface(platformName, interfaceName)`
267
- Unregisters an interface function for a platform.
268
-
269
- **Parameters:**
270
- - `platformName` (String): Platform identifier
271
- - `interfaceName` (String): Interface function name
272
-
273
- #### `connectorRegistry.getConnectorCapabilities(platformName)`
274
- Gets comprehensive information about an connector including its capabilities and registered interfaces.
275
-
276
- **Parameters:**
277
- - `platformName` (String): Platform identifier
278
-
279
- **Returns:** Promise with Object with connector capabilities information
280
-
281
- ### Exported Components
282
-
283
- #### Handlers
284
- ```javascript
285
- const authHandler = require('@app-connect/core/handlers/auth');
286
- const contactHandler = require('@app-connect/core/handlers/contact');
287
- const logHandler = require('@app-connect/core/handlers/log');
288
- const adminHandler = require('@app-connect/core/handlers/admin');
289
- const userHandler = require('@app-connect/core/handlers/user');
290
- const dispositionHandler = require('@app-connect/core/handlers/disposition');
291
- const managedAuthHandler = require('@app-connect/core/handlers/managedAuth');
292
-
293
- // Available handlers:
294
- // authHandler - Authentication operations
295
- // contactHandler - Contact management
296
- // logHandler - Call/message logging
297
- // adminHandler - Admin operations
298
- // userHandler - User management
299
- // dispositionHandler - Call disposition
300
- // managedAuthHandler - Shared API-key auth field operations
301
- ```
302
-
303
- #### Models
304
- ```javascript
305
- const { UserModel } = require('@app-connect/core/models/userModel');
306
- const { CallLogModel } = require('@app-connect/core/models/callLogModel');
307
- const { MessageLogModel } = require('@app-connect/core/models/messageLogModel');
308
- const { AdminConfigModel } = require('@app-connect/core/models/adminConfigModel');
309
- const { CacheModel } = require('@app-connect/core/models/cacheModel');
310
-
311
- // Available models:
312
- // UserModel - User data model
313
- // CallLogModel - Call log data model
314
- // MessageLogModel - Message log data model
315
- // AdminConfigModel - Admin configuration model
316
- // CacheModel - Cache data model
317
- ```
318
-
319
- #### Utilities
320
- ```javascript
321
- const jwt = require('@app-connect/core/lib/jwt');
322
- const analytics = require('@app-connect/core/lib/analytics');
323
- const util = require('@app-connect/core/lib/util');
324
-
325
- // Available utilities:
326
- // jwt - JWT token management
327
- // analytics - Analytics tracking
328
- // util - General utilities
329
- ```
330
-
331
- ## Core Routes
332
-
333
- The core package provides the following API endpoints:
334
-
335
- ### Authentication
336
- - `GET /authValidation` - Validate user authentication
337
- - `GET /oauth-callback` - OAuth callback handler
338
- - `POST /apiKeyLogin` - API key authentication
339
- - `GET /apiKeyManagedAuthState` - Get managed-auth required-field readiness for API-key logins
340
- - `POST /unAuthorize` - Logout user
341
-
342
- ### Contact Management
343
- - `GET /contact` - Find contacts by phone number
344
- - `POST /contact` - Create new contact
345
- - `GET /custom/contact/search` - Search contacts by name
346
-
347
- ### Call Logging
348
- - `GET /callLog` - Retrieve call logs
349
- - `POST /callLog` - Create call log
350
- - `PATCH /callLog` - Update call log
351
- - `PUT /callDisposition` - Set call disposition
352
- - `POST /messageLog` - Create message log
353
-
354
- ### User Management
355
- - `GET /user/settings` - Get user settings
356
- - `POST /user/settings` - Update user settings
357
- - `GET /user/preloadSettings` - Preload user settings
358
-
359
- ### Admin Operations
360
- - `GET /admin/settings` - Get admin settings
361
- - `POST /admin/settings` - Update admin settings
362
- - `GET /admin/serverLoggingSettings` - Get server logging settings
363
- - `POST /admin/serverLoggingSettings` - Update server logging settings
364
- - `GET /admin/managedAuth` - Get managed-auth field definitions and masked stored values
365
- - `POST /admin/managedAuth` - Update org-level or user-level managed auth field values
366
-
367
- ### System
368
- - `GET /releaseNotes` - Get release notes
369
- - `GET /crmManifest` - Get CRM manifest
370
- - `GET /isAlive` - Health check
371
- - `GET /serverVersionInfo` - Get server version
372
- - `GET /hostname` - Get user hostname
373
- - `GET /userInfoHash` - Get hashed user info
374
-
375
- ## Environment Variables
376
-
377
- The core package uses the following environment variables:
378
-
379
- - `DATABASE_URL` - Database connection string for Sequelize ORM
380
- - `DISABLE_SYNC_DB_TABLE` - Skip database table synchronization
381
- - `OVERRIDE_APP_SERVER` - Override app server URL in manifests
382
- - `HASH_KEY` - Key for hashing user information
383
- - `APP_SERVER_SECRET_KEY` - Server secret key
384
- - `IS_PROD` - Production environment flag
385
- - `DYNAMODB_LOCALHOST` - Local DynamoDB endpoint for development, used for lock cache
386
-
387
- ## Connector Interface Registration Benefits
388
-
389
- ### Key Features
390
-
391
- - **Composition over Mutation**: Interface functions are composed with connectors at retrieval time, preserving the original connector
392
- - **Dynamic Registration**: Register interface functions before or after connector registration
393
- - **Immutability**: Original connector objects remain unchanged
394
- - **Clean Separation**: Interface functions are kept separate from core connector logic
395
- - **Flexibility**: Support for interface-only connectors (no base connector required)
396
-
397
- ### Best Practices
398
-
399
- 1. **Register Required Interfaces**: Register all required interface functions before using the connector
400
- 2. **Use Descriptive Names**: Use clear, descriptive names for interface functions
401
- 3. **Handle Errors**: Implement proper error handling in interface functions
402
- 4. **Test Composed Connectors**: Test the final composed connector to ensure interfaces work correctly
403
- 5. **Document Interfaces**: Document what each interface function does and expects
404
-
405
- ### Use Cases
406
-
407
- - **Extending Existing Connectors**: Add new functionality to existing connectors without modification
408
- - **Progressive Enhancement**: Start with interfaces, add base connector later
409
- - **Testing**: Test interface functions separately from base connectors
410
- - **Modular Development**: Develop interface functions independently
411
- - **Plugin Architecture**: Create pluggable interface functions for different scenarios
412
-
413
- ## Architecture
414
-
415
- ```
416
- Core Package
417
- ├── Handlers (Business Logic)
418
- │ ├── auth.js - Authentication logic
419
- │ ├── contact.js - Contact management
420
- │ ├── log.js - Call/message logging
421
- │ ├── admin.js - Admin operations
422
- │ ├── user.js - User management
423
- │ └── disposition.js - Call disposition
424
- ├── Models (Data Layer)
425
- │ ├── userModel.js
426
- │ ├── callLogModel.js
427
- │ ├── messageLogModel.js
428
- │ ├── adminConfigModel.js
429
- │ └── cacheModel.js
430
- ├── Utils (Utilities)
431
- │ ├── jwt.js - JWT operations
432
- │ ├── analytics.js - Analytics tracking
433
- │ └── util.js - General utilities
434
- ├── Connector Registry
435
- │ └── registry.js - CRM connector management
436
- └── API Layer
437
- ├── createCoreApp() - Complete app setup
438
- ├── createCoreRouter() - Route management
439
- ├── createCoreMiddleware() - Middleware management
440
- └── initializeCore() - Service initialization
441
- ```
1
+ # App Connect Core
2
+
3
+ Core package for RingCentral App Connect project providing modular APIs for CRM integration, authentication, contact management, and call logging.
4
+
5
+ For maintainer-facing internal docs about the package internals, see [`docs/README.md`](./docs/README.md). That docs set covers the non-MCP code under `packages/core`.
6
+
7
+ ## Features
8
+
9
+ - **Modular API Design**: Flexible Express app setup with customizable middleware and routes
10
+ - **CRM Connector Registry**: Centralized connector management for multiple CRM platforms
11
+ - **Authentication**: OAuth and API key authentication support
12
+ - **Contact Management**: Find, create, and manage contacts across CRM platforms
13
+ - **Call Logging**: Comprehensive call and message logging capabilities
14
+ - **Analytics**: Built-in analytics tracking for all operations
15
+ - **Database Integration**: Sequelize.js ORM with automatic table management
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @app-connect/core
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ### Basic Usage
26
+
27
+ ```javascript
28
+ const { createCoreApp, connectorRegistry } = require('@app-connect/core');
29
+ const myCRMConnector = require('./connectors/myCRM');
30
+ const manifest = require('./connectors/manifest.json');
31
+ // Set the default manifest for the connector registry. This ensures that all connectors
32
+ // have access to the necessary configuration and metadata before registration.
33
+ connectorRegistry.setDefaultManifest(manifest);
34
+ // Register your CRM connectors. The default manifest must be set before registration
35
+ // to ensure proper initialization of the connector with the required settings.
36
+ connectorRegistry.registerConnector('myCRM', myCRMConnector, manifest);
37
+
38
+ // Create Express app with all core functionality
39
+ const app = createCoreApp();
40
+
41
+ // Add your custom routes
42
+ app.get('/my-custom-route', (req, res) => {
43
+ res.send('Hello from custom route!');
44
+ });
45
+
46
+ exports.getServer = () => app;
47
+ ```
48
+
49
+ ### Connector Interface Registration
50
+
51
+ The connector registry supports dynamic interface registration, allowing you to extend connector functionality without modifying the original connector:
52
+
53
+ ```javascript
54
+ const { connectorRegistry } = require('@app-connect/core');
55
+
56
+ // Register interface functions for a platform
57
+ async function customCreateCallLog({ user, contactInfo, authHeader, callLog, note }) {
58
+ // Custom implementation
59
+ return {
60
+ logId: 'custom-log-id',
61
+ returnMessage: {
62
+ message: 'Call logged with custom implementation',
63
+ messageType: 'success',
64
+ ttl: 2000
65
+ }
66
+ };
67
+ }
68
+
69
+ async function customFindContact({ user, authHeader, phoneNumber }) {
70
+ // Custom implementation
71
+ return [
72
+ {
73
+ id: 'custom-contact-id',
74
+ name: 'Custom Contact',
75
+ type: 'Contact',
76
+ phone: phoneNumber,
77
+ additionalInfo: null
78
+ }
79
+ ];
80
+ }
81
+
82
+ // Register interface functions
83
+ connectorRegistry.registerConnectorInterface('myCRM', 'createCallLog', customCreateCallLog);
84
+ connectorRegistry.registerConnectorInterface('myCRM', 'findContact', customFindContact);
85
+
86
+ // Register the base connector
87
+ connectorRegistry.registerConnector('myCRM', myCRMConnector);
88
+
89
+ // Get composed connector with interfaces
90
+ const composedConnector = connectorRegistry.getConnector('myCRM');
91
+ ```
92
+
93
+ **Interface-Only Connectors (No Base Connector):**
94
+
95
+ ```javascript
96
+ // Register only interface functions, no base connector
97
+ connectorRegistry.registerConnectorInterface('interfaceOnlyCRM', 'createCallLog', customCreateCallLog);
98
+ connectorRegistry.registerConnectorInterface('interfaceOnlyCRM', 'findContact', customFindContact);
99
+
100
+ // Get interface-only connector
101
+ const interfaceOnlyConnector = connectorRegistry.getConnector('interfaceOnlyCRM');
102
+ console.log('Interface-only methods:', Object.keys(interfaceOnlyConnector));
103
+ // Output: ['createCallLog', 'findContact']
104
+
105
+ // Later, you can add a base connector
106
+ connectorRegistry.registerConnector('interfaceOnlyCRM', myCRMConnector);
107
+ const fullConnector = connectorRegistry.getConnector('interfaceOnlyCRM');
108
+ console.log('Full connector methods:', Object.keys(fullConnector));
109
+ // Output: ['getAuthType', 'getUserInfo', 'updateCallLog', 'unAuthorize', 'createContact', 'createCallLog', 'findContact']
110
+ ```
111
+
112
+ ### Advanced Usage with Custom Middleware
113
+
114
+ ```javascript
115
+ const express = require('express');
116
+ const {
117
+ createCoreRouter,
118
+ createCoreMiddleware,
119
+ initializeCore,
120
+ connectorRegistry
121
+ } = require('@app-connect/core');
122
+
123
+ const myCRMConnector = require('./connectors/myCRM');
124
+ const manifest = require('./connectors/manifest.json');
125
+ // Set manifest
126
+ connectorRegistry.setDefaultManifest(manifest);
127
+ // Register connectors
128
+ connectorRegistry.registerConnector('myCRM', myCRMConnector, manifest);
129
+
130
+ // Initialize core services
131
+ initializeCore();
132
+
133
+ // Create your own Express app
134
+ const app = express();
135
+
136
+ // Add custom middleware first
137
+ app.use(express.static('public'));
138
+ app.use('/api/v2', customApiMiddleware);
139
+
140
+ // Apply core middleware
141
+ const coreMiddleware = createCoreMiddleware();
142
+ coreMiddleware.forEach(middleware => app.use(middleware));
143
+
144
+ // Add core routes
145
+ const coreRouter = createCoreRouter();
146
+ app.use('/', coreRouter);
147
+
148
+ // Add custom routes
149
+ app.get('/my-custom-route', (req, res) => {
150
+ res.send('Hello from custom route!');
151
+ });
152
+ ```
153
+
154
+ ## API Reference
155
+
156
+ ### Core Functions
157
+
158
+ #### `createCoreApp(options)`
159
+ Creates a complete Express app with all core functionality.
160
+
161
+ **Parameters:**
162
+ - `options` (Object, optional): Configuration options
163
+ - `skipDatabaseInit` (Boolean): Skip database initialization (default: false)
164
+ - `skipAnalyticsInit` (Boolean): Skip analytics initialization (default: false)
165
+
166
+ **Returns:** Express application instance
167
+
168
+ #### `createCoreRouter()`
169
+ Creates an Express router with all core routes.
170
+
171
+ **Returns:** Express router instance
172
+
173
+ #### `createCoreMiddleware()`
174
+ Returns an array of core middleware functions.
175
+
176
+ **Returns:** Array of middleware functions
177
+
178
+ #### `initializeCore(options)`
179
+ Initializes core services (database, analytics).
180
+
181
+ **Parameters:**
182
+ - `options` (Object, optional): Configuration options
183
+ - `skipDatabaseInit` (Boolean): Skip database initialization (default: false)
184
+ - `skipAnalyticsInit` (Boolean): Skip analytics initialization (default: false)
185
+
186
+ ### Connector Registry
187
+
188
+ #### `connectorRegistry.setDefaultManifest(manifest)`
189
+ Sets the default manifest for connectors.
190
+
191
+ **Parameters:**
192
+ - `manifest` (Object): Default manifest
193
+
194
+ #### `connectorRegistry.registerConnector(name, connector, manifest)`
195
+ Registers a CRM connector.
196
+
197
+ **Parameters:**
198
+ - `name` (String): Connector name
199
+ - `connector` (Object): Connector implementation
200
+ - `manifest` (Object, optional): Connector manifest
201
+
202
+ #### `connectorRegistry.registerConnectorInterface(platformName, interfaceName, interfaceFunction)`
203
+ Registers an interface function for a specific platform that will be composed with the connector at retrieval time.
204
+
205
+ **Parameters:**
206
+ - `platformName` (String): Platform identifier (e.g., 'pipedrive', 'salesforce')
207
+ - `interfaceName` (String): Interface function name (e.g., 'createCallLog', 'findContact')
208
+ - `interfaceFunction` (Function): The interface function to register
209
+
210
+ **Example:**
211
+ ```javascript
212
+ async function customCreateCallLog({ user, contactInfo, authHeader, callLog, note }) {
213
+ // Custom implementation
214
+ return {
215
+ logId: 'custom-log-id',
216
+ returnMessage: {
217
+ message: 'Call logged with custom implementation',
218
+ messageType: 'success',
219
+ ttl: 2000
220
+ }
221
+ };
222
+ }
223
+
224
+ connectorRegistry.registerConnectorInterface('myCRM', 'createCallLog', customCreateCallLog);
225
+ ```
226
+
227
+ #### `connectorRegistry.getConnector(name)`
228
+ Retrieves a registered connector with composed interfaces.
229
+
230
+ **Parameters:**
231
+ - `name` (String): Connector name
232
+
233
+ **Returns:** Composed connector object or interface-only object
234
+
235
+ **Behavior:**
236
+ - If connector exists and interfaces exist: Returns composed connector with both
237
+ - If connector exists but no interfaces: Returns original connector
238
+ - If no connector but interfaces exist: Returns object with just interface functions
239
+ - If no connector and no interfaces: Throws error
240
+
241
+ #### `connectorRegistry.getOriginalConnector(name)`
242
+ Retrieves the original connector without any composed interface functions.
243
+
244
+ **Parameters:**
245
+ - `name` (String): Connector name
246
+
247
+ **Returns:** Original connector object
248
+
249
+ #### `connectorRegistry.getPlatformInterfaces(platformName)`
250
+ Returns a Map of registered interface functions for a platform.
251
+
252
+ **Parameters:**
253
+ - `platformName` (String): Platform identifier
254
+
255
+ **Returns:** Map of interface functions
256
+
257
+ #### `connectorRegistry.hasPlatformInterface(platformName, interfaceName)`
258
+ Checks if a specific interface function is registered for a platform.
259
+
260
+ **Parameters:**
261
+ - `platformName` (String): Platform identifier
262
+ - `interfaceName` (String): Interface function name
263
+
264
+ **Returns:** Boolean indicating if interface exists
265
+
266
+ #### `connectorRegistry.unregisterConnectorInterface(platformName, interfaceName)`
267
+ Unregisters an interface function for a platform.
268
+
269
+ **Parameters:**
270
+ - `platformName` (String): Platform identifier
271
+ - `interfaceName` (String): Interface function name
272
+
273
+ #### `connectorRegistry.getConnectorCapabilities(platformName)`
274
+ Gets comprehensive information about an connector including its capabilities and registered interfaces.
275
+
276
+ **Parameters:**
277
+ - `platformName` (String): Platform identifier
278
+
279
+ **Returns:** Promise with Object with connector capabilities information
280
+
281
+ ### Exported Components
282
+
283
+ #### Handlers
284
+ ```javascript
285
+ const authHandler = require('@app-connect/core/handlers/auth');
286
+ const contactHandler = require('@app-connect/core/handlers/contact');
287
+ const logHandler = require('@app-connect/core/handlers/log');
288
+ const adminHandler = require('@app-connect/core/handlers/admin');
289
+ const userHandler = require('@app-connect/core/handlers/user');
290
+ const dispositionHandler = require('@app-connect/core/handlers/disposition');
291
+ const managedAuthHandler = require('@app-connect/core/handlers/managedAuth');
292
+
293
+ // Available handlers:
294
+ // authHandler - Authentication operations
295
+ // contactHandler - Contact management
296
+ // logHandler - Call/message logging
297
+ // adminHandler - Admin operations
298
+ // userHandler - User management
299
+ // dispositionHandler - Call disposition
300
+ // managedAuthHandler - Shared API-key auth field operations
301
+ ```
302
+
303
+ #### Models
304
+ ```javascript
305
+ const { UserModel } = require('@app-connect/core/models/userModel');
306
+ const { CallLogModel } = require('@app-connect/core/models/callLogModel');
307
+ const { MessageLogModel } = require('@app-connect/core/models/messageLogModel');
308
+ const { AdminConfigModel } = require('@app-connect/core/models/adminConfigModel');
309
+ const { CacheModel } = require('@app-connect/core/models/cacheModel');
310
+
311
+ // Available models:
312
+ // UserModel - User data model
313
+ // CallLogModel - Call log data model
314
+ // MessageLogModel - Message log data model
315
+ // AdminConfigModel - Admin configuration model
316
+ // CacheModel - Cache data model
317
+ ```
318
+
319
+ #### Utilities
320
+ ```javascript
321
+ const jwt = require('@app-connect/core/lib/jwt');
322
+ const analytics = require('@app-connect/core/lib/analytics');
323
+ const util = require('@app-connect/core/lib/util');
324
+
325
+ // Available utilities:
326
+ // jwt - JWT token management
327
+ // analytics - Analytics tracking
328
+ // util - General utilities
329
+ ```
330
+
331
+ ## Core Routes
332
+
333
+ The core package provides the following API endpoints:
334
+
335
+ ### Authentication
336
+ - `GET /authValidation` - Validate user authentication
337
+ - `GET /oauth-callback` - OAuth callback handler
338
+ - `POST /apiKeyLogin` - API key authentication
339
+ - `GET /apiKeyManagedAuthState` - Get managed-auth required-field readiness for API-key logins
340
+ - `POST /unAuthorize` - Logout user
341
+
342
+ ### Contact Management
343
+ - `GET /contact` - Find contacts by phone number
344
+ - `POST /contact` - Create new contact
345
+ - `GET /custom/contact/search` - Search contacts by name
346
+
347
+ ### Call Logging
348
+ - `GET /callLog` - Retrieve call logs
349
+ - `POST /callLog` - Create call log
350
+ - `PATCH /callLog` - Update call log
351
+ - `PUT /callDisposition` - Set call disposition
352
+ - `POST /messageLog` - Create message log
353
+
354
+ ### User Management
355
+ - `GET /user/settings` - Get user settings
356
+ - `POST /user/settings` - Update user settings
357
+ - `GET /user/preloadSettings` - Preload user settings
358
+
359
+ ### Admin Operations
360
+ - `GET /admin/settings` - Get admin settings
361
+ - `POST /admin/settings` - Update admin settings
362
+ - `GET /admin/serverLoggingSettings` - Get server logging settings
363
+ - `POST /admin/serverLoggingSettings` - Update server logging settings
364
+ - `GET /admin/managedAuth` - Get managed-auth field definitions and masked stored values
365
+ - `POST /admin/managedAuth` - Update org-level or user-level managed auth field values
366
+
367
+ ### System
368
+ - `GET /releaseNotes` - Get release notes
369
+ - `GET /crmManifest` - Get CRM manifest
370
+ - `GET /isAlive` - Health check
371
+ - `GET /serverVersionInfo` - Get server version
372
+ - `GET /hostname` - Get user hostname
373
+ - `GET /userInfoHash` - Get hashed user info
374
+
375
+ ## Environment Variables
376
+
377
+ The core package uses the following environment variables:
378
+
379
+ - `DATABASE_URL` - Database connection string for Sequelize ORM
380
+ - `DISABLE_SYNC_DB_TABLE` - Skip database table synchronization
381
+ - `OVERRIDE_APP_SERVER` - Override app server URL in manifests
382
+ - `HASH_KEY` - Key for hashing user information
383
+ - `APP_SERVER_SECRET_KEY` - Server secret key
384
+ - `IS_PROD` - Production environment flag
385
+ - `DYNAMODB_LOCALHOST` - Local DynamoDB endpoint for development, used for lock cache
386
+
387
+ ## Connector Interface Registration Benefits
388
+
389
+ ### Key Features
390
+
391
+ - **Composition over Mutation**: Interface functions are composed with connectors at retrieval time, preserving the original connector
392
+ - **Dynamic Registration**: Register interface functions before or after connector registration
393
+ - **Immutability**: Original connector objects remain unchanged
394
+ - **Clean Separation**: Interface functions are kept separate from core connector logic
395
+ - **Flexibility**: Support for interface-only connectors (no base connector required)
396
+
397
+ ### Best Practices
398
+
399
+ 1. **Register Required Interfaces**: Register all required interface functions before using the connector
400
+ 2. **Use Descriptive Names**: Use clear, descriptive names for interface functions
401
+ 3. **Handle Errors**: Implement proper error handling in interface functions
402
+ 4. **Test Composed Connectors**: Test the final composed connector to ensure interfaces work correctly
403
+ 5. **Document Interfaces**: Document what each interface function does and expects
404
+
405
+ ### Use Cases
406
+
407
+ - **Extending Existing Connectors**: Add new functionality to existing connectors without modification
408
+ - **Progressive Enhancement**: Start with interfaces, add base connector later
409
+ - **Testing**: Test interface functions separately from base connectors
410
+ - **Modular Development**: Develop interface functions independently
411
+ - **Plugin Architecture**: Create pluggable interface functions for different scenarios
412
+
413
+ ## Architecture
414
+
415
+ ```
416
+ Core Package
417
+ ├── Handlers (Business Logic)
418
+ │ ├── auth.js - Authentication logic
419
+ │ ├── contact.js - Contact management
420
+ │ ├── log.js - Call/message logging
421
+ │ ├── admin.js - Admin operations
422
+ │ ├── user.js - User management
423
+ │ └── disposition.js - Call disposition
424
+ ├── Models (Data Layer)
425
+ │ ├── userModel.js
426
+ │ ├── callLogModel.js
427
+ │ ├── messageLogModel.js
428
+ │ ├── adminConfigModel.js
429
+ │ └── cacheModel.js
430
+ ├── Utils (Utilities)
431
+ │ ├── jwt.js - JWT operations
432
+ │ ├── analytics.js - Analytics tracking
433
+ │ └── util.js - General utilities
434
+ ├── Connector Registry
435
+ │ └── registry.js - CRM connector management
436
+ └── API Layer
437
+ ├── createCoreApp() - Complete app setup
438
+ ├── createCoreRouter() - Route management
439
+ ├── createCoreMiddleware() - Middleware management
440
+ └── initializeCore() - Service initialization
441
+ ```