rez_core 2.2.154 → 2.2.156

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 (142) hide show
  1. package/dist/app.module.js +2 -0
  2. package/dist/app.module.js.map +1 -1
  3. package/dist/constant/global.constant.d.ts +1 -1
  4. package/dist/constant/global.constant.js +1 -1
  5. package/dist/constant/global.constant.js.map +1 -1
  6. package/dist/module/auth/strategies/google.strategy.js +1 -1
  7. package/dist/module/auth/strategies/google.strategy.js.map +1 -1
  8. package/dist/module/communication/communication.module.d.ts +2 -0
  9. package/dist/module/communication/communication.module.js +69 -0
  10. package/dist/module/communication/communication.module.js.map +1 -0
  11. package/dist/module/communication/controller/communication.controller.d.ts +54 -0
  12. package/dist/module/communication/controller/communication.controller.js +148 -0
  13. package/dist/module/communication/controller/communication.controller.js.map +1 -0
  14. package/dist/module/communication/dto/create-config.dto.d.ts +91 -0
  15. package/dist/module/communication/dto/create-config.dto.js +243 -0
  16. package/dist/module/communication/dto/create-config.dto.js.map +1 -0
  17. package/dist/module/communication/entity/communication-config.entity.d.ts +44 -0
  18. package/dist/module/communication/entity/communication-config.entity.js +45 -0
  19. package/dist/module/communication/entity/communication-config.entity.js.map +1 -0
  20. package/dist/module/communication/entity/communication-hub.entity.d.ts +20 -0
  21. package/dist/module/communication/entity/communication-hub.entity.js +105 -0
  22. package/dist/module/communication/entity/communication-hub.entity.js.map +1 -0
  23. package/dist/module/communication/examples/usage.example.d.ts +11 -0
  24. package/dist/module/communication/examples/usage.example.js +89 -0
  25. package/dist/module/communication/examples/usage.example.js.map +1 -0
  26. package/dist/module/communication/factories/base.factory.d.ts +9 -0
  27. package/dist/module/communication/factories/base.factory.js +3 -0
  28. package/dist/module/communication/factories/base.factory.js.map +1 -0
  29. package/dist/module/communication/factories/communication.factory.d.ts +33 -0
  30. package/dist/module/communication/factories/communication.factory.js +104 -0
  31. package/dist/module/communication/factories/communication.factory.js.map +1 -0
  32. package/dist/module/communication/factories/email.factory.d.ts +19 -0
  33. package/dist/module/communication/factories/email.factory.js +61 -0
  34. package/dist/module/communication/factories/email.factory.js.map +1 -0
  35. package/dist/module/communication/factories/sms.factory.d.ts +15 -0
  36. package/dist/module/communication/factories/sms.factory.js +49 -0
  37. package/dist/module/communication/factories/sms.factory.js.map +1 -0
  38. package/dist/module/communication/factories/telephone.factory.d.ts +13 -0
  39. package/dist/module/communication/factories/telephone.factory.js +43 -0
  40. package/dist/module/communication/factories/telephone.factory.js.map +1 -0
  41. package/dist/module/communication/factories/whatsapp.factory.d.ts +13 -0
  42. package/dist/module/communication/factories/whatsapp.factory.js +43 -0
  43. package/dist/module/communication/factories/whatsapp.factory.js.map +1 -0
  44. package/dist/module/communication/service/communication.service.d.ts +111 -0
  45. package/dist/module/communication/service/communication.service.js +726 -0
  46. package/dist/module/communication/service/communication.service.js.map +1 -0
  47. package/dist/module/communication/service/oauth.service.d.ts +18 -0
  48. package/dist/module/communication/service/oauth.service.js +185 -0
  49. package/dist/module/communication/service/oauth.service.js.map +1 -0
  50. package/dist/module/communication/strategies/communication.strategy.d.ts +17 -0
  51. package/dist/module/communication/strategies/communication.strategy.js +3 -0
  52. package/dist/module/communication/strategies/communication.strategy.js.map +1 -0
  53. package/dist/module/communication/strategies/email/gmail-api.strategy.d.ts +7 -0
  54. package/dist/module/communication/strategies/email/gmail-api.strategy.js +135 -0
  55. package/dist/module/communication/strategies/email/gmail-api.strategy.js.map +1 -0
  56. package/dist/module/communication/strategies/email/gmail-smtp.strategy.d.ts +5 -0
  57. package/dist/module/communication/strategies/email/gmail-smtp.strategy.js +49 -0
  58. package/dist/module/communication/strategies/email/gmail-smtp.strategy.js.map +1 -0
  59. package/dist/module/communication/strategies/email/outlook-api.strategy.d.ts +5 -0
  60. package/dist/module/communication/strategies/email/outlook-api.strategy.js +44 -0
  61. package/dist/module/communication/strategies/email/outlook-api.strategy.js.map +1 -0
  62. package/dist/module/communication/strategies/gmail-smtp.strategy.d.ts +5 -0
  63. package/dist/module/communication/strategies/gmail-smtp.strategy.js +61 -0
  64. package/dist/module/communication/strategies/gmail-smtp.strategy.js.map +1 -0
  65. package/dist/module/communication/strategies/gmail.strategy.d.ts +5 -0
  66. package/dist/module/communication/strategies/gmail.strategy.js +71 -0
  67. package/dist/module/communication/strategies/gmail.strategy.js.map +1 -0
  68. package/dist/module/communication/strategies/knowlarity.strategy.d.ts +6 -0
  69. package/dist/module/communication/strategies/knowlarity.strategy.js +115 -0
  70. package/dist/module/communication/strategies/knowlarity.strategy.js.map +1 -0
  71. package/dist/module/communication/strategies/outlook-smtp.strategy.d.ts +5 -0
  72. package/dist/module/communication/strategies/outlook-smtp.strategy.js +66 -0
  73. package/dist/module/communication/strategies/outlook-smtp.strategy.js.map +1 -0
  74. package/dist/module/communication/strategies/outlook.strategy.d.ts +5 -0
  75. package/dist/module/communication/strategies/outlook.strategy.js +64 -0
  76. package/dist/module/communication/strategies/outlook.strategy.js.map +1 -0
  77. package/dist/module/communication/strategies/sms/knowlarity.strategy.d.ts +5 -0
  78. package/dist/module/communication/strategies/sms/knowlarity.strategy.js +44 -0
  79. package/dist/module/communication/strategies/sms/knowlarity.strategy.js.map +1 -0
  80. package/dist/module/communication/strategies/sms/twilio.strategy.d.ts +5 -0
  81. package/dist/module/communication/strategies/sms/twilio.strategy.js +44 -0
  82. package/dist/module/communication/strategies/sms/twilio.strategy.js.map +1 -0
  83. package/dist/module/communication/strategies/sms.strategy.d.ts +5 -0
  84. package/dist/module/communication/strategies/sms.strategy.js +50 -0
  85. package/dist/module/communication/strategies/sms.strategy.js.map +1 -0
  86. package/dist/module/communication/strategies/telephone/knowlarity-voice.strategy.d.ts +5 -0
  87. package/dist/module/communication/strategies/telephone/knowlarity-voice.strategy.js +44 -0
  88. package/dist/module/communication/strategies/telephone/knowlarity-voice.strategy.js.map +1 -0
  89. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.d.ts +5 -0
  90. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js +47 -0
  91. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js.map +1 -0
  92. package/dist/module/communication/strategies/whatsapp.strategy.d.ts +5 -0
  93. package/dist/module/communication/strategies/whatsapp.strategy.js +58 -0
  94. package/dist/module/communication/strategies/whatsapp.strategy.js.map +1 -0
  95. package/dist/module/meta/entity.module.js +2 -1
  96. package/dist/module/meta/entity.module.js.map +1 -1
  97. package/dist/module/user/controller/login.controller.d.ts +4 -2
  98. package/dist/module/user/controller/login.controller.js +26 -4
  99. package/dist/module/user/controller/login.controller.js.map +1 -1
  100. package/dist/module/workflow/service/populate-workflow.service.js +2 -2
  101. package/dist/module/workflow/service/populate-workflow.service.js.map +1 -1
  102. package/dist/module/workflow/service/stage.service.js +1 -1
  103. package/dist/module/workflow/service/stage.service.js.map +1 -1
  104. package/dist/tsconfig.build.tsbuildinfo +1 -1
  105. package/package.json +4 -1
  106. package/src/app.module.ts +2 -0
  107. package/src/constant/global.constant.ts +1 -1
  108. package/src/module/auth/strategies/google.strategy.ts +1 -1
  109. package/src/module/communication/communication.module.ts +77 -0
  110. package/src/module/communication/controller/communication.controller.ts +122 -0
  111. package/src/module/communication/dto/create-config.dto.ts +234 -0
  112. package/src/module/communication/entity/communication-config.entity.ts +80 -0
  113. package/src/module/communication/entity/communication-hub.entity.ts +77 -0
  114. package/src/module/communication/examples/usage.example.ts +169 -0
  115. package/src/module/communication/factories/base.factory.ts +7 -0
  116. package/src/module/communication/factories/communication.factory.ts +103 -0
  117. package/src/module/communication/factories/email.factory.ts +51 -0
  118. package/src/module/communication/factories/sms.factory.ts +41 -0
  119. package/src/module/communication/factories/telephone.factory.ts +34 -0
  120. package/src/module/communication/factories/whatsapp.factory.ts +34 -0
  121. package/src/module/communication/service/communication.service.ts +1118 -0
  122. package/src/module/communication/service/oauth.service.ts +203 -0
  123. package/src/module/communication/strategies/communication.strategy.ts +23 -0
  124. package/src/module/communication/strategies/email/gmail-api.strategy.ts +161 -0
  125. package/src/module/communication/strategies/email/gmail-smtp.strategy.ts +51 -0
  126. package/src/module/communication/strategies/email/outlook-api.strategy.ts +44 -0
  127. package/src/module/communication/strategies/gmail-smtp.strategy.ts +64 -0
  128. package/src/module/communication/strategies/gmail.strategy.ts +68 -0
  129. package/src/module/communication/strategies/knowlarity.strategy.ts +124 -0
  130. package/src/module/communication/strategies/outlook-smtp.strategy.ts +69 -0
  131. package/src/module/communication/strategies/outlook.strategy.ts +57 -0
  132. package/src/module/communication/strategies/sms/knowlarity.strategy.ts +44 -0
  133. package/src/module/communication/strategies/sms/twilio.strategy.ts +44 -0
  134. package/src/module/communication/strategies/sms.strategy.ts +44 -0
  135. package/src/module/communication/strategies/telephone/knowlarity-voice.strategy.ts +44 -0
  136. package/src/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.ts +49 -0
  137. package/src/module/communication/strategies/whatsapp.strategy.ts +53 -0
  138. package/src/module/meta/entity.module.ts +2 -1
  139. package/src/module/user/controller/login.controller.ts +34 -3
  140. package/src/module/workflow/service/populate-workflow.service.ts +3 -3
  141. package/src/module/workflow/service/stage.service.ts +1 -1
  142. package/src/resources/dev.properties.yaml +1 -0
