rez_core 2.2.158 → 2.2.159

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 (239) hide show
  1. package/dist/module/auth/strategies/google.strategy.js +6 -1
  2. package/dist/module/auth/strategies/google.strategy.js.map +1 -1
  3. package/dist/module/auth/strategies/jwt.strategy.js +1 -1
  4. package/dist/module/auth/strategies/jwt.strategy.js.map +1 -1
  5. package/dist/module/communication/communication.module.js +13 -2
  6. package/dist/module/communication/communication.module.js.map +1 -1
  7. package/dist/module/communication/controller/communication.controller.js.map +1 -1
  8. package/dist/module/communication/dto/create-config.dto.js +11 -1
  9. package/dist/module/communication/dto/create-config.dto.js.map +1 -1
  10. package/dist/module/communication/entity/communication-config.entity.js.map +1 -1
  11. package/dist/module/communication/entity/communication-hub.entity.js +11 -1
  12. package/dist/module/communication/entity/communication-hub.entity.js.map +1 -1
  13. package/dist/module/communication/examples/usage.example.js +9 -9
  14. package/dist/module/communication/examples/usage.example.js.map +1 -1
  15. package/dist/module/communication/factories/communication.factory.js +4 -4
  16. package/dist/module/communication/factories/communication.factory.js.map +1 -1
  17. package/dist/module/communication/factories/email.factory.js +1 -1
  18. package/dist/module/communication/factories/email.factory.js.map +1 -1
  19. package/dist/module/communication/factories/sms.factory.js +1 -1
  20. package/dist/module/communication/factories/sms.factory.js.map +1 -1
  21. package/dist/module/communication/factories/telephone.factory.js +2 -4
  22. package/dist/module/communication/factories/telephone.factory.js.map +1 -1
  23. package/dist/module/communication/factories/whatsapp.factory.js +2 -4
  24. package/dist/module/communication/factories/whatsapp.factory.js.map +1 -1
  25. package/dist/module/communication/service/communication-queue.service.d.ts +40 -0
  26. package/dist/module/communication/service/communication-queue.service.js +147 -0
  27. package/dist/module/communication/service/communication-queue.service.js.map +1 -0
  28. package/dist/module/communication/service/communication.service.d.ts +34 -2
  29. package/dist/module/communication/service/communication.service.js +117 -24
  30. package/dist/module/communication/service/communication.service.js.map +1 -1
  31. package/dist/module/communication/service/oauth.service.js +25 -20
  32. package/dist/module/communication/service/oauth.service.js.map +1 -1
  33. package/dist/module/communication/strategies/email/gmail-api.strategy.js +16 -7
  34. package/dist/module/communication/strategies/email/gmail-api.strategy.js.map +1 -1
  35. package/dist/module/communication/strategies/gmail-smtp.strategy.js +2 -3
  36. package/dist/module/communication/strategies/gmail-smtp.strategy.js.map +1 -1
  37. package/dist/module/communication/strategies/gmail.strategy.js.map +1 -1
  38. package/dist/module/communication/strategies/knowlarity.strategy.js +20 -14
  39. package/dist/module/communication/strategies/knowlarity.strategy.js.map +1 -1
  40. package/dist/module/communication/strategies/outlook-smtp.strategy.js +2 -3
  41. package/dist/module/communication/strategies/outlook-smtp.strategy.js.map +1 -1
  42. package/dist/module/communication/strategies/outlook.strategy.js +1 -1
  43. package/dist/module/communication/strategies/outlook.strategy.js.map +1 -1
  44. package/dist/module/communication/strategies/sms.strategy.js +1 -3
  45. package/dist/module/communication/strategies/sms.strategy.js.map +1 -1
  46. package/dist/module/communication/strategies/whatsapp.strategy.js +1 -2
  47. package/dist/module/communication/strategies/whatsapp.strategy.js.map +1 -1
  48. package/dist/module/dashboard/dashboard.module.js +1 -1
  49. package/dist/module/dashboard/repository/dashboard.repository.js.map +1 -1
  50. package/dist/module/dashboard/service/dashboard.service.js +3 -3
  51. package/dist/module/dashboard/service/dashboard.service.js.map +1 -1
  52. package/dist/module/enterprise/repository/organization.repository.js.map +1 -1
  53. package/dist/module/filter/entity/saved-filter-master.entity.d.ts +1 -1
  54. package/dist/module/filter/service/filter.service.js +3 -3
  55. package/dist/module/filter/service/filter.service.js.map +1 -1
  56. package/dist/module/filter/service/saved-filter.service.js.map +1 -1
  57. package/dist/module/layout/controller/layout.controller.js +1 -1
  58. package/dist/module/layout/controller/layout.controller.js.map +1 -1
  59. package/dist/module/layout/repository/header-section.repository.js.map +1 -1
  60. package/dist/module/layout/service/header-section.service.js +2 -2
  61. package/dist/module/layout/service/header-section.service.js.map +1 -1
  62. package/dist/module/layout_preference/repository/layout_preference.repository.js +1 -1
  63. package/dist/module/layout_preference/service/layout_preference.service.js +1 -1
  64. package/dist/module/layout_preference/service/layout_preference.service.js.map +1 -1
  65. package/dist/module/listmaster/controller/list-master.controller.js +1 -1
  66. package/dist/module/listmaster/controller/list-master.controller.js.map +1 -1
  67. package/dist/module/listmaster/repository/list-master.repository.js.map +1 -1
  68. package/dist/module/listmaster/service/list-master.service.js +2 -2
  69. package/dist/module/listmaster/service/list-master.service.js.map +1 -1
  70. package/dist/module/master/controller/master.controller.js +2 -2
  71. package/dist/module/master/controller/master.controller.js.map +1 -1
  72. package/dist/module/master/service/master.service.js +1 -1
  73. package/dist/module/master/service/master.service.js.map +1 -1
  74. package/dist/module/meta/controller/attribute-master.controller.js +3 -3
  75. package/dist/module/meta/controller/attribute-master.controller.js.map +1 -1
  76. package/dist/module/meta/controller/entity-dynamic.controller.js +1 -1
  77. package/dist/module/meta/controller/entity-dynamic.controller.js.map +1 -1
  78. package/dist/module/meta/controller/entity.controller.js +2 -2
  79. package/dist/module/meta/controller/entity.controller.js.map +1 -1
  80. package/dist/module/meta/controller/media.controller.js +1 -1
  81. package/dist/module/meta/controller/media.controller.js.map +1 -1
  82. package/dist/module/meta/controller/meta.controller.js +1 -1
  83. package/dist/module/meta/controller/meta.controller.js.map +1 -1
  84. package/dist/module/meta/dto/entity-table.dto.js.map +1 -1
  85. package/dist/module/meta/entity/entity-master.entity.d.ts +1 -0
  86. package/dist/module/meta/entity/entity-master.entity.js +4 -0
  87. package/dist/module/meta/entity/entity-master.entity.js.map +1 -1
  88. package/dist/module/meta/entity/entity-table.entity.js.map +1 -1
  89. package/dist/module/meta/service/entity-dynamic.service.js +1 -1
  90. package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
  91. package/dist/module/meta/service/entity-list.service.js +11 -11
  92. package/dist/module/meta/service/entity-list.service.js.map +1 -1
  93. package/dist/module/meta/service/entity-service-impl.service.js +2 -2
  94. package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
  95. package/dist/module/meta/service/entity-table-column.service.js +3 -3
  96. package/dist/module/meta/service/entity-table-column.service.js.map +1 -1
  97. package/dist/module/meta/service/entity-table.service.js +2 -2
  98. package/dist/module/meta/service/entity-table.service.js.map +1 -1
  99. package/dist/module/meta/service/media-data.service.js +3 -3
  100. package/dist/module/meta/service/media-data.service.js.map +1 -1
  101. package/dist/module/meta/service/update-form-json.service.d.ts +3 -3
  102. package/dist/module/meta/service/update-form-json.service.js +1 -1
  103. package/dist/module/meta/service/update-form-json.service.js.map +1 -1
  104. package/dist/module/module/controller/menu.controller.js.map +1 -1
  105. package/dist/module/module/controller/module-access.controller.js +1 -1
  106. package/dist/module/module/controller/module-access.controller.js.map +1 -1
  107. package/dist/module/module/entity/module-access.entity.js.map +1 -1
  108. package/dist/module/module/entity/module.entity.js.map +1 -1
  109. package/dist/module/module/service/module-access.service.d.ts +1 -1
  110. package/dist/module/module/service/module-access.service.js +1 -1
  111. package/dist/module/module/service/module-access.service.js.map +1 -1
  112. package/dist/module/notification/controller/otp.controller.js +3 -3
  113. package/dist/module/notification/controller/otp.controller.js.map +1 -1
  114. package/dist/module/notification/service/email.service.js +2 -2
  115. package/dist/module/notification/service/email.service.js.map +1 -1
  116. package/dist/module/notification/service/otp.service.js +1 -1
  117. package/dist/module/notification/service/otp.service.js.map +1 -1
  118. package/dist/module/user/controller/login.controller.js +4 -2
  119. package/dist/module/user/controller/login.controller.js.map +1 -1
  120. package/dist/module/user/service/login.service.js +3 -3
  121. package/dist/module/user/service/login.service.js.map +1 -1
  122. package/dist/module/user/service/role.service.js +1 -1
  123. package/dist/module/user/service/role.service.js.map +1 -1
  124. package/dist/module/user/service/user.service.js +5 -5
  125. package/dist/module/user/service/user.service.js.map +1 -1
  126. package/dist/module/workflow/controller/workflow-meta.controller.js +1 -1
  127. package/dist/module/workflow/controller/workflow-meta.controller.js.map +1 -1
  128. package/dist/module/workflow/service/action.service.js +3 -3
  129. package/dist/module/workflow/service/action.service.js.map +1 -1
  130. package/dist/module/workflow/service/stage-group.service.js +1 -1
  131. package/dist/module/workflow/service/stage-group.service.js.map +1 -1
  132. package/dist/module/workflow/service/workflow-meta.service.js +5 -5
  133. package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
  134. package/dist/resources/properties.module.js +2 -2
  135. package/dist/resources/properties.module.js.map +1 -1
  136. package/dist/tsconfig.build.tsbuildinfo +1 -1
  137. package/dist/utils/service/base64util.service.js.map +1 -1
  138. package/dist/utils/service/clockIDGenUtil.service.js.map +1 -1
  139. package/dist/utils/service/dateUtil.service.js +1 -1
  140. package/dist/utils/service/dateUtil.service.js.map +1 -1
  141. package/dist/utils/service/encryptUtil.service.js +4 -4
  142. package/dist/utils/service/encryptUtil.service.js.map +1 -1
  143. package/dist/utils/service/excel-helper.service.js +4 -1
  144. package/dist/utils/service/excel-helper.service.js.map +1 -1
  145. package/dist/utils/service/json-util.service.js.map +1 -1
  146. package/dist/utils/service/loggingUtil.service.js +3 -3
  147. package/dist/utils/service/loggingUtil.service.js.map +1 -1
  148. package/package.json +1 -1
  149. package/src/decorators/roles.decorator.ts +1 -1
  150. package/src/module/auth/strategies/google.strategy.ts +6 -1
  151. package/src/module/auth/strategies/jwt.strategy.ts +1 -1
  152. package/src/module/communication/communication.module.ts +13 -2
  153. package/src/module/communication/controller/communication.controller.ts +21 -18
  154. package/src/module/communication/dto/create-config.dto.ts +32 -13
  155. package/src/module/communication/entity/communication-config.entity.ts +15 -9
  156. package/src/module/communication/entity/communication-hub.entity.ts +29 -3
  157. package/src/module/communication/examples/usage.example.ts +18 -17
  158. package/src/module/communication/factories/communication.factory.ts +36 -18
  159. package/src/module/communication/factories/email.factory.ts +8 -5
  160. package/src/module/communication/factories/sms.factory.ts +8 -5
  161. package/src/module/communication/factories/telephone.factory.ts +9 -8
  162. package/src/module/communication/factories/whatsapp.factory.ts +9 -8
  163. package/src/module/communication/service/communication-queue.service.ts +214 -0
  164. package/src/module/communication/service/communication.service.ts +340 -101
  165. package/src/module/communication/service/oauth.service.ts +67 -46
  166. package/src/module/communication/strategies/email/gmail-api.strategy.ts +44 -24
  167. package/src/module/communication/strategies/gmail-smtp.strategy.ts +15 -11
  168. package/src/module/communication/strategies/gmail.strategy.ts +15 -7
  169. package/src/module/communication/strategies/knowlarity.strategy.ts +67 -33
  170. package/src/module/communication/strategies/outlook-smtp.strategy.ts +15 -11
  171. package/src/module/communication/strategies/outlook.strategy.ts +12 -5
  172. package/src/module/communication/strategies/sms.strategy.ts +13 -10
  173. package/src/module/communication/strategies/whatsapp.strategy.ts +13 -9
  174. package/src/module/dashboard/dashboard.module.ts +1 -1
  175. package/src/module/dashboard/repository/dashboard.repository.ts +4 -2
  176. package/src/module/dashboard/service/dashboard.service.ts +16 -12
  177. package/src/module/enterprise/repository/organization.repository.ts +3 -1
  178. package/src/module/enterprise/service/enterprise.service.ts +2 -2
  179. package/src/module/filter/entity/saved-filter-master.entity.ts +3 -3
  180. package/src/module/filter/service/filter.service.ts +3 -3
  181. package/src/module/filter/service/saved-filter.service.ts +1 -1
  182. package/src/module/layout/controller/layout.controller.ts +1 -1
  183. package/src/module/layout/repository/header-section.repository.ts +2 -2
  184. package/src/module/layout/service/header-section.service.ts +2 -3
  185. package/src/module/layout_preference/repository/layout_preference.repository.ts +2 -2
  186. package/src/module/layout_preference/service/layout_preference.service.ts +1 -1
  187. package/src/module/listmaster/controller/list-master.controller.ts +1 -1
  188. package/src/module/listmaster/repository/list-master.repository.ts +2 -2
  189. package/src/module/listmaster/service/list-master.service.ts +2 -2
  190. package/src/module/master/controller/master.controller.ts +2 -2
  191. package/src/module/master/service/master.service.ts +1 -1
  192. package/src/module/meta/controller/attribute-master.controller.ts +3 -3
  193. package/src/module/meta/controller/entity-dynamic.controller.ts +1 -1
  194. package/src/module/meta/controller/entity.controller.ts +2 -2
  195. package/src/module/meta/controller/media.controller.ts +1 -1
  196. package/src/module/meta/controller/meta.controller.ts +1 -1
  197. package/src/module/meta/dto/entity-tab.dto.ts +4 -4
  198. package/src/module/meta/dto/entity-table.dto.ts +5 -6
  199. package/src/module/meta/entity/entity-master.entity.ts +3 -0
  200. package/src/module/meta/entity/entity-table.entity.ts +1 -2
  201. package/src/module/meta/service/entity-dynamic.service.ts +1 -1
  202. package/src/module/meta/service/entity-list.service.ts +18 -14
  203. package/src/module/meta/service/entity-service-impl.service.ts +2 -2
  204. package/src/module/meta/service/entity-table-column.service.ts +3 -3
  205. package/src/module/meta/service/entity-table.service.ts +2 -2
  206. package/src/module/meta/service/entity.service.ts +1 -1
  207. package/src/module/meta/service/media-data.service.ts +3 -3
  208. package/src/module/meta/service/update-form-json.service.ts +17 -26
  209. package/src/module/module/controller/menu.controller.ts +0 -1
  210. package/src/module/module/controller/module-access.controller.ts +2 -3
  211. package/src/module/module/entity/menu.entity.ts +1 -1
  212. package/src/module/module/entity/module-access.entity.ts +6 -6
  213. package/src/module/module/entity/module-action.entity.ts +2 -2
  214. package/src/module/module/entity/module.entity.ts +0 -1
  215. package/src/module/module/service/module-access.service.ts +7 -8
  216. package/src/module/notification/controller/otp.controller.ts +10 -4
  217. package/src/module/notification/repository/otp.repository.ts +1 -1
  218. package/src/module/notification/service/email.service.ts +2 -2
  219. package/src/module/notification/service/otp.service.ts +8 -3
  220. package/src/module/third-party-module/third-party.module.ts +1 -1
  221. package/src/module/user/controller/login.controller.ts +27 -12
  222. package/src/module/user/service/login.service.ts +27 -27
  223. package/src/module/user/service/role.service.ts +1 -1
  224. package/src/module/user/service/user.service.ts +5 -5
  225. package/src/module/workflow/controller/workflow-meta.controller.ts +1 -1
  226. package/src/module/workflow/service/action.service.ts +3 -3
  227. package/src/module/workflow/service/stage-group.service.ts +1 -1
  228. package/src/module/workflow/service/workflow-meta.service.ts +5 -5
  229. package/src/resources/properties.module.ts +10 -10
  230. package/src/utils/dto/excel-data.dto.ts +2 -2
  231. package/src/utils/dto/excelsheet-data.dto.ts +3 -3
  232. package/src/utils/service/base64util.service.ts +16 -17
  233. package/src/utils/service/clockIDGenUtil.service.ts +15 -13
  234. package/src/utils/service/dateUtil.service.ts +6 -6
  235. package/src/utils/service/encryptUtil.service.ts +4 -4
  236. package/src/utils/service/excel-helper.service.ts +4 -1
  237. package/src/utils/service/file-util.service.ts +2 -2
  238. package/src/utils/service/json-util.service.ts +19 -19
  239. package/src/utils/service/loggingUtil.service.ts +4 -4
