rez_core 2.2.180 → 2.2.182
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/dist/module/communication/controller/communication.controller.d.ts +4 -1
- package/dist/module/communication/controller/communication.controller.js +2 -2
- package/dist/module/communication/controller/communication.controller.js.map +1 -1
- package/dist/module/communication/service/communication.service.d.ts +8 -3
- package/dist/module/communication/service/communication.service.js +213 -3
- package/dist/module/communication/service/communication.service.js.map +1 -1
- package/dist/module/user/controller/user.controller.js +0 -1
- package/dist/module/user/controller/user.controller.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/communication/controller/communication.controller.ts +4 -3
- package/src/module/communication/service/communication.service.ts +326 -19
- package/src/module/user/controller/user.controller.ts +0 -1
package/package.json
CHANGED
|
@@ -85,7 +85,8 @@ export class CommunicationController {
|
|
|
85
85
|
async getLevelConfigs(
|
|
86
86
|
@Param('id', ParseIntPipe) levelId: number,
|
|
87
87
|
@Param('type') levelType: string,
|
|
88
|
-
@Query('communication_config_type')
|
|
88
|
+
@Query('communication_config_type')
|
|
89
|
+
configType?: 'WA' | 'SMS' | 'EMAIL' | 'TELEPHONE',
|
|
89
90
|
@Query('service') service?: 'API' | 'THIRD_PARTY' | 'SMTP',
|
|
90
91
|
@Query('provider') provider?: string,
|
|
91
92
|
) {
|
|
@@ -112,10 +113,10 @@ export class CommunicationController {
|
|
|
112
113
|
@HttpCode(HttpStatus.OK)
|
|
113
114
|
async activateConfig(
|
|
114
115
|
@Param('id', ParseIntPipe) hubId: number,
|
|
115
|
-
@
|
|
116
|
+
@Query('status') status: number,
|
|
116
117
|
) {
|
|
117
118
|
await this.communicationService.updateConfigStatus(hubId, status);
|
|
118
|
-
return { message: 'Configuration
|
|
119
|
+
return { message: 'Configuration updated' };
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
@Post('gmail/oauth/init')
|
|
@@ -146,7 +146,11 @@ export class CommunicationService {
|
|
|
146
146
|
): Promise<CommunicationHubWithConfig[]> {
|
|
147
147
|
let query = this.hubRepository
|
|
148
148
|
.createQueryBuilder('hub')
|
|
149
|
-
.leftJoin(
|
|
149
|
+
.leftJoin(
|
|
150
|
+
'cr_communication_config',
|
|
151
|
+
'config',
|
|
152
|
+
'config.id = hub.config_id',
|
|
153
|
+
)
|
|
150
154
|
.select([
|
|
151
155
|
'hub.id as hub_id',
|
|
152
156
|
'hub.level_id as hub_level_id',
|
|
@@ -219,7 +223,11 @@ export class CommunicationService {
|
|
|
219
223
|
hub.provider,
|
|
220
224
|
);
|
|
221
225
|
|
|
222
|
-
const result = await strategy.sendMessage(
|
|
226
|
+
const result = await strategy.sendMessage(
|
|
227
|
+
to,
|
|
228
|
+
message,
|
|
229
|
+
hub.config.config_json,
|
|
230
|
+
);
|
|
223
231
|
|
|
224
232
|
// If token was refreshed, update it in the database
|
|
225
233
|
if (result.refreshedToken && result.success) {
|
|
@@ -229,11 +237,11 @@ export class CommunicationService {
|
|
|
229
237
|
...currentConfig,
|
|
230
238
|
accessToken: result.refreshedToken,
|
|
231
239
|
};
|
|
232
|
-
|
|
240
|
+
|
|
233
241
|
await this.configRepository.update(hub.config.id, {
|
|
234
242
|
config_json: updatedConfig,
|
|
235
243
|
} as any);
|
|
236
|
-
|
|
244
|
+
|
|
237
245
|
this.logger.log(
|
|
238
246
|
`Updated access token for ${hub.provider}/${hub.service} configuration`,
|
|
239
247
|
);
|
|
@@ -309,13 +317,11 @@ export class CommunicationService {
|
|
|
309
317
|
);
|
|
310
318
|
}
|
|
311
319
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}[]
|
|
318
|
-
> {
|
|
320
|
+
getSupportedCombinations(): {
|
|
321
|
+
mode: string;
|
|
322
|
+
service: string;
|
|
323
|
+
provider: string;
|
|
324
|
+
}[] {
|
|
319
325
|
return this.communicationFactory.getAllSupportedCombinations();
|
|
320
326
|
}
|
|
321
327
|
|
|
@@ -327,8 +333,10 @@ export class CommunicationService {
|
|
|
327
333
|
service?: 'API' | 'THIRD_PARTY' | 'SMTP';
|
|
328
334
|
provider?: string;
|
|
329
335
|
},
|
|
330
|
-
): Promise<
|
|
331
|
-
|
|
336
|
+
): Promise<
|
|
337
|
+
Array<CommunicationHub & { linkedSource?: string; configDetails?: any }>
|
|
338
|
+
> {
|
|
339
|
+
const where: any = { level_id: levelId, level_type: levelType, status: 1 };
|
|
332
340
|
|
|
333
341
|
if (filters?.communication_config_type) {
|
|
334
342
|
where.communication_config_type = filters.communication_config_type;
|
|
@@ -342,10 +350,297 @@ export class CommunicationService {
|
|
|
342
350
|
where.provider = filters.provider;
|
|
343
351
|
}
|
|
344
352
|
|
|
345
|
-
|
|
353
|
+
const hubs = await this.hubRepository.find({
|
|
346
354
|
where,
|
|
347
355
|
order: { created_at: 'DESC' },
|
|
348
356
|
});
|
|
357
|
+
|
|
358
|
+
// Enhance hubs with linked source information
|
|
359
|
+
const enhancedHubs = await Promise.all(
|
|
360
|
+
hubs.map(async (hub) => {
|
|
361
|
+
try {
|
|
362
|
+
const config = await this.configRepository.findOne({
|
|
363
|
+
where: { id: hub.config_id },
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
if (!config) {
|
|
367
|
+
return {
|
|
368
|
+
...hub,
|
|
369
|
+
linkedSource: 'Configuration not found',
|
|
370
|
+
configDetails: null,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const linkedSource = this.extractLinkedSource(
|
|
375
|
+
hub.communication_config_type,
|
|
376
|
+
hub.service,
|
|
377
|
+
hub.provider,
|
|
378
|
+
config.config_json,
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
const configDetails = this.extractConfigDetails(
|
|
382
|
+
hub.communication_config_type,
|
|
383
|
+
hub.service,
|
|
384
|
+
hub.provider,
|
|
385
|
+
config.config_json,
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
return {
|
|
389
|
+
...hub,
|
|
390
|
+
linkedSource,
|
|
391
|
+
configDetails,
|
|
392
|
+
};
|
|
393
|
+
} catch (error) {
|
|
394
|
+
this.logger.warn(
|
|
395
|
+
`Error extracting linked source for hub ${hub.id}:`,
|
|
396
|
+
error.message,
|
|
397
|
+
);
|
|
398
|
+
return {
|
|
399
|
+
...hub,
|
|
400
|
+
linkedSource: 'Error retrieving source',
|
|
401
|
+
configDetails: null,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}),
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
return enhancedHubs;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
private extractLinkedSource(
|
|
411
|
+
configType: string,
|
|
412
|
+
service: string,
|
|
413
|
+
provider: string,
|
|
414
|
+
configJson: any,
|
|
415
|
+
): string {
|
|
416
|
+
const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
switch (key) {
|
|
420
|
+
// Gmail configurations
|
|
421
|
+
case 'email_api_gmail':
|
|
422
|
+
case 'email_smtp_gmail':
|
|
423
|
+
return configJson?.email || 'Gmail account not configured';
|
|
424
|
+
|
|
425
|
+
// Outlook configurations
|
|
426
|
+
case 'email_api_outlook':
|
|
427
|
+
case 'email_smtp_outlook':
|
|
428
|
+
return configJson?.email || 'Outlook account not configured';
|
|
429
|
+
|
|
430
|
+
// WhatsApp configurations
|
|
431
|
+
case 'wa_api_whatsapp':
|
|
432
|
+
return configJson?.phoneNumberId
|
|
433
|
+
? `WhatsApp Business: ${configJson.phoneNumberId}`
|
|
434
|
+
: 'WhatsApp not configured';
|
|
435
|
+
|
|
436
|
+
// SMS configurations
|
|
437
|
+
case 'sms_third_party_twilio':
|
|
438
|
+
return configJson?.fromNumber
|
|
439
|
+
? `Twilio: ${configJson.fromNumber}`
|
|
440
|
+
: 'Twilio number not configured';
|
|
441
|
+
|
|
442
|
+
case 'sms_third_party_knowlarity':
|
|
443
|
+
return configJson?.callerNumber
|
|
444
|
+
? `Knowlarity: ${configJson.callerNumber}`
|
|
445
|
+
: 'Knowlarity number not configured';
|
|
446
|
+
|
|
447
|
+
// Telephone configurations
|
|
448
|
+
case 'telephone_third_party_knowlarity':
|
|
449
|
+
return configJson?.callerNumber
|
|
450
|
+
? `Knowlarity Voice: ${configJson.callerNumber}`
|
|
451
|
+
: 'Knowlarity voice number not configured';
|
|
452
|
+
|
|
453
|
+
// AWS SES configurations
|
|
454
|
+
case 'email_api_aws-ses':
|
|
455
|
+
case 'email_api_ses':
|
|
456
|
+
return configJson?.fromEmail || 'AWS SES not configured';
|
|
457
|
+
|
|
458
|
+
// SendGrid configurations
|
|
459
|
+
case 'email_smtp_sendgrid':
|
|
460
|
+
return configJson?.from || 'SendGrid not configured';
|
|
461
|
+
|
|
462
|
+
// Generic SMTP configurations
|
|
463
|
+
case 'email_smtp_custom':
|
|
464
|
+
case 'email_smtp_generic':
|
|
465
|
+
return configJson?.from || configJson?.user || 'SMTP not configured';
|
|
466
|
+
|
|
467
|
+
default:
|
|
468
|
+
// Generic fallback - try to find common identifier fields
|
|
469
|
+
if (configJson?.email) return configJson.email;
|
|
470
|
+
if (configJson?.from) return configJson.from;
|
|
471
|
+
if (configJson?.user) return configJson.user;
|
|
472
|
+
if (configJson?.phoneNumberId) return configJson.phoneNumberId;
|
|
473
|
+
if (configJson?.fromNumber) return configJson.fromNumber;
|
|
474
|
+
if (configJson?.callerNumber) return configJson.callerNumber;
|
|
475
|
+
|
|
476
|
+
return `${provider} configured`;
|
|
477
|
+
}
|
|
478
|
+
} catch (error) {
|
|
479
|
+
return 'Configuration error';
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
private extractConfigDetails(
|
|
484
|
+
configType: string,
|
|
485
|
+
service: string,
|
|
486
|
+
provider: string,
|
|
487
|
+
configJson: any,
|
|
488
|
+
): any {
|
|
489
|
+
const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
|
|
490
|
+
|
|
491
|
+
try {
|
|
492
|
+
switch (key) {
|
|
493
|
+
// Gmail configurations
|
|
494
|
+
case 'email_api_gmail':
|
|
495
|
+
return {
|
|
496
|
+
email: configJson?.email,
|
|
497
|
+
authMethod: configJson?.authMethod || 'OAUTH2',
|
|
498
|
+
hasRefreshToken: !!configJson?.refreshToken,
|
|
499
|
+
isExpired: configJson?.expiryDate
|
|
500
|
+
? new Date(configJson.expiryDate) < new Date()
|
|
501
|
+
: false,
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
case 'email_smtp_gmail':
|
|
505
|
+
return {
|
|
506
|
+
email: configJson?.email,
|
|
507
|
+
authMethod: 'SMTP',
|
|
508
|
+
hasPassword: !!configJson?.password,
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
// Outlook configurations
|
|
512
|
+
case 'email_api_outlook':
|
|
513
|
+
return {
|
|
514
|
+
email: configJson?.email,
|
|
515
|
+
authMethod: 'OAUTH2',
|
|
516
|
+
hasRefreshToken: !!configJson?.refreshToken,
|
|
517
|
+
tenantId: configJson?.tenantId,
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
case 'email_smtp_outlook':
|
|
521
|
+
return {
|
|
522
|
+
email: configJson?.email,
|
|
523
|
+
authMethod: 'SMTP',
|
|
524
|
+
hasPassword: !!configJson?.password,
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
// WhatsApp configurations
|
|
528
|
+
case 'wa_api_whatsapp':
|
|
529
|
+
return {
|
|
530
|
+
phoneNumberId: configJson?.phoneNumberId,
|
|
531
|
+
apiVersion: configJson?.apiVersion || 'v17.0',
|
|
532
|
+
hasAccessToken: !!configJson?.accessToken,
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
// SMS configurations
|
|
536
|
+
case 'sms_third_party_twilio':
|
|
537
|
+
return {
|
|
538
|
+
fromNumber: configJson?.fromNumber,
|
|
539
|
+
accountSid: configJson?.accountSid
|
|
540
|
+
? configJson.accountSid.substring(0, 8) + '...'
|
|
541
|
+
: null,
|
|
542
|
+
hasAuthToken: !!configJson?.authToken,
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
case 'sms_third_party_knowlarity':
|
|
546
|
+
return {
|
|
547
|
+
callerNumber: configJson?.callerNumber,
|
|
548
|
+
callType: configJson?.callType || 'sms',
|
|
549
|
+
hasApiSecret: !!configJson?.apiSecret,
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
// Telephone configurations
|
|
553
|
+
case 'telephone_third_party_knowlarity':
|
|
554
|
+
return {
|
|
555
|
+
callerNumber: configJson?.callerNumber,
|
|
556
|
+
callType: configJson?.callType || 'voice',
|
|
557
|
+
language: configJson?.language || 'en',
|
|
558
|
+
hasApiSecret: !!configJson?.apiSecret,
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
// AWS SES configurations
|
|
562
|
+
case 'email_api_aws-ses':
|
|
563
|
+
case 'email_api_ses':
|
|
564
|
+
return {
|
|
565
|
+
fromEmail: configJson?.fromEmail,
|
|
566
|
+
region: configJson?.region,
|
|
567
|
+
hasCredentials: !!(
|
|
568
|
+
configJson?.accessKeyId && configJson?.secretAccessKey
|
|
569
|
+
),
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// SendGrid configurations
|
|
573
|
+
case 'email_smtp_sendgrid':
|
|
574
|
+
return {
|
|
575
|
+
from: configJson?.from,
|
|
576
|
+
hasApiKey: !!configJson?.apiKey,
|
|
577
|
+
templateId: configJson?.templateId,
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
// Generic SMTP configurations
|
|
581
|
+
case 'email_smtp_custom':
|
|
582
|
+
case 'email_smtp_generic':
|
|
583
|
+
return {
|
|
584
|
+
host: configJson?.host,
|
|
585
|
+
port: configJson?.port || 587,
|
|
586
|
+
secure: configJson?.secure || false,
|
|
587
|
+
from: configJson?.from || configJson?.user,
|
|
588
|
+
hasCredentials: !!(configJson?.user && configJson?.password),
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
default:
|
|
592
|
+
// Generic details - return safe subset of config
|
|
593
|
+
const safeConfig: any = {};
|
|
594
|
+
|
|
595
|
+
// Include non-sensitive fields
|
|
596
|
+
const safeFields = [
|
|
597
|
+
'email',
|
|
598
|
+
'from',
|
|
599
|
+
'user',
|
|
600
|
+
'host',
|
|
601
|
+
'port',
|
|
602
|
+
'secure',
|
|
603
|
+
'phoneNumberId',
|
|
604
|
+
'fromNumber',
|
|
605
|
+
'callerNumber',
|
|
606
|
+
'region',
|
|
607
|
+
'apiVersion',
|
|
608
|
+
'callType',
|
|
609
|
+
'language',
|
|
610
|
+
'templateId',
|
|
611
|
+
];
|
|
612
|
+
|
|
613
|
+
safeFields.forEach((field) => {
|
|
614
|
+
if (configJson?.[field]) {
|
|
615
|
+
safeConfig[field] = configJson[field];
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// Include boolean indicators for sensitive fields
|
|
620
|
+
const sensitiveFields = [
|
|
621
|
+
'accessToken',
|
|
622
|
+
'refreshToken',
|
|
623
|
+
'password',
|
|
624
|
+
'authToken',
|
|
625
|
+
'apiKey',
|
|
626
|
+
'apiSecret',
|
|
627
|
+
'clientSecret',
|
|
628
|
+
'secretAccessKey',
|
|
629
|
+
];
|
|
630
|
+
|
|
631
|
+
sensitiveFields.forEach((field) => {
|
|
632
|
+
if (configJson?.[field]) {
|
|
633
|
+
safeConfig[
|
|
634
|
+
`has${field.charAt(0).toUpperCase() + field.slice(1)}`
|
|
635
|
+
] = true;
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
return safeConfig;
|
|
640
|
+
}
|
|
641
|
+
} catch (error) {
|
|
642
|
+
return { error: 'Unable to extract configuration details' };
|
|
643
|
+
}
|
|
349
644
|
}
|
|
350
645
|
|
|
351
646
|
async updateConfigStatus(hubId: number, status: number): Promise<void> {
|
|
@@ -385,7 +680,7 @@ export class CommunicationService {
|
|
|
385
680
|
|
|
386
681
|
if (!hubs.length) {
|
|
387
682
|
this.logger.warn(
|
|
388
|
-
`No communication hubs found for ${levelType} ${levelId}. Please configure communication providers using the createCommunicationConfig method
|
|
683
|
+
`No communication hubs found for ${levelType} ${levelId}. Please configure communication providers using the createCommunicationConfig method.`,
|
|
389
684
|
);
|
|
390
685
|
throw new Error(
|
|
391
686
|
`No active ${communicationType} configuration found for ${levelType} ${levelId}. Please configure a communication provider first.`,
|
|
@@ -1293,7 +1588,11 @@ export class CommunicationService {
|
|
|
1293
1588
|
|
|
1294
1589
|
async queueMessage(
|
|
1295
1590
|
messageDto: GenericMessageDto & { useQueue?: boolean; scheduledFor?: Date },
|
|
1296
|
-
): Promise<{
|
|
1591
|
+
): Promise<{
|
|
1592
|
+
queued: boolean;
|
|
1593
|
+
messageId?: string;
|
|
1594
|
+
result?: CommunicationResult;
|
|
1595
|
+
}> {
|
|
1297
1596
|
if (!this.queueService || !messageDto.useQueue) {
|
|
1298
1597
|
// Fallback to immediate sending if queue is not available or not requested
|
|
1299
1598
|
const result = await this.sendGenericMessage(messageDto);
|
|
@@ -1325,7 +1624,10 @@ export class CommunicationService {
|
|
|
1325
1624
|
|
|
1326
1625
|
return { queued: true, messageId };
|
|
1327
1626
|
} catch (error) {
|
|
1328
|
-
this.logger.error(
|
|
1627
|
+
this.logger.error(
|
|
1628
|
+
'Error queuing message, falling back to immediate send:',
|
|
1629
|
+
error.message,
|
|
1630
|
+
);
|
|
1329
1631
|
// Fallback to immediate sending
|
|
1330
1632
|
const result = await this.sendGenericMessage(messageDto);
|
|
1331
1633
|
return { queued: false, result };
|
|
@@ -1361,7 +1663,10 @@ export class CommunicationService {
|
|
|
1361
1663
|
|
|
1362
1664
|
return { queued: true, messageIds };
|
|
1363
1665
|
} catch (error) {
|
|
1364
|
-
this.logger.error(
|
|
1666
|
+
this.logger.error(
|
|
1667
|
+
'Error queuing bulk message, falling back to immediate send:',
|
|
1668
|
+
error.message,
|
|
1669
|
+
);
|
|
1365
1670
|
// Fallback to immediate sending
|
|
1366
1671
|
const result = await this.sendBulkMessage(bulkDto);
|
|
1367
1672
|
return { queued: false, result };
|
|
@@ -1391,7 +1696,9 @@ export class CommunicationService {
|
|
|
1391
1696
|
return this.queueService.cancelMessage(messageId);
|
|
1392
1697
|
}
|
|
1393
1698
|
|
|
1394
|
-
private mapPriorityToSimpleQueue(
|
|
1699
|
+
private mapPriorityToSimpleQueue(
|
|
1700
|
+
priority?: string,
|
|
1701
|
+
): 'high' | 'medium' | 'low' {
|
|
1395
1702
|
switch (priority?.toLowerCase()) {
|
|
1396
1703
|
case 'high':
|
|
1397
1704
|
case 'urgent':
|
|
@@ -31,7 +31,6 @@ export class UserController {
|
|
|
31
31
|
@HttpCode(HttpStatus.OK)
|
|
32
32
|
async checkEmail(@Body() body, @Res() res: Response) {
|
|
33
33
|
const { email_id, subdomain } = body;
|
|
34
|
-
console.log(body, 'body-----------------------------body');
|
|
35
34
|
const result = await this.userService.checkEmailExists({
|
|
36
35
|
email_id,
|
|
37
36
|
subdomain,
|