@app-connect/core 1.7.10 → 1.7.11

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 (55) hide show
  1. package/connector/developerPortal.js +43 -0
  2. package/connector/proxy/index.js +10 -3
  3. package/connector/registry.js +8 -6
  4. package/handlers/admin.js +44 -21
  5. package/handlers/auth.js +89 -67
  6. package/handlers/calldown.js +10 -4
  7. package/handlers/contact.js +4 -104
  8. package/handlers/disposition.js +4 -142
  9. package/handlers/log.js +172 -257
  10. package/handlers/user.js +19 -6
  11. package/index.js +213 -47
  12. package/lib/analytics.js +3 -1
  13. package/lib/authSession.js +68 -0
  14. package/lib/callLogComposer.js +498 -420
  15. package/lib/errorHandler.js +206 -0
  16. package/lib/jwt.js +2 -0
  17. package/lib/logger.js +190 -0
  18. package/lib/oauth.js +21 -10
  19. package/lib/ringcentral.js +2 -10
  20. package/lib/sharedSMSComposer.js +471 -0
  21. package/mcp/SupportedPlatforms.md +12 -0
  22. package/mcp/lib/validator.js +91 -0
  23. package/mcp/mcpHandler.js +166 -0
  24. package/mcp/tools/checkAuthStatus.js +90 -0
  25. package/mcp/tools/collectAuthInfo.js +86 -0
  26. package/mcp/tools/createCallLog.js +299 -0
  27. package/mcp/tools/createMessageLog.js +283 -0
  28. package/mcp/tools/doAuth.js +185 -0
  29. package/mcp/tools/findContactByName.js +87 -0
  30. package/mcp/tools/findContactByPhone.js +96 -0
  31. package/mcp/tools/getCallLog.js +98 -0
  32. package/mcp/tools/getHelp.js +39 -0
  33. package/mcp/tools/getPublicConnectors.js +46 -0
  34. package/mcp/tools/index.js +58 -0
  35. package/mcp/tools/logout.js +63 -0
  36. package/mcp/tools/rcGetCallLogs.js +73 -0
  37. package/mcp/tools/setConnector.js +64 -0
  38. package/mcp/tools/updateCallLog.js +122 -0
  39. package/models/cacheModel.js +3 -0
  40. package/package.json +71 -70
  41. package/releaseNotes.json +12 -0
  42. package/test/handlers/log.test.js +6 -2
  43. package/test/lib/logger.test.js +206 -0
  44. package/test/lib/sharedSMSComposer.test.js +1084 -0
  45. package/test/mcp/tools/collectAuthInfo.test.js +192 -0
  46. package/test/mcp/tools/createCallLog.test.js +412 -0
  47. package/test/mcp/tools/createMessageLog.test.js +580 -0
  48. package/test/mcp/tools/doAuth.test.js +363 -0
  49. package/test/mcp/tools/findContactByName.test.js +263 -0
  50. package/test/mcp/tools/findContactByPhone.test.js +284 -0
  51. package/test/mcp/tools/getCallLog.test.js +286 -0
  52. package/test/mcp/tools/getPublicConnectors.test.js +128 -0
  53. package/test/mcp/tools/logout.test.js +169 -0
  54. package/test/mcp/tools/setConnector.test.js +177 -0
  55. package/test/mcp/tools/updateCallLog.test.js +346 -0
package/handlers/log.js CHANGED
@@ -3,22 +3,30 @@ const { CallLogModel } = require('../models/callLogModel');
3
3
  const { MessageLogModel } = require('../models/messageLogModel');
4
4
  const { UserModel } = require('../models/userModel');
5
5
  const oauth = require('../lib/oauth');
6
- const errorMessage = require('../lib/generalErrorMessage');
7
6
  const { composeCallLog } = require('../lib/callLogComposer');
7
+ const { composeSharedSMSLog } = require('../lib/sharedSMSComposer');
8
8
  const connectorRegistry = require('../connector/registry');
9
9
  const { LOG_DETAILS_FORMAT_TYPE } = require('../lib/constants');
10
10
  const { NoteCache } = require('../models/dynamo/noteCacheSchema');
11
11
  const { Connector } = require('../models/dynamo/connectorSchema');
12
12
  const moment = require('moment');
