rez_core 2.2.158 → 2.2.161

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 (247) 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 +149 -36
  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/communication.strategy.d.ts +1 -0
  34. package/dist/module/communication/strategies/email/gmail-api.strategy.js +16 -7
  35. package/dist/module/communication/strategies/email/gmail-api.strategy.js.map +1 -1
  36. package/dist/module/communication/strategies/gmail-smtp.strategy.js +2 -3
  37. package/dist/module/communication/strategies/gmail-smtp.strategy.js.map +1 -1
  38. package/dist/module/communication/strategies/gmail.strategy.js +20 -1
  39. package/dist/module/communication/strategies/gmail.strategy.js.map +1 -1
  40. package/dist/module/communication/strategies/knowlarity.strategy.js +20 -14
  41. package/dist/module/communication/strategies/knowlarity.strategy.js.map +1 -1
  42. package/dist/module/communication/strategies/outlook-smtp.strategy.js +2 -3
  43. package/dist/module/communication/strategies/outlook-smtp.strategy.js.map +1 -1
  44. package/dist/module/communication/strategies/outlook.strategy.js +1 -1
  45. package/dist/module/communication/strategies/outlook.strategy.js.map +1 -1
  46. package/dist/module/communication/strategies/sms.strategy.js +1 -3
  47. package/dist/module/communication/strategies/sms.strategy.js.map +1 -1
  48. package/dist/module/communication/strategies/whatsapp.strategy.js +1 -2
  49. package/dist/module/communication/strategies/whatsapp.strategy.js.map +1 -1
  50. package/dist/module/dashboard/dashboard.module.js +1 -1
  51. package/dist/module/dashboard/repository/dashboard.repository.js.map +1 -1
  52. package/dist/module/dashboard/service/dashboard.service.js +3 -3
  53. package/dist/module/dashboard/service/dashboard.service.js.map +1 -1
  54. package/dist/module/enterprise/repository/organization.repository.js.map +1 -1
  55. package/dist/module/filter/entity/saved-filter-master.entity.d.ts +1 -1
  56. package/dist/module/filter/service/filter.service.js +3 -3
  57. package/dist/module/filter/service/filter.service.js.map +1 -1
  58. package/dist/module/filter/service/saved-filter.service.js.map +1 -1
  59. package/dist/module/layout/controller/layout.controller.js +1 -1
  60. package/dist/module/layout/controller/layout.controller.js.map +1 -1
  61. package/dist/module/layout/repository/header-section.repository.js.map +1 -1
  62. package/dist/module/layout/service/header-section.service.js +2 -2
  63. package/dist/module/layout/service/header-section.service.js.map +1 -1
  64. package/dist/module/layout_preference/repository/layout_preference.repository.js +1 -1
  65. package/dist/module/layout_preference/service/layout_preference.service.js +1 -1
  66. package/dist/module/layout_preference/service/layout_preference.service.js.map +1 -1
  67. package/dist/module/listmaster/controller/list-master.controller.js +1 -1
  68. package/dist/module/listmaster/controller/list-master.controller.js.map +1 -1
  69. package/dist/module/listmaster/repository/list-master.repository.js.map +1 -1
  70. package/dist/module/listmaster/service/list-master.service.js +2 -2
  71. package/dist/module/listmaster/service/list-master.service.js.map +1 -1
  72. package/dist/module/master/controller/master.controller.js +2 -2
  73. package/dist/module/master/controller/master.controller.js.map +1 -1
  74. package/dist/module/master/service/master.service.js +1 -1
  75. package/dist/module/master/service/master.service.js.map +1 -1
  76. package/dist/module/meta/controller/attribute-master.controller.js +3 -3
  77. package/dist/module/meta/controller/attribute-master.controller.js.map +1 -1
  78. package/dist/module/meta/controller/entity-dynamic.controller.js +1 -1
  79. package/dist/module/meta/controller/entity-dynamic.controller.js.map +1 -1
  80. package/dist/module/meta/controller/entity.controller.js +2 -2
  81. package/dist/module/meta/controller/entity.controller.js.map +1 -1
  82. package/dist/module/meta/controller/media.controller.js +1 -1
  83. package/dist/module/meta/controller/media.controller.js.map +1 -1
  84. package/dist/module/meta/controller/meta.controller.js +1 -1
  85. package/dist/module/meta/controller/meta.controller.js.map +1 -1
  86. package/dist/module/meta/dto/entity-table.dto.js.map +1 -1
  87. package/dist/module/meta/entity/entity-master.entity.d.ts +1 -0
  88. package/dist/module/meta/entity/entity-master.entity.js +4 -0
  89. package/dist/module/meta/entity/entity-master.entity.js.map +1 -1
  90. package/dist/module/meta/entity/entity-table.entity.js.map +1 -1
  91. package/dist/module/meta/service/entity-dynamic.service.js +1 -1
  92. package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
  93. package/dist/module/meta/service/entity-list.service.js +11 -11
  94. package/dist/module/meta/service/entity-list.service.js.map +1 -1
  95. package/dist/module/meta/service/entity-service-impl.service.js +2 -2
  96. package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
  97. package/dist/module/meta/service/entity-table-column.service.js +3 -3
  98. package/dist/module/meta/service/entity-table-column.service.js.map +1 -1
  99. package/dist/module/meta/service/entity-table.service.js +2 -2
  100. package/dist/module/meta/service/entity-table.service.js.map +1 -1
  101. package/dist/module/meta/service/media-data.service.js +3 -3
  102. package/dist/module/meta/service/media-data.service.js.map +1 -1
  103. package/dist/module/meta/service/update-form-json.service.d.ts +3 -3
  104. package/dist/module/meta/service/update-form-json.service.js +1 -1
  105. package/dist/module/meta/service/update-form-json.service.js.map +1 -1
  106. package/dist/module/module/controller/menu.controller.js.map +1 -1
  107. package/dist/module/module/controller/module-access.controller.js +1 -1
  108. package/dist/module/module/controller/module-access.controller.js.map +1 -1
  109. package/dist/module/module/entity/module-access.entity.js.map +1 -1
  110. package/dist/module/module/entity/module.entity.js.map +1 -1
  111. package/dist/module/module/service/module-access.service.d.ts +1 -1
  112. package/dist/module/module/service/module-access.service.js +1 -1
  113. package/dist/module/module/service/module-access.service.js.map +1 -1
  114. package/dist/module/notification/controller/otp.controller.js +3 -3
  115. package/dist/module/notification/controller/otp.controller.js.map +1 -1
  116. package/dist/module/notification/service/email.service.js +2 -2
  117. package/dist/module/notification/service/email.service.js.map +1 -1
  118. package/dist/module/notification/service/otp.service.js +1 -1
  119. package/dist/module/notification/service/otp.service.js.map +1 -1
  120. package/dist/module/user/controller/login.controller.js +4 -2
  121. package/dist/module/user/controller/login.controller.js.map +1 -1
  122. package/dist/module/user/service/login.service.js +3 -3
  123. package/dist/module/user/service/login.service.js.map +1 -1
  124. package/dist/module/user/service/role.service.js +1 -1
  125. package/dist/module/user/service/role.service.js.map +1 -1
  126. package/dist/module/user/service/user.service.js +5 -5
  127. package/dist/module/user/service/user.service.js.map +1 -1
  128. package/dist/module/workflow/controller/workflow-meta.controller.d.ts +1 -1
  129. package/dist/module/workflow/controller/workflow-meta.controller.js +7 -5
  130. package/dist/module/workflow/controller/workflow-meta.controller.js.map +1 -1
  131. package/dist/module/workflow/service/action.service.js +3 -3
  132. package/dist/module/workflow/service/action.service.js.map +1 -1
  133. package/dist/module/workflow/service/stage-group.service.js +1 -1
  134. package/dist/module/workflow/service/stage-group.service.js.map +1 -1
  135. package/dist/module/workflow/service/task.service.js +1 -0
  136. package/dist/module/workflow/service/task.service.js.map +1 -1
  137. package/dist/module/workflow/service/workflow-meta.service.d.ts +1 -1
  138. package/dist/module/workflow/service/workflow-meta.service.js +14 -14
  139. package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
  140. package/dist/resources/properties.module.js +2 -2
  141. package/dist/resources/properties.module.js.map +1 -1
  142. package/dist/tsconfig.build.tsbuildinfo +1 -1
  143. package/dist/utils/service/base64util.service.js.map +1 -1
  144. package/dist/utils/service/clockIDGenUtil.service.js.map +1 -1
  145. package/dist/utils/service/dateUtil.service.js +1 -1
  146. package/dist/utils/service/dateUtil.service.js.map +1 -1
  147. package/dist/utils/service/encryptUtil.service.js +4 -4
  148. package/dist/utils/service/encryptUtil.service.js.map +1 -1
  149. package/dist/utils/service/excel-helper.service.js +4 -1
  150. package/dist/utils/service/excel-helper.service.js.map +1 -1
  151. package/dist/utils/service/json-util.service.js.map +1 -1
  152. package/dist/utils/service/loggingUtil.service.js +3 -3
  153. package/dist/utils/service/loggingUtil.service.js.map +1 -1
  154. package/package.json +1 -1
  155. package/src/decorators/roles.decorator.ts +1 -1
  156. package/src/module/auth/strategies/google.strategy.ts +6 -1
  157. package/src/module/auth/strategies/jwt.strategy.ts +1 -1
  158. package/src/module/communication/communication.module.ts +13 -2
  159. package/src/module/communication/controller/communication.controller.ts +21 -18
  160. package/src/module/communication/dto/create-config.dto.ts +32 -13
  161. package/src/module/communication/entity/communication-config.entity.ts +15 -9
  162. package/src/module/communication/entity/communication-hub.entity.ts +29 -3
  163. package/src/module/communication/examples/usage.example.ts +18 -17
  164. package/src/module/communication/factories/communication.factory.ts +36 -18
  165. package/src/module/communication/factories/email.factory.ts +8 -5
  166. package/src/module/communication/factories/sms.factory.ts +8 -5
  167. package/src/module/communication/factories/telephone.factory.ts +9 -8
  168. package/src/module/communication/factories/whatsapp.factory.ts +9 -8
  169. package/src/module/communication/service/communication-queue.service.ts +214 -0
  170. package/src/module/communication/service/communication.service.ts +381 -112
  171. package/src/module/communication/service/oauth.service.ts +67 -46
  172. package/src/module/communication/strategies/communication.strategy.ts +1 -0
  173. package/src/module/communication/strategies/email/gmail-api.strategy.ts +44 -24
  174. package/src/module/communication/strategies/gmail-smtp.strategy.ts +15 -11
  175. package/src/module/communication/strategies/gmail.strategy.ts +42 -7
  176. package/src/module/communication/strategies/knowlarity.strategy.ts +67 -33
  177. package/src/module/communication/strategies/outlook-smtp.strategy.ts +15 -11
  178. package/src/module/communication/strategies/outlook.strategy.ts +12 -5
  179. package/src/module/communication/strategies/sms.strategy.ts +13 -10
  180. package/src/module/communication/strategies/whatsapp.strategy.ts +13 -9
  181. package/src/module/dashboard/dashboard.module.ts +1 -1
  182. package/src/module/dashboard/repository/dashboard.repository.ts +4 -2
  183. package/src/module/dashboard/service/dashboard.service.ts +16 -12
  184. package/src/module/enterprise/repository/organization.repository.ts +3 -1
  185. package/src/module/enterprise/service/enterprise.service.ts +2 -2
  186. package/src/module/filter/entity/saved-filter-master.entity.ts +3 -3
  187. package/src/module/filter/service/filter.service.ts +3 -3
  188. package/src/module/filter/service/saved-filter.service.ts +1 -1
  189. package/src/module/layout/controller/layout.controller.ts +1 -1
  190. package/src/module/layout/repository/header-section.repository.ts +2 -2
  191. package/src/module/layout/service/header-section.service.ts +2 -3
  192. package/src/module/layout_preference/repository/layout_preference.repository.ts +2 -2
  193. package/src/module/layout_preference/service/layout_preference.service.ts +1 -1
  194. package/src/module/listmaster/controller/list-master.controller.ts +1 -1
  195. package/src/module/listmaster/repository/list-master.repository.ts +2 -2
  196. package/src/module/listmaster/service/list-master.service.ts +2 -2
  197. package/src/module/master/controller/master.controller.ts +2 -2
  198. package/src/module/master/service/master.service.ts +1 -1
  199. package/src/module/meta/controller/attribute-master.controller.ts +3 -3
  200. package/src/module/meta/controller/entity-dynamic.controller.ts +1 -1
  201. package/src/module/meta/controller/entity.controller.ts +2 -2
  202. package/src/module/meta/controller/media.controller.ts +1 -1
  203. package/src/module/meta/controller/meta.controller.ts +1 -1
  204. package/src/module/meta/dto/entity-tab.dto.ts +4 -4
  205. package/src/module/meta/dto/entity-table.dto.ts +5 -6
  206. package/src/module/meta/entity/entity-master.entity.ts +3 -0
  207. package/src/module/meta/entity/entity-table.entity.ts +1 -2
  208. package/src/module/meta/service/entity-dynamic.service.ts +1 -1
  209. package/src/module/meta/service/entity-list.service.ts +18 -14
  210. package/src/module/meta/service/entity-service-impl.service.ts +2 -2
  211. package/src/module/meta/service/entity-table-column.service.ts +3 -3
  212. package/src/module/meta/service/entity-table.service.ts +2 -2
  213. package/src/module/meta/service/entity.service.ts +1 -1
  214. package/src/module/meta/service/media-data.service.ts +3 -3
  215. package/src/module/meta/service/update-form-json.service.ts +17 -26
  216. package/src/module/module/controller/menu.controller.ts +0 -1
  217. package/src/module/module/controller/module-access.controller.ts +2 -3
  218. package/src/module/module/entity/menu.entity.ts +1 -1
  219. package/src/module/module/entity/module-access.entity.ts +6 -6
  220. package/src/module/module/entity/module-action.entity.ts +2 -2
  221. package/src/module/module/entity/module.entity.ts +0 -1
  222. package/src/module/module/service/module-access.service.ts +7 -8
  223. package/src/module/notification/controller/otp.controller.ts +10 -4
  224. package/src/module/notification/repository/otp.repository.ts +1 -1
  225. package/src/module/notification/service/email.service.ts +2 -2
  226. package/src/module/notification/service/otp.service.ts +8 -3
  227. package/src/module/third-party-module/third-party.module.ts +1 -1
  228. package/src/module/user/controller/login.controller.ts +27 -12
  229. package/src/module/user/service/login.service.ts +27 -27
  230. package/src/module/user/service/role.service.ts +1 -1
  231. package/src/module/user/service/user.service.ts +5 -5
  232. package/src/module/workflow/controller/workflow-meta.controller.ts +5 -1
  233. package/src/module/workflow/service/action.service.ts +3 -3
  234. package/src/module/workflow/service/stage-group.service.ts +1 -1
  235. package/src/module/workflow/service/task.service.ts +1 -0
  236. package/src/module/workflow/service/workflow-meta.service.ts +19 -18
  237. package/src/resources/properties.module.ts +10 -10
  238. package/src/utils/dto/excel-data.dto.ts +2 -2
  239. package/src/utils/dto/excelsheet-data.dto.ts +3 -3
  240. package/src/utils/service/base64util.service.ts +16 -17
  241. package/src/utils/service/clockIDGenUtil.service.ts +15 -13
  242. package/src/utils/service/dateUtil.service.ts +6 -6
  243. package/src/utils/service/encryptUtil.service.ts +4 -4
  244. package/src/utils/service/excel-helper.service.ts +4 -1
  245. package/src/utils/service/file-util.service.ts +2 -2
  246. package/src/utils/service/json-util.service.ts +19 -19
  247. 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({
@@ -145,20 +148,22 @@ export class CommunicationService {
145
148
  .createQueryBuilder('hub')
146
149
  .leftJoin('communication_config', 'config', 'config.id = hub.config_id')
147
150
  .select([
148
- 'hub.id',
149
- 'hub.status',
150
- 'hub.config_id',
151
- 'hub.communication_config_type',
152
- 'hub.service',
153
- 'hub.provider',
154
- 'hub.priority',
155
- 'hub.is_default',
156
- 'hub.created_at',
157
- 'hub.updated_at',
151
+ 'hub.id as hub_id',
152
+ 'hub.level_id as hub_level_id',
153
+ 'hub.level_type as hub_level_type',
154
+ 'hub.status as hub_status',
155
+ 'hub.config_id as hub_config_id',
156
+ 'hub.communication_config_type as hub_communication_config_type',
157
+ 'hub.service as hub_service',
158
+ 'hub.provider as hub_provider',
159
+ 'hub.priority as hub_priority',
160
+ 'hub.is_default as hub_is_default',
161
+ 'hub.created_at as hub_created_at',
162
+ 'hub.updated_at as hub_updated_at',
158
163
  'config.id as config_id',
159
164
  'config.config_json as config_json',
160
165
  'config.created_at as config_created_at',
161
- 'config.updated_at as config_updated_at'
166
+ 'config.updated_at as config_updated_at',
162
167
  ])
163
168
  .where('hub.level_id = :levelId', { levelId })
164
169
  .andWhere('hub.level_type = :levelType', { levelType })
@@ -171,7 +176,7 @@ export class CommunicationService {
171
176
  const results = await query.getRawMany();
172
177
 
173
178
  // Transform the raw results into the expected format
174
- const hubsWithConfig: CommunicationHubWithConfig[] = results.map(row => ({
179
+ const hubsWithConfig: CommunicationHubWithConfig[] = results.map((row) => ({
175
180
  id: row.hub_id,
176
181
  level_id: row.hub_level_id,
177
182
  level_type: row.hub_level_type,
@@ -214,7 +219,32 @@ export class CommunicationService {
214
219
  hub.provider,
215
220
  );
216
221
 
217
- return strategy.sendMessage(to, message, hub.config.config_json);
222
+ const result = await strategy.sendMessage(to, message, hub.config.config_json);
223
+
224
+ // If token was refreshed, update it in the database
225
+ if (result.refreshedToken && result.success) {
226
+ try {
227
+ const currentConfig = hub.config.config_json as any;
228
+ const updatedConfig = {
229
+ ...currentConfig,
230
+ accessToken: result.refreshedToken,
231
+ };
232
+
233
+ await this.configRepository.update(hub.config.id, {
234
+ config_json: updatedConfig,
235
+ } as any);
236
+
237
+ this.logger.log(
238
+ `Updated access token for ${hub.provider}/${hub.service} configuration`,
239
+ );
240
+ } catch (error) {
241
+ this.logger.warn(
242
+ `Failed to update refreshed token in database: ${error.message}`,
243
+ );
244
+ }
245
+ }
246
+
247
+ return result;
218
248
  }
219
249
 
220
250
  async createCommunicationConfig(
@@ -226,29 +256,57 @@ export class CommunicationService {
226
256
  config: any,
227
257
  priority?: number,
228
258
  is_default?: boolean,
229
- ): Promise<CommunicationHub | { authUrl: string; state: string; message: string }> {
259
+ ): Promise<
260
+ CommunicationHub | { authUrl: string; state: string; message: string }
261
+ > {
230
262
  // Validate service/provider combination using supported combinations
231
263
  const supportedCombinations = await this.getSupportedCombinations();
232
264
  const isValidCombination = supportedCombinations.some(
233
- combo => combo.mode === configType &&
234
- combo.service.toLowerCase() === service.toLowerCase() &&
235
- combo.provider.toLowerCase() === provider.toLowerCase()
265
+ (combo) =>
266
+ combo.mode === configType &&
267
+ combo.service.toLowerCase() === service.toLowerCase() &&
268
+ combo.provider.toLowerCase() === provider.toLowerCase(),
236
269
  );
237
-
270
+
238
271
  if (!isValidCombination) {
239
- throw new Error(`Unsupported combination: ${configType}/${service}/${provider}`);
272
+ throw new Error(
273
+ `Unsupported combination: ${configType}/${service}/${provider}`,
274
+ );
240
275
  }
241
276
 
242
277
  // Check if this requires OAuth flow
243
- const requiresOAuth = this.requiresOAuthFlow(configType, service, provider, config);
244
-
278
+ const requiresOAuth = this.requiresOAuthFlow(
279
+ configType,
280
+ service,
281
+ provider,
282
+ config,
283
+ );
284
+
245
285
  if (requiresOAuth) {
246
286
  // 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);
287
+ return await this.generateOAuthUrl(
288
+ levelId,
289
+ levelType,
290
+ configType,
291
+ service,
292
+ provider,
293
+ config,
294
+ priority,
295
+ is_default,
296
+ );
248
297
  }
249
298
 
250
299
  // Direct config creation (non-OAuth flow)
251
- return await this.createDirectConfig(levelId, levelType, configType, service, provider, config, priority, is_default);
300
+ return await this.createDirectConfig(
301
+ levelId,
302
+ levelType,
303
+ configType,
304
+ service,
305
+ provider,
306
+ config,
307
+ priority,
308
+ is_default,
309
+ );
252
310
  }
253
311
 
254
312
  async getSupportedCombinations(): Promise<
@@ -275,7 +333,9 @@ export class CommunicationService {
275
333
  await this.hubRepository.update(hubId, { status });
276
334
  }
277
335
 
278
- async sendGenericMessage(messageDto: GenericMessageDto): Promise<CommunicationResult> {
336
+ async sendGenericMessage(
337
+ messageDto: GenericMessageDto,
338
+ ): Promise<CommunicationResult> {
279
339
  try {
280
340
  const {
281
341
  levelId,
@@ -291,17 +351,26 @@ export class CommunicationService {
291
351
  attachments,
292
352
  mediaUrl,
293
353
  templateId,
294
- variables
354
+ variables,
295
355
  } = messageDto;
296
356
 
297
357
  // Auto-detect communication type if not specified
298
358
  const communicationType = this.detectCommunicationType(to, type);
299
-
359
+
300
360
  // Get active hubs for the detected type
301
- const hubs = await this.getActiveHubs(levelId, levelType, communicationType);
302
-
361
+ const hubs = await this.getActiveHubs(
362
+ levelId,
363
+ levelType,
364
+ communicationType,
365
+ );
366
+
303
367
  if (!hubs.length) {
304
- throw new Error(`No active ${communicationType} configuration found for ${levelType} ${levelId}`);
368
+ this.logger.warn(
369
+ `No communication hubs found for ${levelType} ${levelId}. Please configure communication providers using the createCommunicationConfig method.`
370
+ );
371
+ throw new Error(
372
+ `No active ${communicationType} configuration found for ${levelType} ${levelId}. Please configure a communication provider first.`,
373
+ );
305
374
  }
306
375
 
307
376
  // Sort hubs by priority and default preference
@@ -338,10 +407,17 @@ export class CommunicationService {
338
407
  }
339
408
 
340
409
  // Merge config with enhanced parameters
341
- const finalConfig = { ...hub.config.config_json, ...enhancedConfig };
410
+ const finalConfig = {
411
+ ...hub.config.config_json,
412
+ ...enhancedConfig,
413
+ };
414
+
415
+ const result = await strategy.sendMessage(
416
+ recipient,
417
+ processedMessage,
418
+ finalConfig,
419
+ );
342
420
 
343
- const result = await strategy.sendMessage(recipient, processedMessage, finalConfig);
344
-
345
421
  if (result.success) {
346
422
  this.logger.log(
347
423
  `Generic message sent successfully via ${hub.provider}/${hub.service} to ${recipient}`,
@@ -367,7 +443,7 @@ export class CommunicationService {
367
443
  if (hasSuccess) {
368
444
  return {
369
445
  success: true,
370
- messageId: results.map(r => r.messageId).join(','),
446
+ messageId: results.map((r) => r.messageId).join(','),
371
447
  provider: 'multiple',
372
448
  service: 'multiple',
373
449
  timestamp: new Date(),
@@ -390,10 +466,17 @@ export class CommunicationService {
390
466
  }
391
467
 
392
468
  // Merge config with enhanced parameters
393
- const finalConfig = { ...hub.config.config_json, ...enhancedConfig };
469
+ const finalConfig = {
470
+ ...hub.config.config_json,
471
+ ...enhancedConfig,
472
+ };
473
+
474
+ const result = await strategy.sendMessage(
475
+ to,
476
+ processedMessage,
477
+ finalConfig,
478
+ );
394
479
 
395
- const result = await strategy.sendMessage(to, processedMessage, finalConfig);
396
-
397
480
  if (result.success) {
398
481
  this.logger.log(
399
482
  `Generic message sent successfully via ${hub.provider}/${hub.service} to ${to}`,
@@ -421,7 +504,9 @@ export class CommunicationService {
421
504
  }
422
505
  }
423
506
 
424
- async sendBulkMessage(bulkDto: BulkMessageDto): Promise<{ results: CommunicationResult[]; summary: any }> {
507
+ async sendBulkMessage(
508
+ bulkDto: BulkMessageDto,
509
+ ): Promise<{ results: CommunicationResult[]; summary: any }> {
425
510
  try {
426
511
  const {
427
512
  levelId,
@@ -434,7 +519,7 @@ export class CommunicationService {
434
519
  html,
435
520
  templateId,
436
521
  variables,
437
- batchSize = 10
522
+ batchSize = 10,
438
523
  } = bulkDto;
439
524
 
440
525
  const results: CommunicationResult[] = [];
@@ -442,7 +527,9 @@ export class CommunicationService {
442
527
 
443
528
  for (let i = 0; i < batches.length; i++) {
444
529
  const batch = batches[i];
445
- this.logger.log(`Processing batch ${i + 1}/${batches.length} with ${batch.length} recipients`);
530
+ this.logger.log(
531
+ `Processing batch ${i + 1}/${batches.length} with ${batch.length} recipients`,
532
+ );
446
533
 
447
534
  const batchPromises = batch.map(async (recipient) => {
448
535
  try {
@@ -490,18 +577,24 @@ export class CommunicationService {
490
577
 
491
578
  // Rate limiting delay between batches
492
579
  if (i < batches.length - 1) {
493
- await new Promise(resolve => setTimeout(resolve, 1000));
580
+ await new Promise((resolve) => setTimeout(resolve, 1000));
494
581
  }
495
582
  }
496
583
 
497
584
  const summary = {
498
585
  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) + '%',
586
+ successful: results.filter((r) => r.success).length,
587
+ failed: results.filter((r) => !r.success).length,
588
+ successRate:
589
+ (
590
+ (results.filter((r) => r.success).length / results.length) *
591
+ 100
592
+ ).toFixed(2) + '%',
502
593
  };
503
594
 
504
- this.logger.log(`Bulk message completed: ${summary.successful}/${summary.total} successful`);
595
+ this.logger.log(
596
+ `Bulk message completed: ${summary.successful}/${summary.total} successful`,
597
+ );
505
598
 
506
599
  return { results, summary };
507
600
  } catch (error) {
@@ -510,10 +603,12 @@ export class CommunicationService {
510
603
  }
511
604
  }
512
605
 
513
- async scheduleMessage(scheduledDto: any): Promise<{ scheduled: boolean; scheduleId?: string }> {
606
+ async scheduleMessage(
607
+ scheduledDto: any,
608
+ ): Promise<{ scheduled: boolean; scheduleId?: string }> {
514
609
  // For now, return a placeholder. In production, integrate with a job queue like Bull or Agenda
515
610
  this.logger.log(`Message scheduled for ${scheduledDto.scheduleFor}`);
516
-
611
+
517
612
  return {
518
613
  scheduled: true,
519
614
  scheduleId: `sched_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,
@@ -523,9 +618,14 @@ export class CommunicationService {
523
618
  async sendTemplateMessage(templateDto: any): Promise<CommunicationResult> {
524
619
  // Get template content (integrate with your template system)
525
620
  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;
621
+
622
+ const processedMessage = this.processTemplate(
623
+ template.content,
624
+ templateDto.variables,
625
+ );
626
+ const processedSubject = template.subject
627
+ ? this.processTemplate(template.subject, templateDto.variables)
628
+ : undefined;
529
629
 
530
630
  const messageDto: GenericMessageDto = {
531
631
  levelId: templateDto.levelId,
@@ -541,7 +641,10 @@ export class CommunicationService {
541
641
  return this.sendGenericMessage(messageDto);
542
642
  }
543
643
 
544
- private detectCommunicationType(to: string | string[], type?: string): CommunicationConfigType {
644
+ private detectCommunicationType(
645
+ to: string | string[],
646
+ type?: string,
647
+ ): CommunicationConfigType {
545
648
  if (type) {
546
649
  return type as CommunicationConfigType;
547
650
  }
@@ -572,18 +675,23 @@ export class CommunicationService {
572
675
  if (a.is_default !== b.is_default) {
573
676
  return b.is_default ? 1 : -1;
574
677
  }
575
-
678
+
576
679
  // Then sort by priority (lower number = higher priority)
577
680
  if (a.priority !== b.priority) {
578
681
  return a.priority - b.priority;
579
682
  }
580
-
683
+
581
684
  // Finally sort by created_at descending (newest first)
582
- return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
685
+ return (
686
+ new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
687
+ );
583
688
  });
584
689
  }
585
690
 
586
- private processTemplate(template: string, variables: Record<string, any>): string {
691
+ private processTemplate(
692
+ template: string,
693
+ variables: Record<string, any>,
694
+ ): string {
587
695
  return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
588
696
  const value = variables[key];
589
697
  return value !== undefined ? String(value) : match;
@@ -617,15 +725,17 @@ export class CommunicationService {
617
725
  // Get system OAuth credentials from config
618
726
  const clientId = this.configService.get<string>('CLIENT_ID');
619
727
  const clientSecret = this.configService.get<string>('CLIENT_SECRET');
620
-
728
+
621
729
  if (!clientId || !clientSecret) {
622
730
  throw new Error('Gmail OAuth credentials not configured');
623
731
  }
624
732
 
625
733
  const state = this.generateSecureState();
626
734
  // Use the existing registered callback URL
627
- const callbackUrl = this.configService.get<string>('CALLBACK_URL') || 'http://localhost:5001/auth/google/callback';
628
-
735
+ const callbackUrl =
736
+ this.configService.get<string>('CALLBACK_URL') ||
737
+ 'http://localhost:5001/auth/google/callback';
738
+
629
739
  this.gmailOAuthStates.set(state, {
630
740
  levelId,
631
741
  levelType,
@@ -634,9 +744,12 @@ export class CommunicationService {
634
744
  });
635
745
 
636
746
  // Auto-cleanup after 10 minutes
637
- setTimeout(() => {
638
- this.gmailOAuthStates.delete(state);
639
- }, 10 * 60 * 1000);
747
+ setTimeout(
748
+ () => {
749
+ this.gmailOAuthStates.delete(state);
750
+ },
751
+ 10 * 60 * 1000,
752
+ );
640
753
 
641
754
  const oauth2Client = new google.auth.OAuth2(
642
755
  clientId,
@@ -684,7 +797,9 @@ export class CommunicationService {
684
797
  // Get system OAuth credentials
685
798
  const clientId = this.configService.get<string>('CLIENT_ID');
686
799
  const clientSecret = this.configService.get<string>('CLIENT_SECRET');
687
- const callbackUrl = this.configService.get<string>('CALLBACK_URL') || 'http://localhost:5001/auth/google/callback';
800
+ const callbackUrl =
801
+ this.configService.get<string>('CALLBACK_URL') ||
802
+ 'http://localhost:5001/auth/google/callback';
688
803
 
689
804
  const oauth2Client = new google.auth.OAuth2(
690
805
  clientId,
@@ -693,7 +808,7 @@ export class CommunicationService {
693
808
  );
694
809
 
695
810
  const { tokens } = await oauth2Client.getToken(code);
696
-
811
+
697
812
  if (!tokens.access_token) {
698
813
  throw new Error('Failed to obtain access token');
699
814
  }
@@ -821,11 +936,15 @@ export class CommunicationService {
821
936
  };
822
937
  } catch (error) {
823
938
  this.logger.error('Error handling Gmail tokens callback:', error.message);
824
- throw new Error(`Failed to complete Gmail tokens callback: ${error.message}`);
939
+ throw new Error(
940
+ `Failed to complete Gmail tokens callback: ${error.message}`,
941
+ );
825
942
  }
826
943
  }
827
944
 
828
- async testGmailConfig(hubId: number): Promise<{ success: boolean; error?: string }> {
945
+ async testGmailConfig(
946
+ hubId: number,
947
+ ): Promise<{ success: boolean; error?: string }> {
829
948
  try {
830
949
  const hub = await this.hubRepository.findOne({
831
950
  where: { id: hubId },
@@ -843,10 +962,15 @@ export class CommunicationService {
843
962
  throw new Error('Configuration not found');
844
963
  }
845
964
 
846
- const isValid = await this.gmailApiStrategy.validateConnection(config.config_json);
847
-
965
+ const isValid = await this.gmailApiStrategy.validateConnection(
966
+ config.config_json,
967
+ );
968
+
848
969
  if (!isValid) {
849
- return { success: false, error: 'Gmail configuration is invalid or expired' };
970
+ return {
971
+ success: false,
972
+ error: 'Gmail configuration is invalid or expired',
973
+ };
850
974
  }
851
975
 
852
976
  return { success: true };
@@ -864,20 +988,20 @@ export class CommunicationService {
864
988
  configType: CommunicationConfigType,
865
989
  service: string,
866
990
  provider: string,
867
- config: any
991
+ config: any,
868
992
  ): boolean {
869
993
  // Check if config indicates OAuth is needed (missing tokens or explicit OAuth request)
870
994
  const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
871
-
995
+
872
996
  switch (key) {
873
997
  case 'email_api_gmail':
874
998
  // Requires OAuth if no access token provided or OAuth explicitly requested
875
999
  return !config.accessToken || config.useOAuth === true;
876
-
1000
+
877
1001
  case 'email_api_outlook':
878
1002
  // Requires OAuth if no access token provided or OAuth explicitly requested
879
1003
  return !config.accessToken || config.useOAuth === true;
880
-
1004
+
881
1005
  default:
882
1006
  // Most other providers don't require OAuth
883
1007
  return false;
@@ -892,29 +1016,41 @@ export class CommunicationService {
892
1016
  provider: string,
893
1017
  config: any,
894
1018
  priority?: number,
895
- is_default?: boolean
1019
+ is_default?: boolean,
896
1020
  ): Promise<{ authUrl: string; state: string; message: string }> {
897
1021
  const key = `${configType.toLowerCase()}_${service.toLowerCase()}_${provider.toLowerCase()}`;
898
-
1022
+
899
1023
  switch (key) {
900
1024
  case 'email_api_gmail':
901
- const gmailResult = await this.initGmailOAuth(levelId, levelType, config.email);
1025
+ const gmailResult = await this.initGmailOAuth(
1026
+ levelId,
1027
+ levelType,
1028
+ config.email,
1029
+ );
902
1030
  return {
903
1031
  authUrl: gmailResult.authUrl,
904
1032
  state: gmailResult.state,
905
- message: 'Please complete Gmail OAuth authorization. Configuration will be created automatically after authorization.'
1033
+ message:
1034
+ 'Please complete Gmail OAuth authorization. Configuration will be created automatically after authorization.',
906
1035
  };
907
-
1036
+
908
1037
  case 'email_api_outlook':
909
- const outlookResult = await this.initOutlookOAuth(levelId, levelType, config.email);
1038
+ const outlookResult = await this.initOutlookOAuth(
1039
+ levelId,
1040
+ levelType,
1041
+ config.email,
1042
+ );
910
1043
  return {
911
1044
  authUrl: outlookResult.authUrl,
912
1045
  state: outlookResult.state,
913
- message: 'Please complete Outlook OAuth authorization. Configuration will be created automatically after authorization.'
1046
+ message:
1047
+ 'Please complete Outlook OAuth authorization. Configuration will be created automatically after authorization.',
914
1048
  };
915
-
1049
+
916
1050
  default:
917
- throw new Error(`OAuth not supported for ${configType}/${service}/${provider}`);
1051
+ throw new Error(
1052
+ `OAuth not supported for ${configType}/${service}/${provider}`,
1053
+ );
918
1054
  }
919
1055
  }
920
1056
 
@@ -926,23 +1062,23 @@ export class CommunicationService {
926
1062
  provider: string,
927
1063
  config: any,
928
1064
  priority?: number,
929
- is_default?: boolean
1065
+ is_default?: boolean,
930
1066
  ): Promise<CommunicationHub> {
931
1067
  // If setting as default, remove default from other configurations of same type
932
1068
  if (is_default) {
933
1069
  await this.hubRepository.update(
934
- {
1070
+ {
935
1071
  level_id: levelId,
936
1072
  level_type: levelType,
937
1073
  communication_config_type: configType,
938
1074
  },
939
- { is_default: false }
1075
+ { is_default: false },
940
1076
  );
941
1077
  }
942
1078
 
943
1079
  // First, create the config
944
1080
  const communicationConfig = this.configRepository.create({
945
- config_json: config as any,
1081
+ config_json: config,
946
1082
  });
947
1083
  const savedConfig = await this.configRepository.save(communicationConfig);
948
1084
 
@@ -960,8 +1096,10 @@ export class CommunicationService {
960
1096
  });
961
1097
 
962
1098
  const savedHub = await this.hubRepository.save(hub);
963
- this.logger.log(`Communication config created: ${configType}/${service}/${provider} for ${levelType} ${levelId}`);
964
-
1099
+ this.logger.log(
1100
+ `Communication config created: ${configType}/${service}/${provider} for ${levelType} ${levelId}`,
1101
+ );
1102
+
965
1103
  return Array.isArray(savedHub) ? savedHub[0] : savedHub;
966
1104
  }
967
1105
 
@@ -974,14 +1112,16 @@ export class CommunicationService {
974
1112
  // Get system OAuth credentials from config
975
1113
  const clientId = this.configService.get<string>('OUTLOOK_CLIENT_ID');
976
1114
  const tenantId = this.configService.get<string>('OUTLOOK_TENANT_ID');
977
-
1115
+
978
1116
  if (!clientId || !tenantId) {
979
1117
  throw new Error('Outlook OAuth credentials not configured');
980
1118
  }
981
1119
 
982
1120
  const state = this.generateSecureState();
983
- const callbackUrl = this.configService.get<string>('OUTLOOK_CALLBACK_URL') || 'http://localhost:5001/auth/outlook/callback';
984
-
1121
+ const callbackUrl =
1122
+ this.configService.get<string>('OUTLOOK_CALLBACK_URL') ||
1123
+ 'http://localhost:5001/auth/outlook/callback';
1124
+
985
1125
  this.gmailOAuthStates.set(state, {
986
1126
  levelId,
987
1127
  levelType,
@@ -990,16 +1130,20 @@ export class CommunicationService {
990
1130
  });
991
1131
 
992
1132
  // Auto-cleanup after 10 minutes
993
- setTimeout(() => {
994
- this.gmailOAuthStates.delete(state);
995
- }, 10 * 60 * 1000);
1133
+ setTimeout(
1134
+ () => {
1135
+ this.gmailOAuthStates.delete(state);
1136
+ },
1137
+ 10 * 60 * 1000,
1138
+ );
996
1139
 
997
1140
  const scopes = [
998
1141
  'https://graph.microsoft.com/Mail.Send',
999
1142
  'https://graph.microsoft.com/User.Read',
1000
1143
  ];
1001
1144
 
1002
- const authUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?` +
1145
+ const authUrl =
1146
+ `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize?` +
1003
1147
  `client_id=${clientId}&` +
1004
1148
  `response_type=code&` +
1005
1149
  `redirect_uri=${encodeURIComponent(callbackUrl)}&` +
@@ -1033,27 +1177,34 @@ export class CommunicationService {
1033
1177
  }
1034
1178
 
1035
1179
  const clientId = this.configService.get<string>('OUTLOOK_CLIENT_ID');
1036
- const clientSecret = this.configService.get<string>('OUTLOOK_CLIENT_SECRET');
1180
+ const clientSecret = this.configService.get<string>(
1181
+ 'OUTLOOK_CLIENT_SECRET',
1182
+ );
1037
1183
  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';
1184
+ const callbackUrl =
1185
+ this.configService.get<string>('OUTLOOK_CALLBACK_URL') ||
1186
+ 'http://localhost:5001/auth/outlook/callback';
1039
1187
 
1040
1188
  // 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',
1189
+ const tokenResponse = await fetch(
1190
+ `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
1191
+ {
1192
+ method: 'POST',
1193
+ headers: {
1194
+ 'Content-Type': 'application/x-www-form-urlencoded',
1195
+ },
1196
+ body: new URLSearchParams({
1197
+ client_id: clientId!,
1198
+ client_secret: clientSecret!,
1199
+ code: code,
1200
+ redirect_uri: callbackUrl,
1201
+ grant_type: 'authorization_code',
1202
+ }),
1045
1203
  },
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
- });
1204
+ );
1054
1205
 
1055
1206
  const tokens = await tokenResponse.json();
1056
-
1207
+
1057
1208
  if (!tokens.access_token) {
1058
1209
  throw new Error('Failed to obtain access token');
1059
1210
  }
@@ -1061,7 +1212,7 @@ export class CommunicationService {
1061
1212
  // Get user info from Microsoft Graph
1062
1213
  const userResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
1063
1214
  headers: {
1064
- 'Authorization': `Bearer ${tokens.access_token}`,
1215
+ Authorization: `Bearer ${tokens.access_token}`,
1065
1216
  },
1066
1217
  });
1067
1218
 
@@ -1111,8 +1262,126 @@ export class CommunicationService {
1111
1262
  configId: savedConfig.id,
1112
1263
  };
1113
1264
  } catch (error) {
1114
- this.logger.error('Error handling Outlook OAuth callback:', error.message);
1265
+ this.logger.error(
1266
+ 'Error handling Outlook OAuth callback:',
1267
+ error.message,
1268
+ );
1115
1269
  throw new Error(`Failed to complete Outlook OAuth: ${error.message}`);
1116
1270
  }
1117
1271
  }
1272
+
1273
+ // Simple Queue Integration Methods
1274
+
1275
+ async queueMessage(
1276
+ messageDto: GenericMessageDto & { useQueue?: boolean; scheduledFor?: Date },
1277
+ ): Promise<{ queued: boolean; messageId?: string; result?: CommunicationResult }> {
1278
+ if (!this.queueService || !messageDto.useQueue) {
1279
+ // Fallback to immediate sending if queue is not available or not requested
1280
+ const result = await this.sendGenericMessage(messageDto);
1281
+ return { queued: false, result };
1282
+ }
1283
+
1284
+ try {
1285
+ const priority = this.mapPriorityToSimpleQueue(messageDto.priority);
1286
+
1287
+ const messageId = await this.queueService.queueMessage(
1288
+ messageDto.levelId,
1289
+ messageDto.levelType,
1290
+ Array.isArray(messageDto.to) ? messageDto.to[0] : messageDto.to,
1291
+ messageDto.message,
1292
+ messageDto.type,
1293
+ priority,
1294
+ messageDto.scheduledFor,
1295
+ {
1296
+ subject: messageDto.subject,
1297
+ html: messageDto.html,
1298
+ cc: messageDto.cc,
1299
+ bcc: messageDto.bcc,
1300
+ attachments: messageDto.attachments,
1301
+ mediaUrl: messageDto.mediaUrl,
1302
+ templateId: messageDto.templateId,
1303
+ variables: messageDto.variables,
1304
+ },
1305
+ );
1306
+
1307
+ return { queued: true, messageId };
1308
+ } catch (error) {
1309
+ this.logger.error('Error queuing message, falling back to immediate send:', error.message);
1310
+ // Fallback to immediate sending
1311
+ const result = await this.sendGenericMessage(messageDto);
1312
+ return { queued: false, result };
1313
+ }
1314
+ }
1315
+
1316
+ async queueBulkMessage(
1317
+ bulkDto: BulkMessageDto & { useQueue?: boolean; scheduledFor?: Date },
1318
+ ): Promise<{ queued: boolean; messageIds?: string[]; result?: any }> {
1319
+ if (!this.queueService || !bulkDto.useQueue) {
1320
+ // Fallback to immediate sending if queue is not available or not requested
1321
+ const result = await this.sendBulkMessage(bulkDto);
1322
+ return { queued: false, result };
1323
+ }
1324
+
1325
+ try {
1326
+ const priority = this.mapPriorityToSimpleQueue(bulkDto.priority) || 'low';
1327
+
1328
+ const messageIds = await this.queueService.queueBulkMessages(
1329
+ bulkDto.levelId,
1330
+ bulkDto.levelType,
1331
+ bulkDto.recipients,
1332
+ bulkDto.message,
1333
+ bulkDto.type,
1334
+ priority,
1335
+ {
1336
+ subject: bulkDto.subject,
1337
+ html: bulkDto.html,
1338
+ templateId: bulkDto.templateId,
1339
+ variables: bulkDto.variables,
1340
+ },
1341
+ );
1342
+
1343
+ return { queued: true, messageIds };
1344
+ } catch (error) {
1345
+ this.logger.error('Error queuing bulk message, falling back to immediate send:', error.message);
1346
+ // Fallback to immediate sending
1347
+ const result = await this.sendBulkMessage(bulkDto);
1348
+ return { queued: false, result };
1349
+ }
1350
+ }
1351
+
1352
+ // Helper method to check if queue service is available
1353
+ isQueueAvailable(): boolean {
1354
+ return !!this.queueService;
1355
+ }
1356
+
1357
+ // Helper method to get queue stats if available
1358
+ getQueueStats() {
1359
+ if (!this.queueService) {
1360
+ return null;
1361
+ }
1362
+
1363
+ return this.queueService.getQueueStats();
1364
+ }
1365
+
1366
+ // Helper method to cancel queued messages
1367
+ cancelQueuedMessage(messageId: string): boolean {
1368
+ if (!this.queueService) {
1369
+ return false;
1370
+ }
1371
+
1372
+ return this.queueService.cancelMessage(messageId);
1373
+ }
1374
+
1375
+ private mapPriorityToSimpleQueue(priority?: string): 'high' | 'medium' | 'low' {
1376
+ switch (priority?.toLowerCase()) {
1377
+ case 'high':
1378
+ case 'urgent':
1379
+ return 'high';
1380
+ case 'low':
1381
+ return 'low';
1382
+ case 'medium':
1383
+ default:
1384
+ return 'medium';
1385
+ }
1386
+ }
1118
1387
  }