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.
- package/dist/module/auth/strategies/google.strategy.js +6 -1
- package/dist/module/auth/strategies/google.strategy.js.map +1 -1
- package/dist/module/auth/strategies/jwt.strategy.js +1 -1
- package/dist/module/auth/strategies/jwt.strategy.js.map +1 -1
- package/dist/module/communication/communication.module.js +13 -2
- package/dist/module/communication/communication.module.js.map +1 -1
- package/dist/module/communication/controller/communication.controller.js.map +1 -1
- package/dist/module/communication/dto/create-config.dto.js +11 -1
- package/dist/module/communication/dto/create-config.dto.js.map +1 -1
- package/dist/module/communication/entity/communication-config.entity.js.map +1 -1
- package/dist/module/communication/entity/communication-hub.entity.js +11 -1
- package/dist/module/communication/entity/communication-hub.entity.js.map +1 -1
- package/dist/module/communication/examples/usage.example.js +9 -9
- package/dist/module/communication/examples/usage.example.js.map +1 -1
- package/dist/module/communication/factories/communication.factory.js +4 -4
- package/dist/module/communication/factories/communication.factory.js.map +1 -1
- package/dist/module/communication/factories/email.factory.js +1 -1
- package/dist/module/communication/factories/email.factory.js.map +1 -1
- package/dist/module/communication/factories/sms.factory.js +1 -1
- package/dist/module/communication/factories/sms.factory.js.map +1 -1
- package/dist/module/communication/factories/telephone.factory.js +2 -4
- package/dist/module/communication/factories/telephone.factory.js.map +1 -1
- package/dist/module/communication/factories/whatsapp.factory.js +2 -4
- package/dist/module/communication/factories/whatsapp.factory.js.map +1 -1
- package/dist/module/communication/service/communication-queue.service.d.ts +40 -0
- package/dist/module/communication/service/communication-queue.service.js +147 -0
- package/dist/module/communication/service/communication-queue.service.js.map +1 -0
- package/dist/module/communication/service/communication.service.d.ts +34 -2
- package/dist/module/communication/service/communication.service.js +117 -24
- package/dist/module/communication/service/communication.service.js.map +1 -1
- package/dist/module/communication/service/oauth.service.js +25 -20
- package/dist/module/communication/service/oauth.service.js.map +1 -1
- package/dist/module/communication/strategies/email/gmail-api.strategy.js +16 -7
- package/dist/module/communication/strategies/email/gmail-api.strategy.js.map +1 -1
- package/dist/module/communication/strategies/gmail-smtp.strategy.js +2 -3
- package/dist/module/communication/strategies/gmail-smtp.strategy.js.map +1 -1
- package/dist/module/communication/strategies/gmail.strategy.js.map +1 -1
- package/dist/module/communication/strategies/knowlarity.strategy.js +20 -14
- package/dist/module/communication/strategies/knowlarity.strategy.js.map +1 -1
- package/dist/module/communication/strategies/outlook-smtp.strategy.js +2 -3
- package/dist/module/communication/strategies/outlook-smtp.strategy.js.map +1 -1
- package/dist/module/communication/strategies/outlook.strategy.js +1 -1
- package/dist/module/communication/strategies/outlook.strategy.js.map +1 -1
- package/dist/module/communication/strategies/sms.strategy.js +1 -3
- package/dist/module/communication/strategies/sms.strategy.js.map +1 -1
- package/dist/module/communication/strategies/whatsapp.strategy.js +1 -2
- package/dist/module/communication/strategies/whatsapp.strategy.js.map +1 -1
- package/dist/module/dashboard/dashboard.module.js +1 -1
- package/dist/module/dashboard/repository/dashboard.repository.js.map +1 -1
- package/dist/module/dashboard/service/dashboard.service.js +3 -3
- package/dist/module/dashboard/service/dashboard.service.js.map +1 -1
- package/dist/module/enterprise/repository/organization.repository.js.map +1 -1
- package/dist/module/filter/entity/saved-filter-master.entity.d.ts +1 -1
- package/dist/module/filter/service/filter.service.js +3 -3
- package/dist/module/filter/service/filter.service.js.map +1 -1
- package/dist/module/filter/service/saved-filter.service.js.map +1 -1
- package/dist/module/layout/controller/layout.controller.js +1 -1
- package/dist/module/layout/controller/layout.controller.js.map +1 -1
- package/dist/module/layout/repository/header-section.repository.js.map +1 -1
- package/dist/module/layout/service/header-section.service.js +2 -2
- package/dist/module/layout/service/header-section.service.js.map +1 -1
- package/dist/module/layout_preference/repository/layout_preference.repository.js +1 -1
- package/dist/module/layout_preference/service/layout_preference.service.js +1 -1
- package/dist/module/layout_preference/service/layout_preference.service.js.map +1 -1
- package/dist/module/listmaster/controller/list-master.controller.js +1 -1
- package/dist/module/listmaster/controller/list-master.controller.js.map +1 -1
- package/dist/module/listmaster/repository/list-master.repository.js.map +1 -1
- package/dist/module/listmaster/service/list-master.service.js +2 -2
- package/dist/module/listmaster/service/list-master.service.js.map +1 -1
- package/dist/module/master/controller/master.controller.js +2 -2
- package/dist/module/master/controller/master.controller.js.map +1 -1
- package/dist/module/master/service/master.service.js +1 -1
- package/dist/module/master/service/master.service.js.map +1 -1
- package/dist/module/meta/controller/attribute-master.controller.js +3 -3
- package/dist/module/meta/controller/attribute-master.controller.js.map +1 -1
- package/dist/module/meta/controller/entity-dynamic.controller.js +1 -1
- package/dist/module/meta/controller/entity-dynamic.controller.js.map +1 -1
- package/dist/module/meta/controller/entity.controller.js +2 -2
- package/dist/module/meta/controller/entity.controller.js.map +1 -1
- package/dist/module/meta/controller/media.controller.js +1 -1
- package/dist/module/meta/controller/media.controller.js.map +1 -1
- package/dist/module/meta/controller/meta.controller.js +1 -1
- package/dist/module/meta/controller/meta.controller.js.map +1 -1
- package/dist/module/meta/dto/entity-table.dto.js.map +1 -1
- package/dist/module/meta/entity/entity-master.entity.d.ts +1 -0
- package/dist/module/meta/entity/entity-master.entity.js +4 -0
- package/dist/module/meta/entity/entity-master.entity.js.map +1 -1
- package/dist/module/meta/entity/entity-table.entity.js.map +1 -1
- package/dist/module/meta/service/entity-dynamic.service.js +1 -1
- package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
- package/dist/module/meta/service/entity-list.service.js +11 -11
- package/dist/module/meta/service/entity-list.service.js.map +1 -1
- package/dist/module/meta/service/entity-service-impl.service.js +2 -2
- package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
- package/dist/module/meta/service/entity-table-column.service.js +3 -3
- package/dist/module/meta/service/entity-table-column.service.js.map +1 -1
- package/dist/module/meta/service/entity-table.service.js +2 -2
- package/dist/module/meta/service/entity-table.service.js.map +1 -1
- package/dist/module/meta/service/media-data.service.js +3 -3
- package/dist/module/meta/service/media-data.service.js.map +1 -1
- package/dist/module/meta/service/update-form-json.service.d.ts +3 -3
- package/dist/module/meta/service/update-form-json.service.js +1 -1
- package/dist/module/meta/service/update-form-json.service.js.map +1 -1
- package/dist/module/module/controller/menu.controller.js.map +1 -1
- package/dist/module/module/controller/module-access.controller.js +1 -1
- package/dist/module/module/controller/module-access.controller.js.map +1 -1
- package/dist/module/module/entity/module-access.entity.js.map +1 -1
- package/dist/module/module/entity/module.entity.js.map +1 -1
- package/dist/module/module/service/module-access.service.d.ts +1 -1
- package/dist/module/module/service/module-access.service.js +1 -1
- package/dist/module/module/service/module-access.service.js.map +1 -1
- package/dist/module/notification/controller/otp.controller.js +3 -3
- package/dist/module/notification/controller/otp.controller.js.map +1 -1
- package/dist/module/notification/service/email.service.js +2 -2
- package/dist/module/notification/service/email.service.js.map +1 -1
- package/dist/module/notification/service/otp.service.js +1 -1
- package/dist/module/notification/service/otp.service.js.map +1 -1
- package/dist/module/user/controller/login.controller.js +4 -2
- package/dist/module/user/controller/login.controller.js.map +1 -1
- package/dist/module/user/service/login.service.js +3 -3
- package/dist/module/user/service/login.service.js.map +1 -1
- package/dist/module/user/service/role.service.js +1 -1
- package/dist/module/user/service/role.service.js.map +1 -1
- package/dist/module/user/service/user.service.js +5 -5
- package/dist/module/user/service/user.service.js.map +1 -1
- package/dist/module/workflow/controller/workflow-meta.controller.js +1 -1
- package/dist/module/workflow/controller/workflow-meta.controller.js.map +1 -1
- package/dist/module/workflow/service/action.service.js +3 -3
- package/dist/module/workflow/service/action.service.js.map +1 -1
- package/dist/module/workflow/service/stage-group.service.js +1 -1
- package/dist/module/workflow/service/stage-group.service.js.map +1 -1
- package/dist/module/workflow/service/workflow-meta.service.js +5 -5
- package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
- package/dist/resources/properties.module.js +2 -2
- package/dist/resources/properties.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/service/base64util.service.js.map +1 -1
- package/dist/utils/service/clockIDGenUtil.service.js.map +1 -1
- package/dist/utils/service/dateUtil.service.js +1 -1
- package/dist/utils/service/dateUtil.service.js.map +1 -1
- package/dist/utils/service/encryptUtil.service.js +4 -4
- package/dist/utils/service/encryptUtil.service.js.map +1 -1
- package/dist/utils/service/excel-helper.service.js +4 -1
- package/dist/utils/service/excel-helper.service.js.map +1 -1
- package/dist/utils/service/json-util.service.js.map +1 -1
- package/dist/utils/service/loggingUtil.service.js +3 -3
- package/dist/utils/service/loggingUtil.service.js.map +1 -1
- package/package.json +1 -1
- package/src/decorators/roles.decorator.ts +1 -1
- package/src/module/auth/strategies/google.strategy.ts +6 -1
- package/src/module/auth/strategies/jwt.strategy.ts +1 -1
- package/src/module/communication/communication.module.ts +13 -2
- package/src/module/communication/controller/communication.controller.ts +21 -18
- package/src/module/communication/dto/create-config.dto.ts +32 -13
- package/src/module/communication/entity/communication-config.entity.ts +15 -9
- package/src/module/communication/entity/communication-hub.entity.ts +29 -3
- package/src/module/communication/examples/usage.example.ts +18 -17
- package/src/module/communication/factories/communication.factory.ts +36 -18
- package/src/module/communication/factories/email.factory.ts +8 -5
- package/src/module/communication/factories/sms.factory.ts +8 -5
- package/src/module/communication/factories/telephone.factory.ts +9 -8
- package/src/module/communication/factories/whatsapp.factory.ts +9 -8
- package/src/module/communication/service/communication-queue.service.ts +214 -0
- package/src/module/communication/service/communication.service.ts +340 -101
- package/src/module/communication/service/oauth.service.ts +67 -46
- package/src/module/communication/strategies/email/gmail-api.strategy.ts +44 -24
- package/src/module/communication/strategies/gmail-smtp.strategy.ts +15 -11
- package/src/module/communication/strategies/gmail.strategy.ts +15 -7
- package/src/module/communication/strategies/knowlarity.strategy.ts +67 -33
- package/src/module/communication/strategies/outlook-smtp.strategy.ts +15 -11
- package/src/module/communication/strategies/outlook.strategy.ts +12 -5
- package/src/module/communication/strategies/sms.strategy.ts +13 -10
- package/src/module/communication/strategies/whatsapp.strategy.ts +13 -9
- package/src/module/dashboard/dashboard.module.ts +1 -1
- package/src/module/dashboard/repository/dashboard.repository.ts +4 -2
- package/src/module/dashboard/service/dashboard.service.ts +16 -12
- package/src/module/enterprise/repository/organization.repository.ts +3 -1
- package/src/module/enterprise/service/enterprise.service.ts +2 -2
- package/src/module/filter/entity/saved-filter-master.entity.ts +3 -3
- package/src/module/filter/service/filter.service.ts +3 -3
- package/src/module/filter/service/saved-filter.service.ts +1 -1
- package/src/module/layout/controller/layout.controller.ts +1 -1
- package/src/module/layout/repository/header-section.repository.ts +2 -2
- package/src/module/layout/service/header-section.service.ts +2 -3
- package/src/module/layout_preference/repository/layout_preference.repository.ts +2 -2
- package/src/module/layout_preference/service/layout_preference.service.ts +1 -1
- package/src/module/listmaster/controller/list-master.controller.ts +1 -1
- package/src/module/listmaster/repository/list-master.repository.ts +2 -2
- package/src/module/listmaster/service/list-master.service.ts +2 -2
- package/src/module/master/controller/master.controller.ts +2 -2
- package/src/module/master/service/master.service.ts +1 -1
- package/src/module/meta/controller/attribute-master.controller.ts +3 -3
- package/src/module/meta/controller/entity-dynamic.controller.ts +1 -1
- package/src/module/meta/controller/entity.controller.ts +2 -2
- package/src/module/meta/controller/media.controller.ts +1 -1
- package/src/module/meta/controller/meta.controller.ts +1 -1
- package/src/module/meta/dto/entity-tab.dto.ts +4 -4
- package/src/module/meta/dto/entity-table.dto.ts +5 -6
- package/src/module/meta/entity/entity-master.entity.ts +3 -0
- package/src/module/meta/entity/entity-table.entity.ts +1 -2
- package/src/module/meta/service/entity-dynamic.service.ts +1 -1
- package/src/module/meta/service/entity-list.service.ts +18 -14
- package/src/module/meta/service/entity-service-impl.service.ts +2 -2
- package/src/module/meta/service/entity-table-column.service.ts +3 -3
- package/src/module/meta/service/entity-table.service.ts +2 -2
- package/src/module/meta/service/entity.service.ts +1 -1
- package/src/module/meta/service/media-data.service.ts +3 -3
- package/src/module/meta/service/update-form-json.service.ts +17 -26
- package/src/module/module/controller/menu.controller.ts +0 -1
- package/src/module/module/controller/module-access.controller.ts +2 -3
- package/src/module/module/entity/menu.entity.ts +1 -1
- package/src/module/module/entity/module-access.entity.ts +6 -6
- package/src/module/module/entity/module-action.entity.ts +2 -2
- package/src/module/module/entity/module.entity.ts +0 -1
- package/src/module/module/service/module-access.service.ts +7 -8
- package/src/module/notification/controller/otp.controller.ts +10 -4
- package/src/module/notification/repository/otp.repository.ts +1 -1
- package/src/module/notification/service/email.service.ts +2 -2
- package/src/module/notification/service/otp.service.ts +8 -3
- package/src/module/third-party-module/third-party.module.ts +1 -1
- package/src/module/user/controller/login.controller.ts +27 -12
- package/src/module/user/service/login.service.ts +27 -27
- package/src/module/user/service/role.service.ts +1 -1
- package/src/module/user/service/user.service.ts +5 -5
- package/src/module/workflow/controller/workflow-meta.controller.ts +1 -1
- package/src/module/workflow/service/action.service.ts +3 -3
- package/src/module/workflow/service/stage-group.service.ts +1 -1
- package/src/module/workflow/service/workflow-meta.service.ts +5 -5
- package/src/resources/properties.module.ts +10 -10
- package/src/utils/dto/excel-data.dto.ts +2 -2
- package/src/utils/dto/excelsheet-data.dto.ts +3 -3
- package/src/utils/service/base64util.service.ts +16 -17
- package/src/utils/service/clockIDGenUtil.service.ts +15 -13
- package/src/utils/service/dateUtil.service.ts +6 -6
- package/src/utils/service/encryptUtil.service.ts +4 -4
- package/src/utils/service/excel-helper.service.ts +4 -1
- package/src/utils/service/file-util.service.ts +2 -2
- package/src/utils/service/json-util.service.ts +19 -19
- 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<
|
|
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 =>
|
|
234
|
-
|
|
235
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
302
|
-
|
|
334
|
+
const hubs = await this.getActiveHubs(
|
|
335
|
+
levelId,
|
|
336
|
+
levelType,
|
|
337
|
+
communicationType,
|
|
338
|
+
);
|
|
339
|
+
|
|
303
340
|
if (!hubs.length) {
|
|
304
|
-
throw new Error(
|
|
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 = {
|
|
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 = {
|
|
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(
|
|
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(
|
|
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:
|
|
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(
|
|
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(
|
|
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(
|
|
528
|
-
|
|
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(
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
639
|
-
|
|
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 =
|
|
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(
|
|
909
|
+
throw new Error(
|
|
910
|
+
`Failed to complete Gmail tokens callback: ${error.message}`,
|
|
911
|
+
);
|
|
825
912
|
}
|
|
826
913
|
}
|
|
827
914
|
|
|
828
|
-
async testGmailConfig(
|
|
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(
|
|
847
|
-
|
|
935
|
+
const isValid = await this.gmailApiStrategy.validateConnection(
|
|
936
|
+
config.config_json,
|
|
937
|
+
);
|
|
938
|
+
|
|
848
939
|
if (!isValid) {
|
|
849
|
-
return {
|
|
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(
|
|
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:
|
|
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(
|
|
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:
|
|
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(
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
995
|
-
|
|
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 =
|
|
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>(
|
|
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 =
|
|
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(
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
}
|