13
13
  const { getMediaReaderLinkByPlatformMediaLink } = require('../lib/util');
14
+ const logger = require('../lib/logger');
15
+ const { handleApiError, handleDatabaseError } = require('../lib/errorHandler');
14
16
 
15
17
  async function createCallLog({ platform, userId, incomingData, hashedAccountId, isFromSSCL }) {
16
18
  try {
17
- const existingCallLog = await CallLogModel.findOne({
18
- where: {
19
- sessionId: incomingData.logInfo.sessionId
20
- }
21
- });
19
+ let existingCallLog = null;
20
+ try {
21
+ existingCallLog = await CallLogModel.findOne({
22
+ where: {
23
+ sessionId: incomingData.logInfo.sessionId
24
+ }
25
+ });
26
+ }
27
+ catch (error) {
28
+ return handleDatabaseError(error, 'Error finding existing call log');
29
+ }
22
30
  if (existingCallLog) {
23
31
  return {
24
32
  successful: false,
@@ -29,7 +37,13 @@ async function createCallLog({ platform, userId, incomingData, hashedAccountId,
29
37
  }
30
38
  }
31
39
  }
32
- let user = await UserModel.findByPk(userId);
40
+ let user = null;
41
+ try {
42
+ user = await UserModel.findByPk(userId);
43
+ }
44
+ catch (error) {
45
+ return handleDatabaseError(error, 'Error finding user');
46
+ }
33
47
  if (!user || !user.accessToken) {
34
48
  return {
35
49
  successful: false,
@@ -88,12 +102,12 @@ async function createCallLog({ platform, userId, incomingData, hashedAccountId,
88
102
  type: incomingData.contactType ?? "",
89
103
  name: incomingData.contactName ?? ""
90
104
  };
91
-
105
+
92
106
  // Compose call log details centrally
93
107
  const logFormat = platformModule.getLogFormatType ? platformModule.getLogFormatType(platform, proxyConfig) : LOG_DETAILS_FORMAT_TYPE.PLAIN_TEXT;
94
108
  let composedLogDetails = '';
95
109
  if (logFormat === LOG_DETAILS_FORMAT_TYPE.PLAIN_TEXT || logFormat === LOG_DETAILS_FORMAT_TYPE.HTML || logFormat === LOG_DETAILS_FORMAT_TYPE.MARKDOWN) {
96
- composedLogDetails = await composeCallLog({
110
+ composedLogDetails = composeCallLog({
97
111
  logFormat,
98
112
  callLog,
99
113
  contactInfo,
@@ -135,54 +149,23 @@ async function createCallLog({ platform, userId, incomingData, hashedAccountId,
135
149
  proxyConfig,
136
150
  });
137
151
  if (logId) {
138
- await CallLogModel.create({
139
- id: incomingData.logInfo.telephonySessionId || incomingData.logInfo.id,
140
- sessionId: incomingData.logInfo.sessionId,
141
- platform,
142
- thirdPartyLogId: logId,
143
- userId,
144
- contactId
145
- });
152
+ try {
153
+ await CallLogModel.create({
154
+ id: incomingData.logInfo.telephonySessionId || incomingData.logInfo.id,
155
+ sessionId: incomingData.logInfo.sessionId,
156
+ platform,
157
+ thirdPartyLogId: logId,
158
+ userId,
159
+ contactId
160
+ });
161
+ }
162
+ catch (error) {
163
+ return handleDatabaseError(error, 'Error creating call log');
164
+ }
146
165
  }
147
166
  return { successful: !!logId, logId, returnMessage, extraDataTracking };
148
167
  } catch (e) {
149
- console.error(`platform: ${platform} \n${e.stack} \n${JSON.stringify(e.response?.data)}`);
150
- if (e.response?.status === 429) {
151
- return {
152
- successful: false,
153
- returnMessage: errorMessage.rateLimitErrorMessage({ platform })
154
- };
155
- }
156
- else if (e.response?.status >= 400 && e.response?.status < 410) {
157
- return {
158
- successful: false,
159
- returnMessage: errorMessage.authorizationErrorMessage({ platform }),
160
- extraDataTracking: {
161
- statusCode: e.response?.status,
162
- }
163
- };
164
- }
165
- return {
166
- successful: false,
167
- returnMessage:
168
- {
169
- message: `Error creating call log`,
170
- messageType: 'warning',
171
- details: [
172
- {
173
- title: 'Details',
174
- items: [
175
- {
176
- id: '1',
177
- type: 'text',
178
- text: `Please check if your account has permission to CREATE logs.`
179
- }
180
- ]
181
- }
182
- ],
183
- ttl: 5000
184
- }
185
- };
168
+ return handleApiError(e, platform, 'createCallLog', { userId });
186
169
  }
187
170
  }
188
171
 
@@ -233,8 +216,7 @@ async function getCallLog({ userId, sessionIds, platform, requireDetails }) {
233
216
  }
234
217
  });
235
218
  for (const sId of sessionIdsArray) {
236
- if(sId == 0)
237
- {
219
+ if (sId == 0) {
238
220
  logs.push({ sessionId: sId, matched: false });
239
221
  continue;
240
222
  }
@@ -271,59 +253,23 @@ async function getCallLog({ userId, sessionIds, platform, requireDetails }) {
271
253
  return { successful: true, logs, returnMessage, extraDataTracking };
272
254
  }
273
255
  catch (e) {
274
- console.error(`platform: ${platform} \n${e.stack} \n${JSON.stringify(e.response?.data)}`);
275
- if (e.response?.status === 429) {
276
- return {
277
- successful: false,
278
- returnMessage: errorMessage.rateLimitErrorMessage({ platform }),
279
- extraDataTracking: {
280
- statusCode: e.response?.status,
281
- }
282
- };
283
- }
284
- else if (e.response?.status >= 400 && e.response?.status < 410) {
285
- return {
286
- successful: false,
287
- returnMessage: errorMessage.authorizationErrorMessage({ platform }),
288
- extraDataTracking: {
289
- statusCode: e.response?.status,
290
- }
291
- };
292
- }
293
- return {
294
- successful: false,
295
- returnMessage:
296
- {
297
- message: `Error getting call log`,
298
- messageType: 'warning',
299
- details: [
300
- {
301
- title: 'Details',
302
- items: [
303
- {
304
- id: '1',
305
- type: 'text',
306
- text: `Please check if your account has permission to READ logs.`
307
- }
308
- ]
309
- }
310
- ],
311
- ttl: 5000
312
- },
313
- extraDataTracking: {
314
- statusCode: e.response?.status,
315
- }
316
- };
256
+ return handleApiError(e, platform, 'getCallLog', { userId, sessionIds, requireDetails });
317
257
  }
318
258
  }
319
259
 
320
260
  async function updateCallLog({ platform, userId, incomingData, hashedAccountId, isFromSSCL }) {
321
261
  try {
322
- const existingCallLog = await CallLogModel.findOne({
323
- where: {
324
- sessionId: incomingData.sessionId
325
- }
326
- });
262
+ let existingCallLog = null;
263
+ try {
264
+ existingCallLog = await CallLogModel.findOne({
265
+ where: {
266
+ sessionId: incomingData.sessionId
267
+ }
268
+ });
269
+ }
270
+ catch (error) {
271
+ return handleDatabaseError(error, 'Error finding existing call log');
272
+ }
327
273
  if (existingCallLog) {
328
274
  const platformModule = connectorRegistry.getConnector(platform);
329
275
  let user = await UserModel.findByPk(userId);
@@ -371,9 +317,9 @@ async function updateCallLog({ platform, userId, incomingData, hashedAccountId,
371
317
  existingBody = getLogResult.callLogInfo.note;
372
318
  }
373
319
  } catch (error) {
374
- console.log('Error getting existing log details, proceeding with empty body', error);
320
+ logger.error('Error getting existing log details, proceeding with empty body', { stack: error.stack });
375
321
  }
376
- composedLogDetails = await composeCallLog({
322
+ composedLogDetails = composeCallLog({
377
323
  logFormat,
378
324
  existingBody,
379
325
  callLog: {
@@ -434,49 +380,7 @@ async function updateCallLog({ platform, userId, incomingData, hashedAccountId,
434
380
  }
435
381
  return { successful: false };
436
382
  } catch (e) {
437
- console.error(`platform: ${platform} \n${e.stack} \n${JSON.stringify(e.response?.data)}`);
438
- if (e.response?.status === 429) {
439
- return {
440
- successful: false,
441
- returnMessage: errorMessage.rateLimitErrorMessage({ platform }),
442
- extraDataTracking: {
443
- statusCode: e.response?.status,
444
- }
445
- };
446
- }
447
- else if (e.response?.status >= 400 && e.response?.status < 410) {
448
- return {
449
- successful: false,
450
- returnMessage: errorMessage.authorizationErrorMessage({ platform }),
451
- extraDataTracking: {
452
- statusCode: e.response?.status,
453
- }
454
- };
455
- }
456
- return {
457
- successful: false,
458
- returnMessage:
459
- {
460
- message: `Error updating call log`,
461
- messageType: 'warning',
462
- details: [
463
- {
464
- title: 'Details',
465
- items: [
466
- {
467
- id: '1',
468
- type: 'text',
469
- text: `Please check if the log entity still exist on ${platform} and your account has permission to EDIT logs.`
470
- }
471
- ]
472
- }
473
- ],
474
- ttl: 5000
475
- },
476
- extraDataTracking: {
477
- statusCode: e.response?.status,
478
- }
479
- };
383
+ return handleApiError(e, platform, 'updateCallLog', { userId });
480
384
  }
481
385
  }
482
386
 
@@ -498,7 +402,13 @@ async function createMessageLog({ platform, userId, incomingData }) {
498
402
  const platformModule = connectorRegistry.getConnector(platform);
499
403
  const contactNumber = incomingData.logInfo.correspondents[0].phoneNumber;
500
404
  const additionalSubmission = incomingData.additionalSubmission;
501
- let user = await UserModel.findByPk(userId);
405
+ let user = null;
406
+ try {
407
+ user = await UserModel.findByPk(userId);
408
+ }
409
+ catch (error) {
410
+ return handleDatabaseError(error, 'Error finding user');
411
+ }
502
412
  if (!user || !user.accessToken) {
503
413
  return {
504
414
  successful: false,
@@ -546,139 +456,144 @@ async function createMessageLog({ platform, userId, incomingData }) {
546
456
  type: incomingData.contactType ?? "",
547
457
  name: incomingData.contactName ?? ""
548
458
  };
459
+ // For shared SMS
460
+ const assigneeName = incomingData.logInfo.assignee?.name;
461
+ const ownerName = incomingData.logInfo.owner?.name;
462
+ const isSharedSMS = !!ownerName;
463
+
549
464
  const messageIds = incomingData.logInfo.messages.map(m => { return { id: m.id.toString() }; });
550
- const existingMessages = await MessageLogModel.findAll({
551
- where: {
552
- [Op.or]: messageIds
553
- }
554
- });
465
+ let existingMessages = null;
466
+ try {
467
+ existingMessages = await MessageLogModel.findAll({
468
+ where: {
469
+ [Op.or]: messageIds
470
+ }
471
+ });
472
+ }
473
+ catch (error) {
474
+ return handleDatabaseError(error, 'Error finding existing messages');
475
+ }
555
476
  const existingIds = existingMessages.map(m => m.id);
556
477
  const logIds = [];
557
- // reverse the order of messages to log the oldest message first
558
- const reversedMessages = incomingData.logInfo.messages.reverse();
559
- for (const message of reversedMessages) {
560
- if (existingIds.includes(message.id.toString())) {
561
- continue;
562
- }
563
- let recordingLink = null;
564
- if (message.attachments && message.attachments.some(a => a.type === 'AudioRecording')) {
565
- recordingLink = message.attachments.find(a => a.type === 'AudioRecording').link;
566
- }
567
- let faxDocLink = null;
568
- let faxDownloadLink = null;
569
- if (message.attachments && message.attachments.some(a => a.type === 'RenderedDocument')) {
570
- faxDocLink = message.attachments.find(a => a.type === 'RenderedDocument').link;
571
- faxDownloadLink = message.attachments.find(a => a.type === 'RenderedDocument').uri + `?access_token=${incomingData.logInfo.rcAccessToken}`
572
- }
573
- let imageLink = null;
574
- let imageDownloadLink = null;
575
- let imageContentType = null;
576
- if (message.attachments && message.attachments.some(a => a.type === 'MmsAttachment' && a.contentType.startsWith('image/'))) {
577
- const imageAttachment = message.attachments.find(a => a.type === 'MmsAttachment' && a.contentType.startsWith('image/'));
578
- if (imageAttachment) {
579
- imageLink = getMediaReaderLinkByPlatformMediaLink(imageAttachment?.uri);
580
- imageDownloadLink = imageAttachment?.uri + `?access_token=${incomingData.logInfo.rcAccessToken}`;
581
- imageContentType = imageAttachment?.contentType;
582
- }
583
- }
584
- let videoLink = null;
585
- if (message.attachments && message.attachments.some(a => a.type === 'MmsAttachment')) {
586
- const imageAttachment = message.attachments.find(a => a.type === 'MmsAttachment' && a.contentType.startsWith('image/'));
587
- if (imageAttachment) {
588
- imageLink = getMediaReaderLinkByPlatformMediaLink(imageAttachment?.uri);
589
- }
590
- const videoAttachment = message.attachments.find(a => a.type === 'MmsAttachment' && a.contentType.startsWith('video/'));
591
- if (videoAttachment) {
592
- videoLink = getMediaReaderLinkByPlatformMediaLink(videoAttachment?.uri);
593
- }
594
- }
595
- const existingSameDateMessageLog = await MessageLogModel.findOne({
478
+ // Case: Shared SMS
479
+ if (isSharedSMS) {
480
+ const existingMessageLog = await MessageLogModel.findOne({
596
481
  where: {
597
482
  conversationLogId: incomingData.logInfo.conversationLogId
598
483
  }
599
484
  });
600
- let crmLogId = ''
601
- if (existingSameDateMessageLog) {
602
- const updateMessageResult = await platformModule.updateMessageLog({ user, contactInfo, existingMessageLog: existingSameDateMessageLog, message, authHeader, additionalSubmission, imageLink, videoLink, proxyConfig });
603
- crmLogId = existingSameDateMessageLog.thirdPartyLogId;
485
+ const entities = incomingData.logInfo.entities;
486
+ const sharedSMSLogContent = composeSharedSMSLog({ logFormat: platformModule.getLogFormatType(platform, proxyConfig), conversation: incomingData.logInfo, contactName: contactInfo.name, timezoneOffset: user.timezoneOffset });
487
+ if (existingMessageLog) {
488
+ const updateMessageResult = await platformModule.updateMessageLog({ user, contactInfo, sharedSMSLogContent, existingMessageLog: existingMessageLog, authHeader, additionalSubmission, proxyConfig });
604
489
  returnMessage = updateMessageResult?.returnMessage;
605
490
  }
606
491
  else {
607
- const createMessageLogResult = await platformModule.createMessageLog({ user, contactInfo, authHeader, message, additionalSubmission, recordingLink, faxDocLink, faxDownloadLink, imageLink, imageDownloadLink, imageContentType, videoLink, proxyConfig });
608
- crmLogId = createMessageLogResult.logId;
492
+ const createMessageLogResult = await platformModule.createMessageLog({ user, contactInfo, sharedSMSLogContent, authHeader, additionalSubmission, proxyConfig });
493
+ const crmLogId = createMessageLogResult.logId;
609
494
  returnMessage = createMessageLogResult?.returnMessage;
610
495
  extraDataTracking = createMessageLogResult.extraDataTracking;
496
+ if (createMessageLogResult.logId) {
497
+ const createdMessageLog =
498
+ await MessageLogModel.create({
499
+ id: incomingData.logInfo.conversationLogId,
500
+ platform,
501
+ conversationId: incomingData.logInfo.conversationId,
502
+ thirdPartyLogId: createMessageLogResult.logId,
503
+ userId,
504
+ conversationLogId: incomingData.logInfo.conversationLogId
505
+ });
506
+ logIds.push(createdMessageLog.id);
507
+ }
611
508
  }
612
- if (crmLogId) {
613
- const createdMessageLog =
614
- await MessageLogModel.create({
615
- id: message.id.toString(),
616
- platform,
617
- conversationId: incomingData.logInfo.conversationId,
618
- thirdPartyLogId: crmLogId,
619
- userId,
509
+ }
510
+ // Case: normal SMS
511
+ else {
512
+ // reverse the order of messages to log the oldest message first
513
+ const reversedMessages = incomingData.logInfo.messages.reverse();
514
+ for (const message of reversedMessages) {
515
+ if (existingIds.includes(message.id.toString())) {
516
+ continue;
517
+ }
518
+ let recordingLink = null;
519
+ if (message.attachments && message.attachments.some(a => a.type === 'AudioRecording')) {
520
+ recordingLink = message.attachments.find(a => a.type === 'AudioRecording').link;
521
+ }
522
+ let faxDocLink = null;
523
+ let faxDownloadLink = null;
524
+ if (message.attachments && message.attachments.some(a => a.type === 'RenderedDocument')) {
525
+ faxDocLink = message.attachments.find(a => a.type === 'RenderedDocument').link;
526
+ faxDownloadLink = message.attachments.find(a => a.type === 'RenderedDocument').uri + `?access_token=${incomingData.logInfo.rcAccessToken}`
527
+ }
528
+ let imageLink = null;
529
+ let imageDownloadLink = null;
530
+ let imageContentType = null;
531
+ if (message.attachments && message.attachments.some(a => a.type === 'MmsAttachment' && a.contentType.startsWith('image/'))) {
532
+ const imageAttachment = message.attachments.find(a => a.type === 'MmsAttachment' && a.contentType.startsWith('image/'));
533
+ if (imageAttachment) {
534
+ imageLink = getMediaReaderLinkByPlatformMediaLink(imageAttachment?.uri);
535
+ imageDownloadLink = imageAttachment?.uri + `?access_token=${incomingData.logInfo.rcAccessToken}`;
536
+ imageContentType = imageAttachment?.contentType;
537
+ }
538
+ }
539
+ let videoLink = null;
540
+ if (message.attachments && message.attachments.some(a => a.type === 'MmsAttachment')) {
541
+ const imageAttachment = message.attachments.find(a => a.type === 'MmsAttachment' && a.contentType.startsWith('image/'));
542
+ if (imageAttachment) {
543
+ imageLink = getMediaReaderLinkByPlatformMediaLink(imageAttachment?.uri);
544
+ }
545
+ const videoAttachment = message.attachments.find(a => a.type === 'MmsAttachment' && a.contentType.startsWith('video/'));
546
+ if (videoAttachment) {
547
+ videoLink = getMediaReaderLinkByPlatformMediaLink(videoAttachment?.uri);
548
+ }
549
+ }
550
+ const existingSameDateMessageLog = await MessageLogModel.findOne({
551
+ where: {
620
552
  conversationLogId: incomingData.logInfo.conversationLogId
621
- });
622
- logIds.push(createdMessageLog.id);
553
+ }
554
+ });
555
+ if (existingSameDateMessageLog) {
556
+ const updateMessageResult = await platformModule.updateMessageLog({ user, contactInfo, assigneeName, ownerName, existingMessageLog: existingSameDateMessageLog, message, authHeader, additionalSubmission, imageLink, videoLink, proxyConfig });
557
+ returnMessage = updateMessageResult?.returnMessage;
558
+ }
559
+ else {
560
+ const createMessageLogResult = await platformModule.createMessageLog({ user, contactInfo, assigneeName, ownerName, authHeader, message, additionalSubmission, recordingLink, faxDocLink, faxDownloadLink, imageLink, imageDownloadLink, imageContentType, videoLink, proxyConfig });
561
+ const crmLogId = createMessageLogResult.logId;
562
+ if (crmLogId) {
563
+ try {
564
+ const createdMessageLog =
565
+ await MessageLogModel.create({
566
+ id: message.id.toString(),
567
+ platform,
568
+ conversationId: incomingData.logInfo.conversationId,
569
+ thirdPartyLogId: crmLogId,
570
+ userId,
571
+ conversationLogId: incomingData.logInfo.conversationLogId
572
+ });
573
+ logIds.push(createdMessageLog.id);
574
+ } catch (error) {
575
+ return handleDatabaseError(error, 'Error creating message log');
576
+ }
577
+ }
578
+ returnMessage = createMessageLogResult?.returnMessage;
579
+ extraDataTracking = createMessageLogResult.extraDataTracking;
580
+ }
623
581
  }
624
582
  }
625
583
  return { successful: true, logIds, returnMessage, extraDataTracking };
626
584
  }
627
585
  catch (e) {
628
- console.error(`platform: ${platform} \n${e.stack}`);
629
- if (e.response?.status === 429) {
630
- return {
631
- successful: false,
632
- returnMessage: errorMessage.rateLimitErrorMessage({ platform }),
633
- extraDataTracking: {
634
- statusCode: e.response?.status,
635
- }
636
- };
637
- }
638
- else if (e.response?.status >= 400 && e.response?.status < 410) {
639
- return {
640
- successful: false,
641
- returnMessage: errorMessage.authorizationErrorMessage({ platform }),
642
- extraDataTracking: {
643
- statusCode: e.response?.status,
644
- }
645
- };
646
- }
647
- return {
648
- successful: false,
649
- returnMessage:
650
- {
651
- message: `Error creating message log`,
652
- messageType: 'warning',
653
- details: [
654
- {
655
- title: 'Details',
656
- items: [
657
- {
658
- id: '1',
659
- type: 'text',
660
- text: `Please check if your account has permission to CREATE logs.`
661
- }
662
- ]
663
- }
664
- ],
665
- ttl: 5000
666
- },
667
- extraDataTracking: {
668
- statusCode: e.response?.status,
669
- }
670
- };
586
+ return handleApiError(e, platform, 'createMessageLog', { userId });
671
587
  }
672
588
  }
673
589
 
674
- async function saveNoteCache({ sessionId, note }) {
590
+ async function saveNoteCache({ platform, userId, sessionId, note }) {
675
591
  try {
676
592
  const now = moment();
677
- const noteCache = await NoteCache.create({ sessionId, note, ttl: now.unix() + 3600 });
593
+ await NoteCache.create({ sessionId, note, ttl: now.unix() + 3600 });
678
594
  return { successful: true, returnMessage: 'Note cache saved' };
679
595
  } catch (e) {
680
- console.error(`Error saving note cache: ${e.stack}`);
681
- return { successful: false, returnMessage: 'Error saving note cache' };
596
+ return handleApiError(e, platform, 'saveNoteCache', { userId, sessionId, note });
682
597
  }
683
598
  }
684
599
 
package/handlers/user.js CHANGED
@@ -2,6 +2,8 @@ const axios = require('axios');
2
2
  const { AdminConfigModel } = require('../models/adminConfigModel');
3
3
  const { getHashValue } = require('../lib/util');
4
4
  const connectorRegistry = require('../connector/registry');
5
+ const logger = require('../lib/logger');
6
+ const { handleDatabaseError } = require('../lib/errorHandler');
5
7
 
6
8
  async function getUserSettingsByAdmin({ rcAccessToken, rcAccountId }) {
7
9
  let hashedRcAccountId = null;
@@ -31,6 +33,7 @@ async function getUserSettings({ user, rcAccessToken, rcAccountId }) {
31
33
  userSettingsByAdmin = await getUserSettingsByAdmin({ rcAccessToken, rcAccountId });
32
34
  }
33
35
  catch (e) {
36
+ logger.error('Error getting user settings by admin', { stack: e.stack });
34
37
  userSettingsByAdmin = [];
35
38
  }
36
39
  }
@@ -77,9 +80,14 @@ async function updateUserSettings({ user, userSettings, platformName }) {
77
80
  if (platformModule.onUpdateUserSettings) {
78
81
  const { successful, returnMessage } = await platformModule.onUpdateUserSettings({ user, userSettings, updatedSettings });
79
82
  if (successful) {
80
- await user.update({
81
- userSettings: updatedSettings
82
- });
83
+ try {
84
+ await user.update({
85
+ userSettings: updatedSettings
86
+ });
87
+ }
88
+ catch (error) {
89
+ return handleDatabaseError(error, 'Error updating user settings');
90
+ }
83
91
  }
84
92
  return {
85
93
  successful,
@@ -87,9 +95,14 @@ async function updateUserSettings({ user, userSettings, platformName }) {
87
95
  };
88
96
  }
89
97
  else {
90
- await user.update({
91
- userSettings: updatedSettings
92
- });
98
+ try {
99
+ await user.update({
100
+ userSettings: updatedSettings
101
+ });
102
+ }
103
+ catch (error) {
104
+ return handleDatabaseError(error, 'Error updating user settings');
105
+ }
93
106
  }
94
107
  return {
95
108
  userSettings: user.userSettings