@@ -1,16 +1,17 @@
1
- import { Injectable, Logger } from '@nestjs/common';
1
+ import { Injectable, Logger, Inject, forwardRef } from '@nestjs/common';
2
2
  import { InjectRepository } from '@nestjs/typeorm';
3
3
  import { Repository } from 'typeorm';
4
4
  import { ConfigService } from '@nestjs/config';
5
5
  import { google } from 'googleapis';
6
6
  import {
7
- CommunicationHub,
8
7
  CommunicationConfigType,
8
+ CommunicationHub,
9
9
  } from '../entity/communication-hub.entity';
10
10
  import { CommunicationConfig } from '../entity/communication-config.entity';
11
11
  import { CommunicationFactory } from '../factories/communication.factory';
12
12
  import { CommunicationResult } from '../strategies/communication.strategy';
13
13
  import { GmailApiStrategy } from '../strategies/email/gmail-api.strategy';
14
+ import { CommunicationQueueService } from './communication-queue.service';
14
15
 
15
16
  export interface SendMessageDto {
16
17
  levelId: number;
@@ -83,6 +84,8 @@ export class CommunicationService {
83
84
  private readonly communicationFactory: CommunicationFactory,
84
85
  private readonly gmailApiStrategy: GmailApiStrategy,
85
86
  private readonly configService: ConfigService,
87
+ @Inject(forwardRef(() => CommunicationQueueService))
88
+ private readonly queueService?: CommunicationQueueService,
86
89
  ) {}
87
90
 
88
91
  async sendMessage({
@@ -158,7 +161,7 @@ export class CommunicationService {
158
161
  'config.id as config_id',
159
162
  'config.config_json as config_json',
160
163
  'config.created_at as config_created_at',
161
- 'config.updated_at as config_updated_at'
164
+ 'config.updated_at as config_updated_at',
162
165
  ])
163
166
  .where('hub.level_id = :levelId', { levelId })
164
167
  .andWhere('hub.level_type = :levelType', { levelType })
@@ -171,7 +174,7 @@ export class CommunicationService {
171
174
  const results = await query.getRawMany();
172
175
 
173
176
  // Transform the raw results into the expected format
174
- const hubsWithConfig: CommunicationHubWithConfig[] = results.map(row => ({
177
+ const hubsWithConfig: CommunicationHubWithConfig[] = results.map((row) => ({
175
178
  id: row.hub_id,
176
179
  level_id: row.hub_level_id,
177
180
  level_type: row.hub_level_type,
@@ -226,29 +229,57 @@ export class CommunicationService {
226
229
  config: any,
227
230
  priority?: number,
228
231
  is_default?: boolean,
229
- ): Promise<CommunicationHub | { authUrl: string; state: string; message: string }> {
232
+ ): Promise<
233
+ CommunicationHub | { authUrl: string; state: string; message: string }
234
+ > {
230
235
  // Validate service/provider combination using supported combinations
231
236
  const supportedCombinations = await this.getSupportedCombinations();
232
237
  const isValidCombination = supportedCombinations.some(
233
- combo => combo.mode === configType &&
234
- combo.service.toLowerCase() === service.toLowerCase() &&
235
- combo.provider.toLowerCase() === provider.toLowerCase()
238
+ (combo) =>
239
+ combo.mode === configType &&
240
+ combo.service.toLowerCase() === service.toLowerCase() &&
241
+ combo.provider.toLowerCase() === provider.toLowerCase(),
236
242
  );
237
-
243
+
238
244
  if (!isValidCombination) {
239
- throw new Error(`Unsupported combination: ${configType}/${service}/${provider}`);
245
+ throw new Error(
246
+ `Unsupported combination: ${configType}/${service}/${provider}`,
247
+ );
240
248
  }
241
249
 
242
250
  // Check if this requires OAuth flow
243
- const requiresOAuth = this.requiresOAuthFlow(configType, service, provider, config);
244
-
251
+ const requiresOAuth = this.requiresOAuthFlow(
252
+ configType,
253
+ service,
254
+ provider,
255
+ config,
256
+ );
257
+
245
258
  if (requiresOAuth) {
246
259
  // Generate OAuth URL and return it instead of creating config immediately
247
- return await this.generateOAuthUrl(levelId, levelType, configType, service, provider, config, priority, is_default);
260
+ return await this.generateOAuthUrl(
261
+ levelId,
262
+ levelType,
263
+ configType,
264
+ service,
265
+ provider,
266
+ config,
267
+ priority,
268
+ is_default,
269
+ );
248
270
  }
249
271
 
250
272
  // Direct config creation (non-OAuth flow)
251
- return await this.createDirectConfig(levelId, levelType, configType, service, provider, config, priority, is_default);
273
+ return await this.createDirectConfig(
274
+ levelId,
275
+ levelType,
276
+ configType,
277
+ service,
278
+ provider,
279
+ config,
280
+ priority,
281
+ is_default,
282
+ );
252
283
  }
253
284
 
254
285
  async getSupportedCombinations(): Promise<
@@ -275,7 +306,9 @@ export class CommunicationService {
275
306
  await this.hubRepository.update(hubId, { status });
276
307
  }
277
308
 
278
- async sendGenericMessage(messageDto: GenericMessageDto): Promise<CommunicationResult> {
309
+ async sendGenericMessage(
310
+ messageDto: GenericMessageDto,
311
+ ): Promise<CommunicationResult> {
279
312
  try {
280
313
  const {
281
314
  levelId,
@@ -291,17 +324,23 @@ export class CommunicationService {
291
324
  attachments,
292
325
  mediaUrl,
293
326
  templateId,
294
- variables
327
+ variables,
295
328
  } = messageDto;
296
329
 
297
330
  // Auto-detect communication type if not specified
298
331
  const communicationType = this.detectCommunicationType(to, type);
299
-
332
+
300
333
  // Get active hubs for the detected type
301
- const hubs = await this.getActiveHubs(levelId, levelType, communicationType);
302
-
334
+ const hubs = await this.getActiveHubs(
335
+ levelId,
336
+ levelType,
337
+ communicationType,
338
+ );
339
+
303
340
  if (!hubs.length) {
304
- throw new Error(`No active ${communicationType} configuration found for ${levelType} ${levelId}`);
341
+ throw new Error(
342
+ `No active ${communicationType} configuration found for ${levelType} ${levelId}`,
343
+ );
305
344
  }
306
345
 
307
346
  // Sort hubs by priority and default preference
@@ -338,10 +377,17 @@ export class CommunicationService {
338
377
  }
339
378
 
340
379
  // Merge config with enhanced parameters
341
- const finalConfig = { ...hub.config.config_json, ...enhancedConfig };
380
+ const finalConfig = {
381
+ ...hub.config.config_json,
382
+ ...enhancedConfig,
383
+ };
384
+
385
+ const result = await strategy.sendMessage(
386
+ recipient,
387
+ processedMessage,
388
+ finalConfig,
389
+ );
342
390
 
343
- const result = await strategy.sendMessage(recipient, processedMessage, finalConfig);
344
-
345
391
  if (result.success) {
346
392
  this.logger.log(
347
393
  `Generic message sent successfully via ${hub.provider}/${hub.service} to ${recipient}`,
@@ -367,7 +413,7 @@ export class CommunicationService {
367
413
  if (hasSuccess) {
368
414
  return {
369
415
  success: true,
370
- messageId: results.map(r => r.messageId).join(','),
416
+ messageId: results.map((r) => r.messageId).join(','),
371
417
  provider: 'multiple',
372
418
  service: 'multiple',
373
419
  timestamp: new Date(),
@@ -390,10 +436,17 @@ export class CommunicationService {
390
436
  }
391
437
 
392
438
  // Merge config with enhanced parameters
393
- const finalConfig = { ...hub.config.config_json, ...enhancedConfig };
439
+ const finalConfig = {
440
+ ...hub.config.config_json,
441
+ ...enhancedConfig,
442
+ };
443
+
444
+ const result = await strategy.sendMessage(
445
+ to,
446
+ processedMessage,
447
+ finalConfig,
448
+ );
394
449
 
395
- const result = await strategy.sendMessage(to, processedMessage, finalConfig);
396
-
397
450
  if (result.success) {
398
451
  this.logger.log(
399
452
  `Generic message sent successfully via ${hub.provider}/${hub.service} to ${to}`,
@@ -421,7 +474,9 @@ export class CommunicationService {
421
474
  }
422
475
  }
423
476
 
424
- async sendBulkMessage(bulkDto: BulkMessageDto): Promise<{ results: CommunicationResult[]; summary: any }> {
477
+ async sendBulkMessage(
478
+ bulkDto: BulkMessageDto,
479
+ ): Promise<{ results: CommunicationResult[]; summary: any }> {
425
480
  try {
426
481
  const {
427
482
  levelId,
@@ -434,7 +489,7 @@ export class CommunicationService {
434
489
  html,
435
490
  templateId,
436
491
  variables,
437
- batchSize = 10
492
+ batchSize = 10,
438
493
  } = bulkDto;
439
494
 
440
495
  const results: CommunicationResult[] = [];
@@ -442,7 +497,9 @@ export class CommunicationService {
442
497
 
443
498
  for (let i = 0; i < batches.length; i++) {
444
499
  const batch = batches[i];
445
- this.logger.log(`Processing batch ${i + 1}/${batches.length} with ${batch.length} recipients`);
500
+ this.logger.log(
501
+ `Processing batch ${i + 1}/${batches.length} with ${batch.length} recipients`,
502
+ );
446
503
 
447
504
  const batchPromises = batch.map(async (recipient) => {
448
505
  try {
@@ -490,18 +547,24 @@ export class CommunicationService {
490
547
 
491
548
  // Rate limiting delay between batches
492
549
  if (i < batches.length - 1) {
493
- await new Promise(resolve => setTimeout(resolve, 1000));
550
+ await new Promise((resolve) => setTimeout(resolve, 1000));
494
551
  }
495
552
  }
496
553
 
497
554
  const summary = {
498
555
  total: results.length,
499
- successful: results.filter(r => r.success).length,
500
- failed: results.filter(r => !r.success).length,
501
- successRate: ((results.filter(r => r.success).length / results.length) * 100).toFixed(2) + '%',
556
+ successful: results.filter((r) => r.success).length,
557
+ failed: results.filter((r) => !r.success).length,
558
+ successRate:
559
+ (
560
+ (results.filter((r) => r.success).length / results.length) *
561
+ 100
562
+ ).toFixed(2) + '%',
502
563
  };
503
564
 
504
- this.logger.log(`Bulk message completed: ${summary.successful}/${summary.total} successful`);
565
+ this.logger.log(
566
+ `Bulk message completed: ${summary.successful}/${summary.total} successful`,
567
+ );
505
568
 
506
569
  return { results, summary };
507
570
  } catch (error) {
@@ -510,10 +573,12 @@ export class CommunicationService {
510
573
  }
511
574
  }
512
575
 
513
- async scheduleMessage(scheduledDto: any): Promise<{ scheduled: boolean; scheduleId?: string }> {
576
+ async scheduleMessage(
577
+ scheduledDto: any,
578
+ ): Promise<{ scheduled: boolean; scheduleId?: string }> {
514
579
  // For now, return a placeholder. In production, integrate with a job queue like Bull or Agenda
515
580
  this.logger.log(`Message scheduled for ${scheduledDto.scheduleFor}`);
516
-
581
+
517
582
  return {
518
583
  scheduled: true,
519
584
  scheduleId: `sched_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,
@@ -523,9 +588,14 @@ export class CommunicationService {
523
588
  async sendTemplateMessage(templateDto: any): Promise<CommunicationResult> {
524
589
  // Get template content (integrate with your template system)
525
590
  const template = await this.getTemplate(templateDto.templateId);
526
-
527
- const processedMessage = this.processTemplate(template.content, templateDto.variables);
528
- const processedSubject = template.subject ? this.processTemplate(template.subject, templateDto.variables) : undefined;
591
+
592
+ const processedMessage = this.processTemplate(
593
+ template.content,
594
+ templateDto.variables,
595
+ );
596
+ const processedSubject = template.subject
597
+ ? this.processTemplate(template.subject, templateDto.variables)
598
+ : undefined;
529
599
 
530
600
  const messageDto: GenericMessageDto = {
531
601
  levelId: templateDto.levelId,
@@ -541,7 +611,10 @@ export class CommunicationService {
541
611
  return this.sendGenericMessage(messageDto);
542
612
  }
543
613
 
544
- private detectCommunicationType(to: string | string[], type?: string): CommunicationConfigType {
614
+ private detectCommunicationType(
615
+ to: string | string[],
616
+ type?: string,
617
+ ): CommunicationConfigType {
545
618
  if (type) {
546
619
  return type as CommunicationConfigType;
547
620
  }
@@ -572,18 +645,23 @@ export class CommunicationService {
572
645
  if (a.is_default !== b.is_default) {
573
646
  return b.is_default ? 1 : -1;
574
647
  }
575
-
648
+
576
649
  // Then sort by priority (lower number = higher priority)
577
650
  if (a.priority !== b.priority) {
578
651
  return a.priority - b.priority;
579
652
  }
580
-
653
+
581
654
  // Finally sort by created_at descending (newest first)
582
- return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
655
+ return (
656
+ new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
657
+ );
583
658
  });
584
659
  }
585
660
 
586
- private processTemplate(template: string, variables: Record<string, any>): string {
661
+ private processTemplate(
662
+ template: string,
663
+ variables: Record<string, any>,
664
+ ): string {
587
665
  return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
588
666
  const value = variables[key];
589
667
  return value !== undefined ? String(value) : match;
@@ -617,15 +695,17 @@ export class CommunicationService {
617
695
  // Get system OAuth credentials from config
618
696
  const clientId = this.configService.get<string>('CLIENT_ID');
619
697
  const clientSecret = this.configService.get<string>('CLIENT_SECRET');
620
-
698
+
621
699
  if (!clientId || !clientSecret) {
622
700
  throw new Error('Gmail OAuth credentials not configured');
623
701
  }
624
702
 
625
703
  const state = this.generateSecureState();
626
704
  // Use the existing registered callback URL
627
- const callbackUrl = this.configService.get<string>('CALLBACK_URL') || 'http://localhost:5001/auth/google/callback';
628
-
705
+ const callbackUrl =
706
+ this.configService.get<string>('CALLBACK_URL') ||
707
+ 'http://localhost:5001/auth/google/callback';
708
+
629
709
  this.gmailOAuthStates.set(state, {
630
710
  levelId,
631
711
  levelType,
@@ -634,9 +714,12 @@ export class CommunicationService {
634
714
  });
635
715
 
636
716
  // Auto-cleanup after 10 minutes
637
- setTimeout(() => {
638
- this.gmailOAuthStates.delete(state);
639
- }, 10 * 60 * 1000);
717
+ setTimeout(
718
+ () => {
719
+ this.gmailOAuthStates.delete(state);
720
+ },
721
+ 10 * 60 * 1000,
722
+ );
640
723
 
641
724
  const oauth2Client = new google.auth.OAuth2(
642
725
  clientId,
@@ -684,7 +767,9 @@ export class CommunicationService {
684
767
  // Get system OAuth credentials
685
768
  const clientId = this.configService.get<string>('CLIENT_ID');
686
769
  const clientSecret = this.configService.get<string>('CLIENT_SECRET');
687
- const callbackUrl = this.configService.get<string>('CALLBACK_URL') || 'http://localhost:5001/auth/google/callback';
770
+ const callbackUrl =
771
+ this.configService.get<string>('CALLBACK_URL') ||
772
+ 'http://localhost:5001/auth/google/callback';
688
773
 
689
774
  const oauth2Client = new google.auth.OAuth2(
690
775
  clientId,
@@ -693,7 +778,7 @@ export class CommunicationService {
693
778
  );
694
779
 
695
780
  const { tokens } = await oauth2Client.getToken(code);
696
-
781
+
697
782
  if (!tokens.access_token) {
698
783
  throw new Error('Failed to obtain access token');
699
784
  }
@@ -821,11 +906,15 @@ export class CommunicationService {
821
906
  };
822
907
  } catch (error) {
823
908
  this.logger.error('Error handling Gmail tokens callback:', error.message);
824
- throw new Error(`Failed to complete Gmail tokens callback: ${error.message}`);
909
+ throw new Error(
910
+ `Failed to complete Gmail tokens callback: ${error.message}`,
911
+ );
825
912
  }
826
913
  }
827
914
 
828
- async testGmailConfig(hubId: number): Promise<{ success: boolean; error?: string }> {
915
+ async testGmailConfig(
916
+ hubId: number,
917
+ ): Promise<{ success: boolean; error?: string }> {
829
918
  try {
830
919
  const hub = await this.hubRepository.findOne({
831
920
  where: { id: hubId },
@@ -843,10 +932,15 @@ export class CommunicationService {
843
932
  throw new Error('Configuration not found');
844
933
  }
845
934
 
846
- const isValid = await this.gmailApiStrategy.validateConnection(config.config_json);
847
-
935
+ const isValid = await this.gmailApiStrategy.validateConnection(
936
+ config.config_json,
937
+ );
938
+
848
939
  if (!isValid) {
849
- return { success: false, error: 'Gmail configuration is invalid or expired' };
940
+ return {
941
+ success: false,
942
+ error: 'Gmail configuration is invalid or expired',
943
+ };
850
944
  }
851
945
 
852
946
  return { success: true };
@@ -864,20 +958,20 @@ export class CommunicationService {
864
958
  configType: CommunicationConfigType,
865
959
  service: string,
866
960
  provider: string,
867
- config: any
961
+ config: any,
868
962
  ): boolean {
869
963
  // Check if config indicates OAuth is needed (missing tokens or explicit OAuth request)
870
964
  const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
871
-
965
+
872
966
  switch (key) {
873
967
  case 'email_api_gmail':
874
968
  // Requires OAuth if no access token provided or OAuth explicitly requested
875
969
  return !config.accessToken || config.useOAuth === true;
876
-
970
+
877
971
  case 'email_api_outlook':
878
972
  // Requires OAuth if no access token provided or OAuth explicitly requested
879
973
  return !config.accessToken || config.useOAuth === true;
880
-
974
+
881
975
  default:
882
976
  // Most other providers don't require OAuth
883
977
  return false;
@@ -892,29 +986,41 @@ export class CommunicationService {
892
986
  provider: string,
893
987
  config: any,
894
988
  priority?: number,
895
- is_default?: boolean
989
+ is_default?: boolean,
896
990
  ): Promise<{ authUrl: string; state: string; message: string }> {
897
991
  const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
898
-
992
+
899
993
  switch (key) {
900
994
  case 'email_api_gmail':
901
- const gmailResult = await this.initGmailOAuth(levelId, levelType, config.email);
995
+ const gmailResult = await this.initGmailOAuth(
996
+ levelId,
997
+ levelType,
998
+ config.email,
999
+ );
902
1000
  return {
903
1001
  authUrl: gmailResult.authUrl,
904
1002
  state: gmailResult.state,
905
- message: 'Please complete Gmail OAuth authorization. Configuration will be created automatically after authorization.'
1003
+ message:
1004
+ 'Please complete Gmail OAuth authorization. Configuration will be created automatically after authorization.',
906
1005
  };
907
-
1006
+
908
1007
  case 'email_api_outlook':
909
- const outlookResult = await this.initOutlookOAuth(levelId, levelType, config.email);
1008
+ const outlookResult = await this.initOutlookOAuth(
1009
+ levelId,
1010
+ levelType,
1011
+ config.email,
1012
+ );
910
1013
  return {
911
1014
  authUrl: outlookResult.authUrl,
912
1015
  state: outlookResult.state,
913
- message: 'Please complete Outlook OAuth authorization. Configuration will be created automatically after authorization.'
1016
+ message:
1017
+ 'Please complete Outlook OAuth authorization. Configuration will be created automatically after authorization.',
914
1018
  };
915
-
1019
+
916
1020
  default:
917
- throw new Error(`OAuth not supported for ${configType}/${service}/${provider}`);
1021
+ throw new Error(
1022
+ `OAuth not supported for ${configType}/${service}/${provider}`,
1023
+ );
918
1024
  }
919
1025
  }
920
1026
 
@@ -926,23 +1032,23 @@ export class CommunicationService {
926
1032
  provider: string,
927
1033
  config: any,
928
1034
  priority?: number,
929
- is_default?: boolean
1035
+ is_default?: boolean,
930
1036
  ): Promise<CommunicationHub> {
931
1037
  // If setting as default, remove default from other configurations of same type
932
1038
  if (is_default) {
933
1039
  await this.hubRepository.update(
934
- {
1040
+ {
935
1041
  level_id: levelId,
936
1042
  level_type: levelType,
937
1043
  communication_config_type: configType,
938
1044
  },
939
- { is_default: false }
1045
+ { is_default: false },
940
1046
  );
941
1047
  }
942
1048
 
943
1049
  // First, create the config
944
1050
  const communicationConfig = this.configRepository.create({
945
- config_json: config as any,
1051
+ config_json: config,
946
1052
  });
947
1053
  const savedConfig = await this.configRepository.save(communicationConfig);
948
1054
 
@@ -960,8 +1066,10 @@ export class CommunicationService {
960
1066
  });
961
1067
 
962
1068
  const savedHub = await this.hubRepository.save(hub);
963
- this.logger.log(`Communication config created: ${configType}/${service}/${provider} for ${levelType} ${levelId}`);
964
-
1069
+ this.logger.log(
1070
+ `Communication config created: ${configType}/${service}/${provider} for ${levelType} ${levelId}`,
1071
+ );
1072
+
965
1073
  return Array.isArray(savedHub) ? savedHub[0] : savedHub;
966
1074
  }
967
1075
 
@@ -974,14 +1082,16 @@ export class CommunicationService {
974
1082
  // Get system OAuth credentials from config
975
1083
  const clientId = this.configService.get<string>('OUTLOOK_CLIENT_ID');
976
1084
  const tenantId = this.configService.get<string>('OUTLOOK_TENANT_ID');
977
-
1085
+
978
1086
  if (!clientId || !tenantId) {
979
1087
  throw new Error('Outlook OAuth credentials not configured');
980
1088
  }
981
1089
 
982
1090
  const state = this.generateSecureState();
983
- const callbackUrl = this.configService.get<string>('OUTLOOK_CALLBACK_URL') || 'http://localhost:5001/auth/outlook/callback';
984
-
1091
+ const callbackUrl =
1092
+ this.configService.get<string>('OUTLOOK_CALLBACK_URL') ||
1093
+ 'http://localhost:5001/auth/outlook/callback';
1094
+
985
1095
  this.gmailOAuthStates.set(state, {
986
1096
  levelId,
987
1097
  levelType,
@@ -990,16 +1100,20 @@ export class CommunicationService {
990
1100
  });
991
1101
 
992
1102
  // Auto-cleanup after 10 minutes
993
- setTimeout(() => {
994
- this.gmailOAuthStates.delete(state);
995
- }, 10 * 60 * 1000);
1103
+ setTimeout(
1104
+ () => {
1105
+ this.gmailOAuthStates.delete(state);
1106
+ },
1107
+ 10 * 60 * 1000,
1108
+ );
996
1109
 
997
1110
  const scopes = [
998
1111
  'https://graph.microsoft.com/Mail.Send',
999
1112
  'https://graph.microsoft.com/User.Read',
1000
1113
  ];
1001
1114
 
1002
- const authUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?` +
1115
+ const authUrl =
1116
+ `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?` +
1003
1117
  `client_id=${clientId}&` +
1004
1118
  `response_type=code&` +
1005
1119
  `redirect_uri=${encodeURIComponent(callbackUrl)}&` +
@@ -1033,27 +1147,34 @@ export class CommunicationService {
1033
1147
  }
1034
1148
 
1035
1149
  const clientId = this.configService.get<string>('OUTLOOK_CLIENT_ID');
1036
- const clientSecret = this.configService.get<string>('OUTLOOK_CLIENT_SECRET');
1150
+ const clientSecret = this.configService.get<string>(
1151
+ 'OUTLOOK_CLIENT_SECRET',
1152
+ );
1037
1153
  const tenantId = this.configService.get<string>('OUTLOOK_TENANT_ID');
1038
- const callbackUrl = this.configService.get<string>('OUTLOOK_CALLBACK_URL') || 'http://localhost:5001/auth/outlook/callback';
1154
+ const callbackUrl =
1155
+ this.configService.get<string>('OUTLOOK_CALLBACK_URL') ||
1156
+ 'http://localhost:5001/auth/outlook/callback';
1039
1157
 
1040
1158
  // Exchange code for tokens
1041
- const tokenResponse = await fetch(`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, {
1042
- method: 'POST',
1043
- headers: {
1044
- 'Content-Type': 'application/x-www-form-urlencoded',
1159
+ const tokenResponse = await fetch(
1160
+ `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
1161
+ {
1162
+ method: 'POST',
1163
+ headers: {
1164
+ 'Content-Type': 'application/x-www-form-urlencoded',
1165
+ },
1166
+ body: new URLSearchParams({
1167
+ client_id: clientId!,
1168
+ client_secret: clientSecret!,
1169
+ code: code,
1170
+ redirect_uri: callbackUrl,
1171
+ grant_type: 'authorization_code',
1172
+ }),
1045
1173
  },
1046
- body: new URLSearchParams({
1047
- client_id: clientId!,
1048
- client_secret: clientSecret!,
1049
- code: code,
1050
- redirect_uri: callbackUrl,
1051
- grant_type: 'authorization_code',
1052
- }),
1053
- });
1174
+ );
1054
1175
 
1055
1176
  const tokens = await tokenResponse.json();
1056
-
1177
+
1057
1178
  if (!tokens.access_token) {
1058
1179
  throw new Error('Failed to obtain access token');
1059
1180
  }
@@ -1061,7 +1182,7 @@ export class CommunicationService {
1061
1182
  // Get user info from Microsoft Graph
1062
1183
  const userResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
1063
1184
  headers: {
1064
- 'Authorization': `Bearer ${tokens.access_token}`,
1185
+ Authorization: `Bearer ${tokens.access_token}`,
1065
1186
  },
1066
1187
  });
1067
1188
 
@@ -1111,8 +1232,126 @@ export class CommunicationService {
1111
1232
  configId: savedConfig.id,
1112
1233
  };
1113
1234
  } catch (error) {
1114
- this.logger.error('Error handling Outlook OAuth callback:', error.message);
1235
+ this.logger.error(
1236
+ 'Error handling Outlook OAuth callback:',
1237
+ error.message,
1238
+ );
1115
1239
  throw new Error(`Failed to complete Outlook OAuth: ${error.message}`);
1116
1240
  }
1117
1241
  }
1242
+
1243
+ // Simple Queue Integration Methods
1244
+
1245
+ async queueMessage(
1246
+ messageDto: GenericMessageDto & { useQueue?: boolean; scheduledFor?: Date },
1247
+ ): Promise<{ queued: boolean; messageId?: string; result?: CommunicationResult }> {
1248
+ if (!this.queueService || !messageDto.useQueue) {
1249
+ // Fallback to immediate sending if queue is not available or not requested
1250
+ const result = await this.sendGenericMessage(messageDto);
1251
+ return { queued: false, result };
1252
+ }
1253
+
1254
+ try {
1255
+ const priority = this.mapPriorityToSimpleQueue(messageDto.priority);
1256
+
1257
+ const messageId = await this.queueService.queueMessage(
1258
+ messageDto.levelId,
1259
+ messageDto.levelType,
1260
+ Array.isArray(messageDto.to) ? messageDto.to[0] : messageDto.to,
1261
+ messageDto.message,
1262
+ messageDto.type,
1263
+ priority,
1264
+ messageDto.scheduledFor,
1265
+ {
1266
+ subject: messageDto.subject,
1267
+ html: messageDto.html,
1268
+ cc: messageDto.cc,
1269
+ bcc: messageDto.bcc,
1270
+ attachments: messageDto.attachments,
1271
+ mediaUrl: messageDto.mediaUrl,
1272
+ templateId: messageDto.templateId,
1273
+ variables: messageDto.variables,
1274
+ },
1275
+ );
1276
+
1277
+ return { queued: true, messageId };
1278
+ } catch (error) {
1279
+ this.logger.error('Error queuing message, falling back to immediate send:', error.message);
1280
+ // Fallback to immediate sending
1281
+ const result = await this.sendGenericMessage(messageDto);
1282
+ return { queued: false, result };
1283
+ }
1284
+ }
1285
+
1286
+ async queueBulkMessage(
1287
+ bulkDto: BulkMessageDto & { useQueue?: boolean; scheduledFor?: Date },
1288
+ ): Promise<{ queued: boolean; messageIds?: string[]; result?: any }> {
1289
+ if (!this.queueService || !bulkDto.useQueue) {
1290
+ // Fallback to immediate sending if queue is not available or not requested
1291
+ const result = await this.sendBulkMessage(bulkDto);
1292
+ return { queued: false, result };
1293
+ }
1294
+
1295
+ try {
1296
+ const priority = this.mapPriorityToSimpleQueue(bulkDto.priority) || 'low';
1297
+
1298
+ const messageIds = await this.queueService.queueBulkMessages(
1299
+ bulkDto.levelId,
1300
+ bulkDto.levelType,
1301
+ bulkDto.recipients,
1302
+ bulkDto.message,
1303
+ bulkDto.type,
1304
+ priority,
1305
+ {
1306
+ subject: bulkDto.subject,
1307
+ html: bulkDto.html,
1308
+ templateId: bulkDto.templateId,
1309
+ variables: bulkDto.variables,
1310
+ },
1311
+ );
1312
+
1313
+ return { queued: true, messageIds };
1314
+ } catch (error) {
1315
+ this.logger.error('Error queuing bulk message, falling back to immediate send:', error.message);
1316
+ // Fallback to immediate sending
1317
+ const result = await this.sendBulkMessage(bulkDto);
1318
+ return { queued: false, result };
1319
+ }
1320
+ }
1321
+
1322
+ // Helper method to check if queue service is available
1323
+ isQueueAvailable(): boolean {
1324
+ return !!this.queueService;
1325
+ }
1326
+
1327
+ // Helper method to get queue stats if available
1328
+ getQueueStats() {
1329
+ if (!this.queueService) {
1330
+ return null;
1331
+ }
1332
+
1333
+ return this.queueService.getQueueStats();
1334
+ }
1335
+
1336
+ // Helper method to cancel queued messages
1337
+ cancelQueuedMessage(messageId: string): boolean {
1338
+ if (!this.queueService) {
1339
+ return false;
1340
+ }
1341
+
1342
+ return this.queueService.cancelMessage(messageId);
1343
+ }
1344
+
1345
+ private mapPriorityToSimpleQueue(priority?: string): 'high' | 'medium' | 'low' {
1346
+ switch (priority?.toLowerCase()) {
1347
+ case 'high':
1348
+ case 'urgent':
1349
+ return 'high';
1350
+ case 'low':
1351
+ return 'low';
1352
+ case 'medium':
1353
+ default:
1354
+ return 'medium';
1355
+ }
1356
+ }
1118
1357
  }