@app-connect/core 1.7.37 → 1.7.38
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 +17 -16
- package/dist/connector/developerPortal.d.ts +6 -0
- package/{connector → dist/connector}/developerPortal.js +29 -12
- package/dist/connector/mock.d.ts +1 -0
- package/{connector → dist/connector}/mock.js +33 -17
- package/dist/connector/proxy/engine.d.ts +10 -0
- package/dist/connector/proxy/engine.js +222 -0
- package/dist/connector/proxy/index.d.ts +5 -0
- package/dist/connector/proxy/index.js +511 -0
- package/dist/connector/registry.d.ts +1 -0
- package/dist/connector/registry.js +243 -0
- package/dist/handlers/admin.d.ts +1 -0
- package/{handlers → dist/handlers}/admin.js +137 -78
- package/dist/handlers/appointment.d.ts +9 -0
- package/{handlers → dist/handlers}/appointment.js +58 -29
- package/dist/handlers/auth.d.ts +9 -0
- package/{handlers → dist/handlers}/auth.js +68 -40
- package/dist/handlers/calldown.d.ts +10 -0
- package/dist/handlers/calldown.js +134 -0
- package/dist/handlers/contact.d.ts +1 -0
- package/{handlers → dist/handlers}/contact.js +61 -39
- package/dist/handlers/disposition.d.ts +1 -0
- package/{handlers → dist/handlers}/disposition.js +20 -10
- package/dist/handlers/log.d.ts +1 -0
- package/{handlers → dist/handlers}/log.js +91 -124
- package/dist/handlers/managedAuth.d.ts +1 -0
- package/{handlers → dist/handlers}/managedAuth.js +134 -61
- package/dist/handlers/managedOAuth.d.ts +13 -0
- package/{handlers → dist/handlers}/managedOAuth.js +102 -30
- package/dist/handlers/plugin.d.ts +1 -0
- package/{handlers → dist/handlers}/plugin.js +59 -27
- package/dist/handlers/user.d.ts +1 -0
- package/{handlers → dist/handlers}/user.js +45 -27
- package/dist/index.d.ts +1 -0
- package/{index.js → dist/index.js} +538 -449
- package/dist/jest.config.d.ts +1 -0
- package/dist/jest.config.js +65 -0
- package/dist/lib/analytics.d.ts +4 -0
- package/{lib → dist/lib}/analytics.js +8 -6
- package/dist/lib/authSession.d.ts +5 -0
- package/{lib → dist/lib}/authSession.js +15 -43
- package/dist/lib/cacheCleanup.d.ts +4 -0
- package/{lib → dist/lib}/cacheCleanup.js +5 -17
- package/dist/lib/callLogComposer.d.ts +109 -0
- package/{lib → dist/lib}/callLogComposer.js +157 -197
- package/dist/lib/callLogLookup.d.ts +6 -0
- package/{lib → dist/lib}/callLogLookup.js +12 -34
- package/dist/lib/constants.d.ts +6 -0
- package/dist/lib/constants.js +9 -0
- package/dist/lib/debugTracer.d.ts +17 -0
- package/{lib → dist/lib}/debugTracer.js +7 -83
- package/dist/lib/encode.d.ts +3 -0
- package/dist/lib/encode.js +50 -0
- package/dist/lib/errorHandler.d.ts +7 -0
- package/dist/lib/errorHandler.js +161 -0
- package/dist/lib/generalErrorMessage.d.ts +7 -0
- package/{lib → dist/lib}/generalErrorMessage.js +6 -6
- package/dist/lib/jwt.d.ts +4 -0
- package/dist/lib/jwt.js +18 -0
- package/dist/lib/logger.d.ts +24 -0
- package/dist/lib/logger.js +126 -0
- package/dist/lib/migrateCallLogsSchema.d.ts +32 -0
- package/{lib → dist/lib}/migrateCallLogsSchema.js +75 -160
- package/dist/lib/oauth.d.ts +4 -0
- package/{lib → dist/lib}/oauth.js +157 -160
- package/dist/lib/ringcentral.d.ts +24 -0
- package/dist/lib/ringcentral.js +226 -0
- package/dist/lib/s3ErrorLogReport.d.ts +4 -0
- package/{lib → dist/lib}/s3ErrorLogReport.js +11 -23
- package/dist/lib/sharedSMSComposer.d.ts +7 -0
- package/{lib → dist/lib}/sharedSMSComposer.js +21 -107
- package/dist/lib/util.d.ts +7 -0
- package/{lib → dist/lib}/util.js +9 -20
- package/dist/mcp/lib/oauthError.d.ts +1 -0
- package/dist/mcp/lib/oauthError.js +25 -0
- package/dist/mcp/lib/validator.d.ts +1 -0
- package/{mcp → dist/mcp}/lib/validator.js +16 -20
- package/dist/mcp/lib/widgetSessionToken.d.ts +1 -0
- package/dist/mcp/lib/widgetSessionToken.js +46 -0
- package/dist/mcp/mcpHandler.d.ts +8 -0
- package/{mcp → dist/mcp}/mcpHandler.js +98 -88
- package/dist/mcp/tools/cancelAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/cancelAppointment.js +7 -16
- package/dist/mcp/tools/checkAuthStatus.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/checkAuthStatus.js +21 -14
- package/dist/mcp/tools/confirmAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/confirmAppointment.js +7 -16
- package/dist/mcp/tools/createAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createAppointment.js +7 -19
- package/dist/mcp/tools/createCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createCallLog.js +18 -29
- package/dist/mcp/tools/createContact.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createContact.js +8 -20
- package/dist/mcp/tools/createMessageLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createMessageLog.js +14 -26
- package/dist/mcp/tools/doAuth.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/doAuth.js +17 -13
- package/dist/mcp/tools/findContactByName.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/findContactByName.js +9 -15
- package/dist/mcp/tools/findContactByPhone.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/findContactByPhone.js +8 -15
- package/dist/mcp/tools/getCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getCallLog.js +12 -21
- package/dist/mcp/tools/getGoogleFilePicker.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getGoogleFilePicker.js +9 -18
- package/dist/mcp/tools/getHelp.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getHelp.js +5 -6
- package/dist/mcp/tools/getPublicConnectors.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getPublicConnectors.js +19 -18
- package/dist/mcp/tools/getSessionInfo.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getSessionInfo.js +10 -16
- package/dist/mcp/tools/index.d.ts +8 -0
- package/dist/mcp/tools/index.js +50 -0
- package/dist/mcp/tools/listAppointments.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/listAppointments.js +7 -19
- package/dist/mcp/tools/logout.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/logout.js +16 -14
- package/dist/mcp/tools/rcGetCallLogs.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/rcGetCallLogs.js +10 -8
- package/dist/mcp/tools/updateAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/updateAppointment.js +17 -22
- package/dist/mcp/tools/updateCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/updateCallLog.js +16 -26
- package/dist/models/accountDataModel.d.ts +3 -0
- package/dist/models/accountDataModel.js +39 -0
- package/dist/models/adminConfigModel.d.ts +2 -0
- package/dist/models/adminConfigModel.js +39 -0
- package/dist/models/cacheModel.d.ts +2 -0
- package/{models → dist/models}/cacheModel.js +7 -3
- package/dist/models/callDownListModel.d.ts +2 -0
- package/{models → dist/models}/callDownListModel.js +8 -4
- package/dist/models/callLogModel.d.ts +2 -0
- package/dist/models/callLogModel.js +43 -0
- package/dist/models/dynamo/connectorSchema.d.ts +2 -0
- package/dist/models/dynamo/connectorSchema.js +141 -0
- package/dist/models/dynamo/lockSchema.d.ts +2 -0
- package/{models → dist/models}/dynamo/lockSchema.js +5 -7
- package/dist/models/dynamo/noteCacheSchema.d.ts +2 -0
- package/{models → dist/models}/dynamo/noteCacheSchema.js +4 -6
- package/dist/models/llmSessionModel.d.ts +2 -0
- package/dist/models/llmSessionModel.js +21 -0
- package/dist/models/messageLogModel.d.ts +2 -0
- package/{models → dist/models}/messageLogModel.js +8 -4
- package/dist/models/sequelize.d.ts +2 -0
- package/dist/models/sequelize.js +68 -0
- package/dist/models/userModel.d.ts +2 -0
- package/dist/models/userModel.js +49 -0
- package/dist/package.json +100 -0
- package/dist/releaseNotes.json +1222 -0
- package/dist/tsconfig.json +14 -0
- package/dist/types/admin.d.ts +141 -0
- package/dist/types/analytics.d.ts +14 -0
- package/dist/types/appointment.d.ts +50 -0
- package/dist/types/auth.d.ts +137 -0
- package/dist/types/authSession.d.ts +35 -0
- package/dist/types/cacheCleanup.d.ts +12 -0
- package/dist/types/calldown.d.ts +54 -0
- package/dist/types/common.d.ts +46 -0
- package/dist/types/connector.d.ts +165 -0
- package/dist/types/contact.d.ts +125 -0
- package/dist/types/errorHandler.d.ts +60 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/types/json.d.ts +9 -0
- package/dist/types/jwt.d.ts +8 -0
- package/dist/types/logging.d.ts +224 -0
- package/dist/types/managedAuth.d.ts +114 -0
- package/dist/types/managedOAuth.d.ts +59 -0
- package/dist/types/manifest.d.ts +120 -0
- package/dist/types/migration.d.ts +15 -0
- package/dist/types/plugin.d.ts +74 -0
- package/dist/types/ringcentral.d.ts +61 -0
- package/dist/types/s3ErrorLogReport.d.ts +16 -0
- package/dist/types/sharedSMSComposer.d.ts +105 -0
- package/dist/types/user.d.ts +46 -0
- package/dist/types/util.d.ts +7 -0
- package/package.json +34 -6
- package/releaseNotes.json +8 -0
- package/.env.test +0 -5
- package/connector/proxy/engine.js +0 -165
- package/connector/proxy/index.js +0 -500
- package/connector/registry.js +0 -252
- package/docs/README.md +0 -50
- package/docs/architecture.md +0 -94
- package/docs/connectors.md +0 -116
- package/docs/handlers.md +0 -128
- package/docs/libraries.md +0 -98
- package/docs/models.md +0 -146
- package/docs/routes.md +0 -119
- package/docs/tests.md +0 -73
- package/handlers/calldown.js +0 -99
- package/jest.config.js +0 -57
- package/lib/constants.js +0 -9
- package/lib/encode.js +0 -30
- package/lib/errorHandler.js +0 -218
- package/lib/jwt.js +0 -18
- package/lib/logger.js +0 -190
- package/lib/ringcentral.js +0 -267
- package/mcp/README.md +0 -420
- package/mcp/tools/index.js +0 -51
- package/mcp/ui/App/App.tsx +0 -358
- package/mcp/ui/App/components/AuthInfoForm.tsx +0 -113
- package/mcp/ui/App/components/AuthSuccess.tsx +0 -22
- package/mcp/ui/App/components/ConnectorList.tsx +0 -82
- package/mcp/ui/App/components/DebugPanel.tsx +0 -43
- package/mcp/ui/App/components/OAuthConnect.tsx +0 -270
- package/mcp/ui/App/lib/callTool.ts +0 -130
- package/mcp/ui/App/lib/debugLog.ts +0 -41
- package/mcp/ui/App/lib/developerPortal.ts +0 -111
- package/mcp/ui/App/main.css +0 -6
- package/mcp/ui/App/root.tsx +0 -13
- package/mcp/ui/dist/index.html +0 -53
- package/mcp/ui/vite.config.ts +0 -16
- package/models/accountDataModel.js +0 -34
- package/models/adminConfigModel.js +0 -35
- package/models/callLogModel.js +0 -39
- package/models/dynamo/connectorSchema.js +0 -146
- package/models/llmSessionModel.js +0 -17
- package/models/sequelize.js +0 -17
- package/models/userModel.js +0 -45
- package/test/connector/developerPortal.test.js +0 -166
- package/test/connector/mock.test.js +0 -131
- package/test/connector/proxy/engine.test.js +0 -211
- package/test/connector/proxy/index.test.js +0 -525
- package/test/connector/proxy/sample.json +0 -162
- package/test/connector/registry.test.js +0 -416
- package/test/handlers/admin.test.js +0 -960
- package/test/handlers/appointment.test.js +0 -260
- package/test/handlers/auth.test.js +0 -1096
- package/test/handlers/calldown.test.js +0 -310
- package/test/handlers/contact.test.js +0 -1014
- package/test/handlers/disposition.test.js +0 -396
- package/test/handlers/log.test.js +0 -1847
- package/test/handlers/managedAuth.test.js +0 -458
- package/test/handlers/managedOAuth.test.js +0 -262
- package/test/handlers/plugin.test.js +0 -429
- package/test/handlers/user.test.js +0 -381
- package/test/index.test.js +0 -301
- package/test/lib/analytics.test.js +0 -146
- package/test/lib/authSession.test.js +0 -173
- package/test/lib/cacheCleanup.test.js +0 -127
- package/test/lib/callLogComposer.test.js +0 -1231
- package/test/lib/debugTracer.test.js +0 -328
- package/test/lib/encode.test.js +0 -59
- package/test/lib/errorHandler.test.js +0 -246
- package/test/lib/generalErrorMessage.test.js +0 -82
- package/test/lib/jwt.test.js +0 -176
- package/test/lib/logger.test.js +0 -206
- package/test/lib/oauth.test.js +0 -359
- package/test/lib/ringcentral.test.js +0 -467
- package/test/lib/s3ErrorLogReport.test.js +0 -187
- package/test/lib/sharedSMSComposer.test.js +0 -1084
- package/test/lib/util.test.js +0 -329
- package/test/mcp/mcpHandler.test.js +0 -73
- package/test/mcp/mcpHandlerMore.test.js +0 -384
- package/test/mcp/tools/appointmentTools.test.js +0 -362
- package/test/mcp/tools/checkAuthStatus.test.js +0 -83
- package/test/mcp/tools/createCallLog.test.js +0 -436
- package/test/mcp/tools/createContact.test.js +0 -58
- package/test/mcp/tools/createMessageLog.test.js +0 -595
- package/test/mcp/tools/doAuth.test.js +0 -113
- package/test/mcp/tools/findContactByName.test.js +0 -275
- package/test/mcp/tools/findContactByPhone.test.js +0 -296
- package/test/mcp/tools/getCallLog.test.js +0 -298
- package/test/mcp/tools/getGoogleFilePicker.test.js +0 -281
- package/test/mcp/tools/getPublicConnectors.test.js +0 -107
- package/test/mcp/tools/getSessionInfo.test.js +0 -127
- package/test/mcp/tools/logout.test.js +0 -233
- package/test/mcp/tools/rcGetCallLogs.test.js +0 -56
- package/test/mcp/tools/updateCallLog.test.js +0 -360
- package/test/models/accountDataModel.test.js +0 -98
- package/test/models/callDownListModel.test.js +0 -125
- package/test/models/dynamo/connectorSchema.test.js +0 -189
- package/test/models/dynamo/lockSchema.test.js +0 -37
- package/test/models/dynamo/noteCacheSchema.test.js +0 -45
- package/test/models/llmSessionModel.test.js +0 -91
- package/test/models/models.test.js +0 -660
- package/test/routes/calldownRoutes.test.js +0 -224
- package/test/routes/coreRouterBroadRoutes.test.js +0 -855
- package/test/routes/dispositionRoutes.test.js +0 -192
- package/test/routes/managedAuthRoutes.test.js +0 -386
- package/test/routes/pluginRoutes.test.js +0 -262
- package/test/setup.js +0 -178
- /package/{mcp → dist/mcp}/ui/index.html +0 -0
- /package/{mcp → dist/mcp}/ui/package-lock.json +0 -0
- /package/{mcp → dist/mcp}/ui/package.json +0 -0
- /package/{mcp → dist/mcp}/ui/tsconfig.json +0 -0
package/lib/errorHandler.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
const logger = require('./logger');
|
|
2
|
-
const errorMessage = require('./generalErrorMessage');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Centralized error handler for API operations
|
|
6
|
-
* Handles common error patterns (rate limits, auth errors, etc.)
|
|
7
|
-
*
|
|
8
|
-
* @param {Error} error - The error object
|
|
9
|
-
* @param {string} platform - Platform name (clio, bullhorn, etc.)
|
|
10
|
-
* @param {string} operation - Operation name (createCallLog, findContact, etc.)
|
|
11
|
-
* @param {Object} additionalContext - Additional logging context
|
|
12
|
-
* @returns {Object} Standardized error response
|
|
13
|
-
*/
|
|
14
|
-
function handleApiError(error, platform, operation, additionalContext = {}) {
|
|
15
|
-
const statusCode = error.response?.status ?? 'unknown';
|
|
16
|
-
|
|
17
|
-
// Log the error with full context
|
|
18
|
-
logger.error(`${operation} failed for platform ${platform}`, {
|
|
19
|
-
platform,
|
|
20
|
-
operation,
|
|
21
|
-
statusCode,
|
|
22
|
-
errorMessage: error.message,
|
|
23
|
-
errorStack: error.stack,
|
|
24
|
-
errorResponse: error.response?.data,
|
|
25
|
-
...additionalContext,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
// Rate limit error (429)
|
|
29
|
-
if (statusCode === 429) {
|
|
30
|
-
return {
|
|
31
|
-
successful: false,
|
|
32
|
-
returnMessage: errorMessage.rateLimitErrorMessage({ platform }),
|
|
33
|
-
extraDataTracking: {
|
|
34
|
-
statusCode,
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Authorization/Authentication errors (400-409)
|
|
40
|
-
if (statusCode >= 400 && statusCode < 410) {
|
|
41
|
-
return {
|
|
42
|
-
successful: false,
|
|
43
|
-
returnMessage: errorMessage.authorizationErrorMessage({ platform }),
|
|
44
|
-
extraDataTracking: {
|
|
45
|
-
statusCode,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Get operation-specific error message
|
|
51
|
-
const defaultErrorMessage = getOperationErrorMessage(operation, platform);
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
successful: false,
|
|
55
|
-
returnMessage: defaultErrorMessage,
|
|
56
|
-
extraDataTracking: {
|
|
57
|
-
statusCode,
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Get operation-specific error message
|
|
64
|
-
* @param {string} operation - Operation name
|
|
65
|
-
* @param {string} platform - Platform name
|
|
66
|
-
* @returns {Object} Error message object
|
|
67
|
-
*/
|
|
68
|
-
function getOperationErrorMessage(operation, platform) {
|
|
69
|
-
const operationMessages = {
|
|
70
|
-
createCallLog: {
|
|
71
|
-
message: 'Error creating call log',
|
|
72
|
-
details: ['Please check if your account has permission to CREATE logs.'],
|
|
73
|
-
},
|
|
74
|
-
updateCallLog: {
|
|
75
|
-
message: 'Error updating call log',
|
|
76
|
-
details: [`Please check if the log entity still exists on ${platform} and your account has permission to EDIT logs.`],
|
|
77
|
-
},
|
|
78
|
-
getCallLog: {
|
|
79
|
-
message: 'Error getting call log',
|
|
80
|
-
details: ['Please check if your account has permission to READ logs.'],
|
|
81
|
-
},
|
|
82
|
-
createMessageLog: {
|
|
83
|
-
message: 'Error creating message log',
|
|
84
|
-
details: ['Please check if your account has permission to CREATE logs.'],
|
|
85
|
-
},
|
|
86
|
-
updateMessageLog: {
|
|
87
|
-
message: 'Error updating message log',
|
|
88
|
-
details: [`Please check if the log entity still exists on ${platform} and your account has permission to EDIT logs.`],
|
|
89
|
-
},
|
|
90
|
-
findContact: {
|
|
91
|
-
message: 'Error finding contact',
|
|
92
|
-
details: ['Please check if your account has permission to GET contacts.'],
|
|
93
|
-
},
|
|
94
|
-
createContact: {
|
|
95
|
-
message: 'Error creating contact',
|
|
96
|
-
details: ['Please check if your account has permission to CREATE contacts.'],
|
|
97
|
-
},
|
|
98
|
-
findContactWithName: {
|
|
99
|
-
message: 'Error searching contacts',
|
|
100
|
-
details: ['Please check if your account has permission to GET contacts.'],
|
|
101
|
-
},
|
|
102
|
-
createAppointment: {
|
|
103
|
-
message: 'Error creating appointment',
|
|
104
|
-
details: ['Please check if your account has permission to CREATE appointments. or All attendees have email address.'],
|
|
105
|
-
},
|
|
106
|
-
updateAppointment: {
|
|
107
|
-
message: 'Error updating appointment',
|
|
108
|
-
details: [`Please check if the appointment entity still exists on ${platform} and your account has permission to EDIT appointments. or All attendees have email address.`],
|
|
109
|
-
},
|
|
110
|
-
getAppointment: {
|
|
111
|
-
message: 'Error getting appointment',
|
|
112
|
-
details: ['Please check if your account has permission to GET appointments.'],
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const operationInfo = operationMessages[operation] || {
|
|
117
|
-
message: `Error performing ${operation}`,
|
|
118
|
-
details: ['Please check if your account has the necessary permissions.'],
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
message: operationInfo.message,
|
|
123
|
-
messageType: 'warning',
|
|
124
|
-
details: [
|
|
125
|
-
{
|
|
126
|
-
title: 'Details',
|
|
127
|
-
items: operationInfo.details.map((detail, index) => ({
|
|
128
|
-
id: index + 1,
|
|
129
|
-
type: 'text',
|
|
130
|
-
text: detail,
|
|
131
|
-
})),
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
ttl: 5000,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Handle database errors
|
|
140
|
-
* @param {Error} error - The error object
|
|
141
|
-
* @param {string} operation - Database operation name
|
|
142
|
-
* @param {Object} context - Additional context
|
|
143
|
-
*/
|
|
144
|
-
function handleDatabaseError(error, operation, context = {}) {
|
|
145
|
-
logger.error(`Database operation failed: ${operation}`, {
|
|
146
|
-
operation,
|
|
147
|
-
errorMessage: error.message,
|
|
148
|
-
errorStack: error.stack,
|
|
149
|
-
...context,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
successful: false,
|
|
154
|
-
returnMessage: {
|
|
155
|
-
message: 'Database operation failed',
|
|
156
|
-
messageType: 'warning',
|
|
157
|
-
ttl: 5000,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Wrap async route handlers to catch errors
|
|
164
|
-
* Prevents unhandled promise rejections
|
|
165
|
-
* @param {Function} fn - Async route handler
|
|
166
|
-
* @returns {Function} Wrapped handler
|
|
167
|
-
*/
|
|
168
|
-
function asyncHandler(fn) {
|
|
169
|
-
return (req, res, next) => {
|
|
170
|
-
Promise.resolve(fn(req, res, next)).catch(next);
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Express error handling middleware
|
|
176
|
-
* Should be added after all routes
|
|
177
|
-
* @param {Error} err - Error object
|
|
178
|
-
* @param {Object} req - Express request
|
|
179
|
-
* @param {Object} res - Express response
|
|
180
|
-
* @param {Function} next - Express next function (required by Express signature)
|
|
181
|
-
*/
|
|
182
|
-
function errorMiddleware(err, req, res, next) { // eslint-disable-line no-unused-vars
|
|
183
|
-
const platform = req.platform || req.query?.platform || 'unknown';
|
|
184
|
-
const operation = req.route?.path || 'unknown';
|
|
185
|
-
|
|
186
|
-
logger.error('Request failed', {
|
|
187
|
-
platform,
|
|
188
|
-
operation,
|
|
189
|
-
method: req.method,
|
|
190
|
-
path: req.path,
|
|
191
|
-
statusCode: err.statusCode || 500,
|
|
192
|
-
error: err,
|
|
193
|
-
correlationId: req.correlationId,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Don't expose internal errors in production
|
|
197
|
-
const message = process.env.NODE_ENV === 'production'
|
|
198
|
-
? 'An internal error occurred'
|
|
199
|
-
: err.message;
|
|
200
|
-
|
|
201
|
-
res.status(err.statusCode || 500).json({
|
|
202
|
-
successful: false,
|
|
203
|
-
returnMessage: {
|
|
204
|
-
message,
|
|
205
|
-
messageType: 'error',
|
|
206
|
-
ttl: 5000,
|
|
207
|
-
},
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
module.exports = {
|
|
212
|
-
handleApiError,
|
|
213
|
-
handleDatabaseError,
|
|
214
|
-
asyncHandler,
|
|
215
|
-
errorMiddleware,
|
|
216
|
-
getOperationErrorMessage,
|
|
217
|
-
};
|
|
218
|
-
|
package/lib/jwt.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const { sign, verify } = require('jsonwebtoken');
|
|
2
|
-
const logger = require('./logger');
|
|
3
|
-
|
|
4
|
-
function generateJwt(data) {
|
|
5
|
-
return sign(data, process.env.APP_SERVER_SECRET_KEY, { expiresIn: '2w' })
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function decodeJwt(token) {
|
|
9
|
-
try {
|
|
10
|
-
return verify(token, process.env.APP_SERVER_SECRET_KEY);
|
|
11
|
-
} catch (e) {
|
|
12
|
-
logger.error('Error decoding JWT', { stack: e.stack });
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
exports.generateJwt = generateJwt;
|
|
18
|
-
exports.decodeJwt = decodeJwt;
|
package/lib/logger.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
const util = require('util');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Logger levels
|
|
5
|
-
*/
|
|
6
|
-
const LOG_LEVELS = {
|
|
7
|
-
ERROR: 0,
|
|
8
|
-
WARN: 1,
|
|
9
|
-
INFO: 2,
|
|
10
|
-
DEBUG: 3,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Color codes for terminal output
|
|
15
|
-
*/
|
|
16
|
-
const COLORS = {
|
|
17
|
-
ERROR: '\x1b[31m', // Red
|
|
18
|
-
WARN: '\x1b[33m', // Yellow
|
|
19
|
-
INFO: '\x1b[36m', // Cyan
|
|
20
|
-
DEBUG: '\x1b[90m', // Gray
|
|
21
|
-
RESET: '\x1b[0m',
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
class Logger {
|
|
25
|
-
constructor(options = {}) {
|
|
26
|
-
this.level = this._getLogLevel(options.level || process.env.LOG_LEVEL || 'INFO');
|
|
27
|
-
this.isProd = process.env.NODE_ENV === 'production';
|
|
28
|
-
this.enableColors = !this.isProd && process.stdout.isTTY;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
_getLogLevel(levelName) {
|
|
32
|
-
const upperLevel = levelName.toUpperCase();
|
|
33
|
-
return LOG_LEVELS[upperLevel] !== undefined ? LOG_LEVELS[upperLevel] : LOG_LEVELS.INFO;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
_shouldLog(level) {
|
|
37
|
-
return LOG_LEVELS[level] <= this.level;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_formatMessage(level, message, context = {}) {
|
|
41
|
-
const timestamp = new Date().toISOString();
|
|
42
|
-
|
|
43
|
-
if (this.isProd) {
|
|
44
|
-
// Production: JSON format for log aggregation tools
|
|
45
|
-
return JSON.stringify({
|
|
46
|
-
timestamp,
|
|
47
|
-
level,
|
|
48
|
-
message,
|
|
49
|
-
...context,
|
|
50
|
-
});
|
|
51
|
-
} else {
|
|
52
|
-
// Development: Human-readable format with colors
|
|
53
|
-
const color = this.enableColors ? COLORS[level] : '';
|
|
54
|
-
const reset = this.enableColors ? COLORS.RESET : '';
|
|
55
|
-
const contextStr = Object.keys(context).length > 0
|
|
56
|
-
? '\n' + util.inspect(context, { depth: 4, colors: this.enableColors })
|
|
57
|
-
: '';
|
|
58
|
-
|
|
59
|
-
return `${color}[${timestamp}] [${level}]${reset} ${message}${contextStr}`;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_log(level, message, context = {}) {
|
|
64
|
-
if (!this._shouldLog(level)) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const formattedMessage = this._formatMessage(level, message, context);
|
|
69
|
-
|
|
70
|
-
if (level === 'ERROR' || level === 'WARN') {
|
|
71
|
-
console.error(formattedMessage);
|
|
72
|
-
} else {
|
|
73
|
-
console.log(formattedMessage);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Log error level messages
|
|
79
|
-
* @param {string} message - Log message
|
|
80
|
-
* @param {Object} context - Additional context (error, stack, platform, etc.)
|
|
81
|
-
*/
|
|
82
|
-
error(message, context = {}) {
|
|
83
|
-
// If context has an error object, extract useful information
|
|
84
|
-
let enrichedContext = context;
|
|
85
|
-
if (context.error instanceof Error) {
|
|
86
|
-
const { error, ...rest } = context;
|
|
87
|
-
enrichedContext = {
|
|
88
|
-
...rest,
|
|
89
|
-
errorMessage: error.message,
|
|
90
|
-
errorStack: error.stack,
|
|
91
|
-
errorResponse: error.response?.data,
|
|
92
|
-
errorStatus: error.response?.status,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
this._log('ERROR', message, enrichedContext);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Log warning level messages
|
|
101
|
-
* @param {string} message - Log message
|
|
102
|
-
* @param {Object} context - Additional context
|
|
103
|
-
*/
|
|
104
|
-
warn(message, context = {}) {
|
|
105
|
-
this._log('WARN', message, context);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Log info level messages
|
|
110
|
-
* @param {string} message - Log message
|
|
111
|
-
* @param {Object} context - Additional context
|
|
112
|
-
*/
|
|
113
|
-
info(message, context = {}) {
|
|
114
|
-
this._log('INFO', message, context);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Log debug level messages
|
|
119
|
-
* @param {string} message - Log message
|
|
120
|
-
* @param {Object} context - Additional context
|
|
121
|
-
*/
|
|
122
|
-
debug(message, context = {}) {
|
|
123
|
-
this._log('DEBUG', message, context);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Create a child logger with default context
|
|
128
|
-
* Useful for adding request-specific or module-specific context
|
|
129
|
-
* @param {Object} defaultContext - Context to include in all logs
|
|
130
|
-
* @returns {Object} Child logger with bound context
|
|
131
|
-
*/
|
|
132
|
-
child(defaultContext = {}) {
|
|
133
|
-
return {
|
|
134
|
-
error: (message, context = {}) => this.error(message, { ...defaultContext, ...context }),
|
|
135
|
-
warn: (message, context = {}) => this.warn(message, { ...defaultContext, ...context }),
|
|
136
|
-
info: (message, context = {}) => this.info(message, { ...defaultContext, ...context }),
|
|
137
|
-
debug: (message, context = {}) => this.debug(message, { ...defaultContext, ...context }),
|
|
138
|
-
child: (additionalContext) => this.child({ ...defaultContext, ...additionalContext }),
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Log API request/response for debugging
|
|
144
|
-
* @param {Object} options - Request details
|
|
145
|
-
*/
|
|
146
|
-
logApiRequest({ method, url, status, duration, platform, error }) {
|
|
147
|
-
const context = {
|
|
148
|
-
method,
|
|
149
|
-
url,
|
|
150
|
-
status,
|
|
151
|
-
duration: duration ? `${duration}ms` : undefined,
|
|
152
|
-
platform,
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
if (error) {
|
|
156
|
-
this.error('API request failed', { ...context, error });
|
|
157
|
-
} else if (status >= 400) {
|
|
158
|
-
this.warn('API request returned error status', context);
|
|
159
|
-
} else {
|
|
160
|
-
this.debug('API request completed', context);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Log database query for debugging
|
|
166
|
-
* @param {Object} options - Query details
|
|
167
|
-
*/
|
|
168
|
-
logDatabaseQuery({ operation, table, duration, error }) {
|
|
169
|
-
const context = {
|
|
170
|
-
operation,
|
|
171
|
-
table,
|
|
172
|
-
duration: duration ? `${duration}ms` : undefined,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
if (error) {
|
|
176
|
-
this.error('Database query failed', { ...context, error });
|
|
177
|
-
} else {
|
|
178
|
-
this.debug('Database query completed', context);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Create singleton instance
|
|
184
|
-
const logger = new Logger();
|
|
185
|
-
|
|
186
|
-
// Export both the class and instance
|
|
187
|
-
module.exports = logger;
|
|
188
|
-
module.exports.Logger = Logger;
|
|
189
|
-
module.exports.LOG_LEVELS = LOG_LEVELS;
|
|
190
|
-
|
package/lib/ringcentral.js
DELETED
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const fetch = require('node-fetch');
|
|
3
|
-
|
|
4
|
-
const DEFAULT_RENEW_HANDICAP_MS = 60 * 1000; // 1 minute
|
|
5
|
-
|
|
6
|
-
function stringifyQuery(query) {
|
|
7
|
-
const queryParams = new URLSearchParams(query);
|
|
8
|
-
return queryParams.toString();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const REFRESH_RENEW_HANDICAP_MS = 10 * 1000; // 10s
|
|
12
|
-
function isRefreshTokenValid(token, handicap = REFRESH_RENEW_HANDICAP_MS) {
|
|
13
|
-
const expireTime = token.refresh_token_expire_time;
|
|
14
|
-
return expireTime - handicap > Date.now();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function isAccessTokenValid(token, handicap = DEFAULT_RENEW_HANDICAP_MS) {
|
|
18
|
-
const expireTime = token.expire_time;
|
|
19
|
-
return expireTime - handicap > Date.now();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
class RingCentral {
|
|
23
|
-
constructor(options) {
|
|
24
|
-
this._options = options;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
loginUrl({
|
|
28
|
-
state,
|
|
29
|
-
}) {
|
|
30
|
-
const query = {
|
|
31
|
-
response_type: 'code',
|
|
32
|
-
redirect_uri: this._options.redirectUri,
|
|
33
|
-
client_id: this._options.clientId,
|
|
34
|
-
response_hint: 'brand_id contracted_country_code',
|
|
35
|
-
};
|
|
36
|
-
if (state) {
|
|
37
|
-
query.state = state;
|
|
38
|
-
}
|
|
39
|
-
return `${this._options.server}/restapi/oauth/authorize?${stringifyQuery(query)}`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async generateToken({ code }) {
|
|
43
|
-
const body = {
|
|
44
|
-
code,
|
|
45
|
-
grant_type: 'authorization_code',
|
|
46
|
-
redirect_uri: this._options.redirectUri,
|
|
47
|
-
};
|
|
48
|
-
const response = await this._tokenRequest('/restapi/oauth/token', body);
|
|
49
|
-
if (Number.parseInt(response.status, 10) >= 400) {
|
|
50
|
-
throw new Error('Generate Token error', response.status);
|
|
51
|
-
}
|
|
52
|
-
const {
|
|
53
|
-
expires_in,
|
|
54
|
-
refresh_token_expires_in,
|
|
55
|
-
...token
|
|
56
|
-
} = await response.json();
|
|
57
|
-
return {
|
|
58
|
-
...token,
|
|
59
|
-
expire_time: Date.now() + parseInt(expires_in, 10) * 1000,
|
|
60
|
-
refresh_token_expire_time: Date.now() + parseInt(refresh_token_expires_in, 10) * 1000,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async refreshToken(token) {
|
|
65
|
-
const body = {
|
|
66
|
-
grant_type: 'refresh_token',
|
|
67
|
-
refresh_token: token.refresh_token,
|
|
68
|
-
access_token_ttl: token.expires_in,
|
|
69
|
-
refresh_token_ttl: token.refresh_token_expires_in,
|
|
70
|
-
};
|
|
71
|
-
const response = await this._tokenRequest('/restapi/oauth/token', body);
|
|
72
|
-
if (Number.parseInt(response.status, 10) >= 400) {
|
|
73
|
-
const error = new Error('Refresh Token error', response.status);
|
|
74
|
-
error.response = response;
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
77
|
-
const {
|
|
78
|
-
expires_in,
|
|
79
|
-
refresh_token_expires_in,
|
|
80
|
-
...newToken
|
|
81
|
-
} = await response.json();
|
|
82
|
-
return {
|
|
83
|
-
...newToken,
|
|
84
|
-
expire_time: Date.now() + parseInt(expires_in, 10) * 1000,
|
|
85
|
-
refresh_token_expire_time: Date.now() + parseInt(refresh_token_expires_in, 10) * 1000,
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async revokeToken(token) {
|
|
90
|
-
const body = {
|
|
91
|
-
token: token.access_token,
|
|
92
|
-
};
|
|
93
|
-
const response = await this._tokenRequest('/restapi/oauth/revoke', body);
|
|
94
|
-
if (Number.parseInt(response.status, 10) >= 400) {
|
|
95
|
-
throw new Error('Revoke Token error', response.status);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async _tokenRequest(path, body) {
|
|
100
|
-
const authorization = `${this._options.clientId}:${this._options.clientSecret}`;
|
|
101
|
-
const response = await fetch(
|
|
102
|
-
`${this._options.server}${path}`, {
|
|
103
|
-
method: 'POST',
|
|
104
|
-
body: stringifyQuery(body),
|
|
105
|
-
headers: {
|
|
106
|
-
'Accept': 'application/json',
|
|
107
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
108
|
-
'Authorization': `Basic ${Buffer.from(authorization).toString('base64')}`
|
|
109
|
-
},
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
return response;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async request({
|
|
116
|
-
server = this._options.server,
|
|
117
|
-
path,
|
|
118
|
-
query,
|
|
119
|
-
body,
|
|
120
|
-
method,
|
|
121
|
-
accept = 'application/json',
|
|
122
|
-
}, token) {
|
|
123
|
-
let uri = `${server}${path}`;
|
|
124
|
-
if (query) {
|
|
125
|
-
uri = uri + (uri.includes('?') ? '&' : '?') + stringifyQuery(query);
|
|
126
|
-
}
|
|
127
|
-
const response = await fetch(uri, {
|
|
128
|
-
method,
|
|
129
|
-
body: body ? JSON.stringify(body) : body,
|
|
130
|
-
headers: {
|
|
131
|
-
'Accept': accept,
|
|
132
|
-
'Content-Type': 'application/json',
|
|
133
|
-
'Authorization': `${token.token_type} ${token.access_token}`,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
if (Number.parseInt(response.status, 10) >= 400) {
|
|
137
|
-
const error = new Error(`request data error ${response.status}`);
|
|
138
|
-
const errorText = await response.text();
|
|
139
|
-
error.message = errorText;
|
|
140
|
-
error.response = response;
|
|
141
|
-
throw error;
|
|
142
|
-
}
|
|
143
|
-
return response;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async createSubscription({
|
|
147
|
-
eventFilters,
|
|
148
|
-
webhookUri,
|
|
149
|
-
}, token) {
|
|
150
|
-
const response = await this.request({
|
|
151
|
-
method: 'POST',
|
|
152
|
-
path: '/restapi/v1.0/subscription',
|
|
153
|
-
body: {
|
|
154
|
-
eventFilters,
|
|
155
|
-
deliveryMode: {
|
|
156
|
-
transportType: 'WebHook',
|
|
157
|
-
address: webhookUri,
|
|
158
|
-
},
|
|
159
|
-
expiresIn: 7 * 24 * 3600, // 7 days
|
|
160
|
-
},
|
|
161
|
-
}, token);
|
|
162
|
-
const {
|
|
163
|
-
...subscription
|
|
164
|
-
} = await response.json();
|
|
165
|
-
return subscription;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
async getExtensionInfo(extensionId, token) {
|
|
169
|
-
const response = await this.request({
|
|
170
|
-
method: 'GET',
|
|
171
|
-
path: `/restapi/v1.0/account/~/extension/${extensionId}`,
|
|
172
|
-
}, token);
|
|
173
|
-
return response.json();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async getAccountInfo(token) {
|
|
177
|
-
const response = await this.request({
|
|
178
|
-
method: 'GET',
|
|
179
|
-
path: `/restapi/v1.0/account/~`,
|
|
180
|
-
}, token);
|
|
181
|
-
return response.json();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
async getCallsAggregationData({ token, timezone, timeFrom, timeTo, groupBy }) {
|
|
185
|
-
const body = {
|
|
186
|
-
grouping: {
|
|
187
|
-
groupBy
|
|
188
|
-
},
|
|
189
|
-
timeSettings: {
|
|
190
|
-
timeZone: timezone,
|
|
191
|
-
timeRange: {
|
|
192
|
-
timeFrom: timeFrom,
|
|
193
|
-
timeTo: timeTo
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
responseOptions: {
|
|
197
|
-
counters: {
|
|
198
|
-
callsByDirection: {
|
|
199
|
-
aggregationType: "Sum"
|
|
200
|
-
},
|
|
201
|
-
callsByResponse: {
|
|
202
|
-
aggregationType: "Sum"
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
timers: {
|
|
206
|
-
allCallsDuration: {
|
|
207
|
-
aggregationType: "Sum"
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const response = await this.request({
|
|
213
|
-
method: 'POST',
|
|
214
|
-
path: `/analytics/calls/v1/accounts/~/aggregation/fetch`,
|
|
215
|
-
body,
|
|
216
|
-
accept: 'application/json'
|
|
217
|
-
}, token);
|
|
218
|
-
return response.json();
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
async getCallLogData({ extensionId = '~', token, timeFrom, timeTo }) {
|
|
222
|
-
let pageStart = 1;
|
|
223
|
-
let isFinalPage = false;
|
|
224
|
-
let callLogResponse = null;
|
|
225
|
-
let result = { records: [] };
|
|
226
|
-
while (!isFinalPage) {
|
|
227
|
-
callLogResponse = await this.request({
|
|
228
|
-
method: 'GET',
|
|
229
|
-
path: `/restapi/v1.0/account/~/extension/${extensionId}/call-log?dateFrom=${timeFrom}&dateTo=${timeTo}&page=${pageStart}&view=Simple&perPage=1000`,
|
|
230
|
-
}, token);
|
|
231
|
-
const resultJson = await callLogResponse.json();
|
|
232
|
-
result.records.push(...resultJson.records);
|
|
233
|
-
if (resultJson.navigation?.nextPage) {
|
|
234
|
-
pageStart++;
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
isFinalPage = true;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return result;
|
|
241
|
-
}
|
|
242
|
-
async getSMSData({ extensionId = '~', token, timeFrom, timeTo }) {
|
|
243
|
-
let pageStart = 1;
|
|
244
|
-
let isFinalPage = false;
|
|
245
|
-
let smsLogResponse = null;
|
|
246
|
-
let result = { records: [] };
|
|
247
|
-
while (!isFinalPage) {
|
|
248
|
-
smsLogResponse = await this.request({
|
|
249
|
-
method: 'GET',
|
|
250
|
-
path: `/restapi/v1.0/account/~/extension/${extensionId}/message-store?dateFrom=${timeFrom}&dateTo=${timeTo}&page=${pageStart}&perPage=100`,
|
|
251
|
-
}, token);
|
|
252
|
-
const resultJson = await smsLogResponse.json();
|
|
253
|
-
result.records.push(...resultJson.records);
|
|
254
|
-
if (resultJson.navigation?.nextPage) {
|
|
255
|
-
pageStart++;
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
isFinalPage = true;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return result;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
exports.RingCentral = RingCentral;
|
|
266
|
-
exports.isRefreshTokenValid = isRefreshTokenValid;
|
|
267
|
-
exports.isAccessTokenValid = isAccessTokenValid;
|