@@ -0,0 +1,726 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var CommunicationService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.CommunicationService = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const typeorm_1 = require("@nestjs/typeorm");
19
+ const typeorm_2 = require("typeorm");
20
+ const config_1 = require("@nestjs/config");
21
+ const googleapis_1 = require("googleapis");
22
+ const communication_hub_entity_1 = require("../entity/communication-hub.entity");
23
+ const communication_config_entity_1 = require("../entity/communication-config.entity");
24
+ const communication_factory_1 = require("../factories/communication.factory");
25
+ const gmail_api_strategy_1 = require("../strategies/email/gmail-api.strategy");
26
+ let CommunicationService = CommunicationService_1 = class CommunicationService {
27
+ constructor(hubRepository, configRepository, communicationFactory, gmailApiStrategy, configService) {
28
+ this.hubRepository = hubRepository;
29
+ this.configRepository = configRepository;
30
+ this.communicationFactory = communicationFactory;
31
+ this.gmailApiStrategy = gmailApiStrategy;
32
+ this.configService = configService;
33
+ this.logger = new common_1.Logger(CommunicationService_1.name);
34
+ this.gmailOAuthStates = new Map();
35
+ }
36
+ async sendMessage({ levelId, levelType, to, message, mode, priority = 1, }) {
37
+ try {
38
+ const hubs = await this.getActiveHubs(levelId, levelType, mode);
39
+ if (!hubs.length) {
40
+ throw new Error(`No active communication configuration found for ${levelType} ${levelId}`);
41
+ }
42
+ const sortedHubs = this.sortHubsByPriority(hubs, priority);
43
+ for (const hub of sortedHubs) {
44
+ try {
45
+ const result = await this.sendViaHub(hub, to, message);
46
+ if (result.success) {
47
+ this.logger.log(`Message sent successfully via ${hub.provider}/${hub.service}`);
48
+ return result;
49
+ }
50
+ this.logger.warn(`Failed to send via ${hub.provider}/${hub.service}: ${result.error}`);
51
+ }
52
+ catch (error) {
53
+ this.logger.error(`Error sending via ${hub.provider}/${hub.service}:`, error.message);
54
+ continue;
55
+ }
56
+ }
57
+ throw new Error('All communication providers failed');
58
+ }
59
+ catch (error) {
60
+ this.logger.error('Communication service error:', error.message);
61
+ throw error;
62
+ }
63
+ }
64
+ async getActiveHubs(levelId, levelType, mode) {
65
+ let query = this.hubRepository
66
+ .createQueryBuilder('hub')
67
+ .leftJoin('communication_config', 'config', 'config.id = hub.config_id')
68
+ .select([
69
+ 'hub.id',
70
+ 'hub.status',
71
+ 'hub.config_id',
72
+ 'hub.communication_config_type',
73
+ 'hub.service',
74
+ 'hub.provider',
75
+ 'hub.priority',
76
+ 'hub.is_default',
77
+ 'hub.created_at',
78
+ 'hub.updated_at',
79
+ 'config.id as config_id',
80
+ 'config.config_json as config_json',
81
+ 'config.created_at as config_created_at',
82
+ 'config.updated_at as config_updated_at'
83
+ ])
84
+ .where('hub.level_id = :levelId', { levelId })
85
+ .andWhere('hub.level_type = :levelType', { levelType })
86
+ .andWhere('hub.status = :status', { status: 1 });
87
+ if (mode) {
88
+ query = query.andWhere('hub.communication_config_type = :mode', { mode });
89
+ }
90
+ const results = await query.getRawMany();
91
+ const hubsWithConfig = results.map(row => ({
92
+ id: row.hub_id,
93
+ level_id: row.hub_level_id,
94
+ level_type: row.hub_level_type,
95
+ status: row.hub_status,
96
+ config_id: row.hub_config_id,
97
+ communication_config_type: row.hub_communication_config_type,
98
+ service: row.hub_service,
99
+ provider: row.hub_provider,
100
+ priority: row.hub_priority || 1,
101
+ is_default: row.hub_is_default || false,
102
+ created_at: row.hub_created_at,
103
+ updated_at: row.hub_updated_at,
104
+ config: {
105
+ id: row.config_id,
106
+ config_json: row.config_json,
107
+ created_at: row.config_created_at,
108
+ updated_at: row.config_updated_at,
109
+ },
110
+ }));
111
+ return hubsWithConfig;
112
+ }
113
+ sortHubsByPriority(hubs, _priority) {
114
+ return hubs;
115
+ }
116
+ async sendViaHub(hub, to, message) {
117
+ const strategy = this.communicationFactory.create(hub.communication_config_type, hub.service, hub.provider);
118
+ return strategy.sendMessage(to, message, hub.config.config_json);
119
+ }
120
+ async createCommunicationConfig(levelId, levelType, configType, service, provider, config, priority, is_default) {
121
+ const supportedCombinations = await this.getSupportedCombinations();
122
+ const isValidCombination = supportedCombinations.some(combo => combo.mode === configType &&
123
+ combo.service.toLowerCase() === service.toLowerCase() &&
124
+ combo.provider.toLowerCase() === provider.toLowerCase());
125
+ if (!isValidCombination) {
126
+ throw new Error(`Unsupported combination: ${configType}/${service}/${provider}`);
127
+ }
128
+ const requiresOAuth = this.requiresOAuthFlow(configType, service, provider, config);
129
+ if (requiresOAuth) {
130
+ return await this.generateOAuthUrl(levelId, levelType, configType, service, provider, config, priority, is_default);
131
+ }
132
+ return await this.createDirectConfig(levelId, levelType, configType, service, provider, config, priority, is_default);
133
+ }
134
+ async getSupportedCombinations() {
135
+ return this.communicationFactory.getAllSupportedCombinations();
136
+ }
137
+ async getLevelConfigs(levelId, levelType) {
138
+ return this.hubRepository.find({
139
+ where: { level_id: levelId, level_type: levelType },
140
+ order: { created_at: 'DESC' },
141
+ });
142
+ }
143
+ async updateConfigStatus(hubId, status) {
144
+ await this.hubRepository.update(hubId, { status });
145
+ }
146
+ async sendGenericMessage(messageDto) {
147
+ try {
148
+ const { levelId, levelType, to, message, type, priority = 'medium', subject, html, cc, bcc, attachments, mediaUrl, templateId, variables } = messageDto;
149
+ const communicationType = this.detectCommunicationType(to, type);
150
+ const hubs = await this.getActiveHubs(levelId, levelType, communicationType);
151
+ if (!hubs.length) {
152
+ throw new Error(`No active ${communicationType} configuration found for ${levelType} ${levelId}`);
153
+ }
154
+ const sortedHubs = this.sortHubsByPriorityAndDefault(hubs, priority);
155
+ const enhancedConfig = {
156
+ subject,
157
+ html,
158
+ cc,
159
+ bcc,
160
+ attachments,
161
+ mediaUrl,
162
+ };
163
+ if (Array.isArray(to)) {
164
+ const results = [];
165
+ let hasSuccess = false;
166
+ for (const recipient of to) {
167
+ for (const hub of sortedHubs) {
168
+ try {
169
+ const strategy = this.communicationFactory.create(hub.communication_config_type, hub.service, hub.provider);
170
+ let processedMessage = message;
171
+ if (templateId && variables) {
172
+ processedMessage = this.processTemplate(message, variables);
173
+ }
174
+ const finalConfig = { ...hub.config.config_json, ...enhancedConfig };
175
+ const result = await strategy.sendMessage(recipient, processedMessage, finalConfig);
176
+ if (result.success) {
177
+ this.logger.log(`Generic message sent successfully via ${hub.provider}/${hub.service} to ${recipient}`);
178
+ results.push(result);
179
+ hasSuccess = true;
180
+ break;
181
+ }
182
+ this.logger.warn(`Failed to send via ${hub.provider}/${hub.service} to ${recipient}: ${result.error}`);
183
+ }
184
+ catch (error) {
185
+ this.logger.error(`Error sending via ${hub.provider}/${hub.service} to ${recipient}:`, error.message);
186
+ continue;
187
+ }
188
+ }
189
+ }
190
+ if (hasSuccess) {
191
+ return {
192
+ success: true,
193
+ messageId: results.map(r => r.messageId).join(','),
194
+ provider: 'multiple',
195
+ service: 'multiple',
196
+ timestamp: new Date(),
197
+ };
198
+ }
199
+ }
200
+ else {
201
+ for (const hub of sortedHubs) {
202
+ try {
203
+ const strategy = this.communicationFactory.create(hub.communication_config_type, hub.service, hub.provider);
204
+ let processedMessage = message;
205
+ if (templateId && variables) {
206
+ processedMessage = this.processTemplate(message, variables);
207
+ }
208
+ const finalConfig = { ...hub.config.config_json, ...enhancedConfig };
209
+ const result = await strategy.sendMessage(to, processedMessage, finalConfig);
210
+ if (result.success) {
211
+ this.logger.log(`Generic message sent successfully via ${hub.provider}/${hub.service} to ${to}`);
212
+ return result;
213
+ }
214
+ this.logger.warn(`Failed to send via ${hub.provider}/${hub.service}: ${result.error}`);
215
+ }
216
+ catch (error) {
217
+ this.logger.error(`Error sending via ${hub.provider}/${hub.service}:`, error.message);
218
+ continue;
219
+ }
220
+ }
221
+ }
222
+ throw new Error('All communication providers failed');
223
+ }
224
+ catch (error) {
225
+ this.logger.error('Generic communication service error:', error.message);
226
+ throw error;
227
+ }
228
+ }
229
+ async sendBulkMessage(bulkDto) {
230
+ try {
231
+ const { levelId, levelType, recipients, message, type, priority = 'low', subject, html, templateId, variables, batchSize = 10 } = bulkDto;
232
+ const results = [];
233
+ const batches = this.chunkArray(recipients, batchSize);
234
+ for (let i = 0; i < batches.length; i++) {
235
+ const batch = batches[i];
236
+ this.logger.log(`Processing batch ${i + 1}/${batches.length} with ${batch.length} recipients`);
237
+ const batchPromises = batch.map(async (recipient) => {
238
+ try {
239
+ const messageDto = {
240
+ levelId,
241
+ levelType,
242
+ to: recipient,
243
+ message,
244
+ type,
245
+ priority,
246
+ subject,
247
+ html,
248
+ templateId,
249
+ variables,
250
+ };
251
+ return await this.sendGenericMessage(messageDto);
252
+ }
253
+ catch (error) {
254
+ return {
255
+ success: false,
256
+ provider: 'unknown',
257
+ service: 'unknown',
258
+ error: error.message,
259
+ timestamp: new Date(),
260
+ };
261
+ }
262
+ });
263
+ const batchResults = await Promise.allSettled(batchPromises);
264
+ const processedResults = batchResults.map((result) => {
265
+ if (result.status === 'fulfilled') {
266
+ return result.value;
267
+ }
268
+ else {
269
+ return {
270
+ success: false,
271
+ provider: 'unknown',
272
+ service: 'unknown',
273
+ error: result.reason?.message || 'Unknown error',
274
+ timestamp: new Date(),
275
+ };
276
+ }
277
+ });
278
+ results.push(...processedResults);
279
+ if (i < batches.length - 1) {
280
+ await new Promise(resolve => setTimeout(resolve, 1000));
281
+ }
282
+ }
283
+ const summary = {
284
+ total: results.length,
285
+ successful: results.filter(r => r.success).length,
286
+ failed: results.filter(r => !r.success).length,
287
+ successRate: ((results.filter(r => r.success).length / results.length) * 100).toFixed(2) + '%',
288
+ };
289
+ this.logger.log(`Bulk message completed: ${summary.successful}/${summary.total} successful`);
290
+ return { results, summary };
291
+ }
292
+ catch (error) {
293
+ this.logger.error('Bulk communication service error:', error.message);
294
+ throw error;
295
+ }
296
+ }
297
+ async scheduleMessage(scheduledDto) {
298
+ this.logger.log(`Message scheduled for ${scheduledDto.scheduleFor}`);
299
+ return {
300
+ scheduled: true,
301
+ scheduleId: `sched_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,
302
+ };
303
+ }
304
+ async sendTemplateMessage(templateDto) {
305
+ const template = await this.getTemplate(templateDto.templateId);
306
+ const processedMessage = this.processTemplate(template.content, templateDto.variables);
307
+ const processedSubject = template.subject ? this.processTemplate(template.subject, templateDto.variables) : undefined;
308
+ const messageDto = {
309
+ levelId: templateDto.levelId,
310
+ levelType: templateDto.levelType,
311
+ to: templateDto.to,
312
+ message: processedMessage,
313
+ subject: processedSubject,
314
+ type: templateDto.type,
315
+ templateId: templateDto.templateId,
316
+ variables: templateDto.variables,
317
+ };
318
+ return this.sendGenericMessage(messageDto);
319
+ }
320
+ detectCommunicationType(to, type) {
321
+ if (type) {
322
+ return type;
323
+ }
324
+ const recipient = Array.isArray(to) ? to[0] : to;
325
+ if (recipient.includes('@')) {
326
+ return communication_hub_entity_1.CommunicationConfigType.EMAIL;
327
+ }
328
+ if (/^\+?[\d\s\-\(\)]+$/.test(recipient)) {
329
+ return communication_hub_entity_1.CommunicationConfigType.SMS;
330
+ }
331
+ return communication_hub_entity_1.CommunicationConfigType.EMAIL;
332
+ }
333
+ sortHubsByPriorityAndDefault(hubs, _priority) {
334
+ return hubs.sort((a, b) => {
335
+ if (a.is_default !== b.is_default) {
336
+ return b.is_default ? 1 : -1;
337
+ }
338
+ if (a.priority !== b.priority) {
339
+ return a.priority - b.priority;
340
+ }
341
+ return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
342
+ });
343
+ }
344
+ processTemplate(template, variables) {
345
+ return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
346
+ const value = variables[key];
347
+ return value !== undefined ? String(value) : match;
348
+ });
349
+ }
350
+ async getTemplate(templateId) {
351
+ return {
352
+ id: templateId,
353
+ subject: 'Default Subject {{variable}}',
354
+ content: 'Hello {{name}}, this is a template message with {{variable}}.',
355
+ };
356
+ }
357
+ chunkArray(array, chunkSize) {
358
+ const chunks = [];
359
+ for (let i = 0; i < array.length; i += chunkSize) {
360
+ chunks.push(array.slice(i, i + chunkSize));
361
+ }
362
+ return chunks;
363
+ }
364
+ async initGmailOAuth(levelId, levelType, email) {
365
+ try {
366
+ const clientId = this.configService.get('CLIENT_ID');
367
+ const clientSecret = this.configService.get('CLIENT_SECRET');
368
+ if (!clientId || !clientSecret) {
369
+ throw new Error('Gmail OAuth credentials not configured');
370
+ }
371
+ const state = this.generateSecureState();
372
+ const callbackUrl = this.configService.get('CALLBACK_URL') || 'http://localhost:5001/auth/google/callback';
373
+ this.gmailOAuthStates.set(state, {
374
+ levelId,
375
+ levelType,
376
+ email,
377
+ timestamp: Date.now(),
378
+ });
379
+ setTimeout(() => {
380
+ this.gmailOAuthStates.delete(state);
381
+ }, 10 * 60 * 1000);
382
+ const oauth2Client = new googleapis_1.google.auth.OAuth2(clientId, clientSecret, callbackUrl);
383
+ const scopes = [
384
+ 'https://www.googleapis.com/auth/gmail.send',
385
+ 'https://www.googleapis.com/auth/gmail.readonly',
386
+ 'https://www.googleapis.com/auth/userinfo.email',
387
+ ];
388
+ const authUrl = oauth2Client.generateAuthUrl({
389
+ access_type: 'offline',
390
+ scope: scopes,
391
+ state: `gmail_config:${state}`,
392
+ prompt: 'consent',
393
+ login_hint: email,
394
+ });
395
+ return { authUrl, state };
396
+ }
397
+ catch (error) {
398
+ this.logger.error('Error initializing Gmail OAuth:', error.message);
399
+ throw new Error('Failed to initialize Gmail OAuth');
400
+ }
401
+ }
402
+ async handleGmailOAuthCallback(code, state) {
403
+ try {
404
+ const oauthState = this.gmailOAuthStates.get(state);
405
+ if (!oauthState) {
406
+ throw new Error('Invalid or expired OAuth state');
407
+ }
408
+ this.gmailOAuthStates.delete(state);
409
+ if (Date.now() - oauthState.timestamp > 10 * 60 * 1000) {
410
+ throw new Error('OAuth state expired');
411
+ }
412
+ const clientId = this.configService.get('CLIENT_ID');
413
+ const clientSecret = this.configService.get('CLIENT_SECRET');
414
+ const callbackUrl = this.configService.get('CALLBACK_URL') || 'http://localhost:5001/auth/google/callback';
415
+ const oauth2Client = new googleapis_1.google.auth.OAuth2(clientId, clientSecret, callbackUrl);
416
+ const { tokens } = await oauth2Client.getToken(code);
417
+ if (!tokens.access_token) {
418
+ throw new Error('Failed to obtain access token');
419
+ }
420
+ oauth2Client.setCredentials(tokens);
421
+ const oauth2 = googleapis_1.google.oauth2({ version: 'v2', auth: oauth2Client });
422
+ const userInfo = await oauth2.userinfo.get();
423
+ const email = userInfo.data.email;
424
+ if (!email) {
425
+ throw new Error('Failed to get user email');
426
+ }
427
+ if (oauthState.email && oauthState.email !== email) {
428
+ throw new Error('Email mismatch with OAuth hint');
429
+ }
430
+ const gmailConfig = {
431
+ clientId,
432
+ clientSecret,
433
+ email: email,
434
+ accessToken: tokens.access_token,
435
+ refreshToken: tokens.refresh_token,
436
+ scope: tokens.scope,
437
+ tokenType: tokens.token_type,
438
+ expiryDate: tokens.expiry_date,
439
+ };
440
+ const communicationConfig = this.configRepository.create({
441
+ config_json: gmailConfig,
442
+ });
443
+ const savedConfig = await this.configRepository.save(communicationConfig);
444
+ const hub = this.hubRepository.create({
445
+ level_id: oauthState.levelId,
446
+ level_type: oauthState.levelType,
447
+ config_id: savedConfig.id,
448
+ communication_config_type: communication_hub_entity_1.CommunicationConfigType.EMAIL,
449
+ service: 'API',
450
+ provider: 'gmail',
451
+ status: 1,
452
+ });
453
+ const savedHub = await this.hubRepository.save(hub);
454
+ this.logger.log(`Gmail OAuth configuration created successfully for ${oauthState.levelType} ${oauthState.levelId} and email ${email}`);
455
+ return {
456
+ hubId: savedHub.id,
457
+ configId: savedConfig.id,
458
+ };
459
+ }
460
+ catch (error) {
461
+ this.logger.error('Error handling Gmail OAuth callback:', error.message);
462
+ throw new Error(`Failed to complete Gmail OAuth: ${error.message}`);
463
+ }
464
+ }
465
+ async handleGmailTokensCallback(email, accessToken, refreshToken, state) {
466
+ try {
467
+ const oauthState = this.gmailOAuthStates.get(state);
468
+ if (!oauthState) {
469
+ throw new Error('Invalid or expired OAuth state');
470
+ }
471
+ this.gmailOAuthStates.delete(state);
472
+ if (Date.now() - oauthState.timestamp > 10 * 60 * 1000) {
473
+ throw new Error('OAuth state expired');
474
+ }
475
+ if (oauthState.email && oauthState.email !== email) {
476
+ throw new Error('Email mismatch with OAuth hint');
477
+ }
478
+ const gmailConfig = {
479
+ email: email,
480
+ accessToken: accessToken,
481
+ refreshToken: refreshToken,
482
+ authMethod: 'GOOGLE_SSO',
483
+ scopes: [
484
+ 'https://www.googleapis.com/auth/gmail.send',
485
+ 'https://www.googleapis.com/auth/userinfo.email',
486
+ ],
487
+ };
488
+ const communicationConfig = this.configRepository.create({
489
+ config_json: gmailConfig,
490
+ });
491
+ const savedConfig = await this.configRepository.save(communicationConfig);
492
+ const hub = this.hubRepository.create({
493
+ level_id: oauthState.levelId,
494
+ level_type: oauthState.levelType,
495
+ config_id: savedConfig.id,
496
+ communication_config_type: communication_hub_entity_1.CommunicationConfigType.EMAIL,
497
+ service: 'API',
498
+ provider: 'gmail',
499
+ status: 1,
500
+ });
501
+ const savedHub = await this.hubRepository.save(hub);
502
+ this.logger.log(`Gmail tokens configuration created successfully for ${oauthState.levelType} ${oauthState.levelId} and email ${email}`);
503
+ return {
504
+ hubId: savedHub.id,
505
+ configId: savedConfig.id,
506
+ };
507
+ }
508
+ catch (error) {
509
+ this.logger.error('Error handling Gmail tokens callback:', error.message);
510
+ throw new Error(`Failed to complete Gmail tokens callback: ${error.message}`);
511
+ }
512
+ }
513
+ async testGmailConfig(hubId) {
514
+ try {
515
+ const hub = await this.hubRepository.findOne({
516
+ where: { id: hubId },
517
+ });
518
+ if (!hub) {
519
+ throw new Error('Communication hub not found');
520
+ }
521
+ const config = await this.configRepository.findOne({
522
+ where: { id: hub.config_id },
523
+ });
524
+ if (!config) {
525
+ throw new Error('Configuration not found');
526
+ }
527
+ const isValid = await this.gmailApiStrategy.validateConnection(config.config_json);
528
+ if (!isValid) {
529
+ return { success: false, error: 'Gmail configuration is invalid or expired' };
530
+ }
531
+ return { success: true };
532
+ }
533
+ catch (error) {
534
+ this.logger.error('Error testing Gmail config:', error.message);
535
+ return { success: false, error: error.message };
536
+ }
537
+ }
538
+ generateSecureState() {
539
+ return Math.random().toString(36).substring(2) + Date.now().toString(36);
540
+ }
541
+ requiresOAuthFlow(configType, service, provider, config) {
542
+ const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
543
+ switch (key) {
544
+ case 'email_api_gmail':
545
+ return !config.accessToken || config.useOAuth === true;
546
+ case 'email_api_outlook':
547
+ return !config.accessToken || config.useOAuth === true;
548
+ default:
549
+ return false;
550
+ }
551
+ }
552
+ async generateOAuthUrl(levelId, levelType, configType, service, provider, config, priority, is_default) {
553
+ const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
554
+ switch (key) {
555
+ case 'email_api_gmail':
556
+ const gmailResult = await this.initGmailOAuth(levelId, levelType, config.email);
557
+ return {
558
+ authUrl: gmailResult.authUrl,
559
+ state: gmailResult.state,
560
+ message: 'Please complete Gmail OAuth authorization. Configuration will be created automatically after authorization.'
561
+ };
562
+ case 'email_api_outlook':
563
+ const outlookResult = await this.initOutlookOAuth(levelId, levelType, config.email);
564
+ return {
565
+ authUrl: outlookResult.authUrl,
566
+ state: outlookResult.state,
567
+ message: 'Please complete Outlook OAuth authorization. Configuration will be created automatically after authorization.'
568
+ };
569
+ default:
570
+ throw new Error(`OAuth not supported for ${configType}/${service}/${provider}`);
571
+ }
572
+ }
573
+ async createDirectConfig(levelId, levelType, configType, service, provider, config, priority, is_default) {
574
+ if (is_default) {
575
+ await this.hubRepository.update({
576
+ level_id: levelId,
577
+ level_type: levelType,
578
+ communication_config_type: configType,
579
+ }, { is_default: false });
580
+ }
581
+ const communicationConfig = this.configRepository.create({
582
+ config_json: config,
583
+ });
584
+ const savedConfig = await this.configRepository.save(communicationConfig);
585
+ const hub = this.hubRepository.create({
586
+ level_id: levelId,
587
+ level_type: levelType,
588
+ config_id: savedConfig.id,
589
+ communication_config_type: configType,
590
+ service: service,
591
+ provider: provider,
592
+ priority: priority || 1,
593
+ is_default: is_default || false,
594
+ status: 1,
595
+ });
596
+ const savedHub = await this.hubRepository.save(hub);
597
+ this.logger.log(`Communication config created: ${configType}/${service}/${provider} for ${levelType} ${levelId}`);
598
+ return Array.isArray(savedHub) ? savedHub[0] : savedHub;
599
+ }
600
+ async initOutlookOAuth(levelId, levelType, email) {
601
+ try {
602
+ const clientId = this.configService.get('OUTLOOK_CLIENT_ID');
603
+ const tenantId = this.configService.get('OUTLOOK_TENANT_ID');
604
+ if (!clientId || !tenantId) {
605
+ throw new Error('Outlook OAuth credentials not configured');
606
+ }
607
+ const state = this.generateSecureState();
608
+ const callbackUrl = this.configService.get('OUTLOOK_CALLBACK_URL') || 'http://localhost:5001/auth/outlook/callback';
609
+ this.gmailOAuthStates.set(state, {
610
+ levelId,
611
+ levelType,
612
+ email,
613
+ timestamp: Date.now(),
614
+ });
615
+ setTimeout(() => {
616
+ this.gmailOAuthStates.delete(state);
617
+ }, 10 * 60 * 1000);
618
+ const scopes = [
619
+ 'https://graph.microsoft.com/Mail.Send',
620
+ 'https://graph.microsoft.com/User.Read',
621
+ ];
622
+ const authUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?` +
623
+ `client_id=${clientId}&` +
624
+ `response_type=code&` +
625
+ `redirect_uri=${encodeURIComponent(callbackUrl)}&` +
626
+ `scope=${encodeURIComponent(scopes.join(' '))}&` +
627
+ `state=outlook_config:${state}&` +
628
+ `response_mode=query&` +
629
+ `prompt=consent` +
630
+ (email ? `&login_hint=${encodeURIComponent(email)}` : '');
631
+ return { authUrl, state };
632
+ }
633
+ catch (error) {
634
+ this.logger.error('Error initializing Outlook OAuth:', error.message);
635
+ throw new Error('Failed to initialize Outlook OAuth');
636
+ }
637
+ }
638
+ async handleOutlookOAuthCallback(code, state) {
639
+ try {
640
+ const oauthState = this.gmailOAuthStates.get(state);
641
+ if (!oauthState) {
642
+ throw new Error('Invalid or expired OAuth state');
643
+ }
644
+ this.gmailOAuthStates.delete(state);
645
+ if (Date.now() - oauthState.timestamp > 10 * 60 * 1000) {
646
+ throw new Error('OAuth state expired');
647
+ }
648
+ const clientId = this.configService.get('OUTLOOK_CLIENT_ID');
649
+ const clientSecret = this.configService.get('OUTLOOK_CLIENT_SECRET');
650
+ const tenantId = this.configService.get('OUTLOOK_TENANT_ID');
651
+ const callbackUrl = this.configService.get('OUTLOOK_CALLBACK_URL') || 'http://localhost:5001/auth/outlook/callback';
652
+ const tokenResponse = await fetch(`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, {
653
+ method: 'POST',
654
+ headers: {
655
+ 'Content-Type': 'application/x-www-form-urlencoded',
656
+ },
657
+ body: new URLSearchParams({
658
+ client_id: clientId,
659
+ client_secret: clientSecret,
660
+ code: code,
661
+ redirect_uri: callbackUrl,
662
+ grant_type: 'authorization_code',
663
+ }),
664
+ });
665
+ const tokens = await tokenResponse.json();
666
+ if (!tokens.access_token) {
667
+ throw new Error('Failed to obtain access token');
668
+ }
669
+ const userResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
670
+ headers: {
671
+ 'Authorization': `Bearer ${tokens.access_token}`,
672
+ },
673
+ });
674
+ const userInfo = await userResponse.json();
675
+ const email = userInfo.mail || userInfo.userPrincipalName;
676
+ if (!email) {
677
+ throw new Error('Failed to get user email');
678
+ }
679
+ const outlookConfig = {
680
+ clientId,
681
+ tenantId,
682
+ email: email,
683
+ accessToken: tokens.access_token,
684
+ refreshToken: tokens.refresh_token,
685
+ scope: tokens.scope,
686
+ tokenType: tokens.token_type,
687
+ expiresIn: tokens.expires_in,
688
+ };
689
+ const communicationConfig = this.configRepository.create({
690
+ config_json: outlookConfig,
691
+ });
692
+ const savedConfig = await this.configRepository.save(communicationConfig);
693
+ const hub = this.hubRepository.create({
694
+ level_id: oauthState.levelId,
695
+ level_type: oauthState.levelType,
696
+ config_id: savedConfig.id,
697
+ communication_config_type: communication_hub_entity_1.CommunicationConfigType.EMAIL,
698
+ service: 'API',
699
+ provider: 'outlook',
700
+ status: 1,
701
+ });
702
+ const savedHub = await this.hubRepository.save(hub);
703
+ this.logger.log(`Outlook OAuth configuration created successfully for ${oauthState.levelType} ${oauthState.levelId} and email ${email}`);
704
+ return {
705
+ hubId: savedHub.id,
706
+ configId: savedConfig.id,
707
+ };
708
+ }
709
+ catch (error) {
710
+ this.logger.error('Error handling Outlook OAuth callback:', error.message);
711
+ throw new Error(`Failed to complete Outlook OAuth: ${error.message}`);
712
+ }
713
+ }
714
+ };
715
+ exports.CommunicationService = CommunicationService;
716
+ exports.CommunicationService = CommunicationService = CommunicationService_1 = __decorate([
717
+ (0, common_1.Injectable)(),
718
+ __param(0, (0, typeorm_1.InjectRepository)(communication_hub_entity_1.CommunicationHub)),
719
+ __param(1, (0, typeorm_1.InjectRepository)(communication_config_entity_1.CommunicationConfig)),
720
+ __metadata("design:paramtypes", [typeorm_2.Repository,
721
+ typeorm_2.Repository,
722
+ communication_factory_1.CommunicationFactory,
723
+ gmail_api_strategy_1.GmailApiStrategy,
724
+ config_1.ConfigService])
725
+ ], CommunicationService);
726
+ //# sourceMappingURL=communication.service.js.map