rez_core 2.2.190 → 2.2.192
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module/communication/communication.module.js +4 -1
- package/dist/module/communication/communication.module.js.map +1 -1
- package/dist/module/communication/controller/calender-event.controller.d.ts +31 -0
- package/dist/module/communication/controller/calender-event.controller.js +51 -0
- package/dist/module/communication/controller/calender-event.controller.js.map +1 -0
- package/dist/module/communication/controller/communication.controller.d.ts +16 -1
- package/dist/module/communication/controller/communication.controller.js +62 -0
- package/dist/module/communication/controller/communication.controller.js.map +1 -1
- package/dist/module/communication/dto/create-config.dto.d.ts +40 -0
- package/dist/module/communication/dto/create-config.dto.js +24 -1
- package/dist/module/communication/dto/create-config.dto.js.map +1 -1
- package/dist/module/communication/factories/whatsapp.factory.d.ts +3 -1
- package/dist/module/communication/factories/whatsapp.factory.js +13 -3
- package/dist/module/communication/factories/whatsapp.factory.js.map +1 -1
- package/dist/module/communication/service/calendar-event.service.d.ts +32 -0
- package/dist/module/communication/service/calendar-event.service.js +115 -0
- package/dist/module/communication/service/calendar-event.service.js.map +1 -0
- package/dist/module/communication/service/communication.service.d.ts +13 -0
- package/dist/module/communication/service/communication.service.js +90 -1
- package/dist/module/communication/service/communication.service.js.map +1 -1
- package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.d.ts +15 -0
- package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js +233 -16
- package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js.map +1 -1
- package/dist/module/workflow/service/task.service.js +0 -1
- package/dist/module/workflow/service/task.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/communication/communication.module.ts +5 -1
- package/src/module/communication/controller/calender-event.controller.ts +31 -0
- package/src/module/communication/controller/communication.controller.ts +62 -0
- package/src/module/communication/dto/create-config.dto.ts +71 -0
- package/src/module/communication/factories/whatsapp.factory.ts +13 -2
- package/src/module/communication/service/calendar-event.service.ts +123 -0
- package/src/module/communication/service/communication.service.ts +153 -2
- package/src/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.ts +373 -19
- package/src/module/workflow/service/task.service.ts +1 -1
package/package.json
CHANGED
|
@@ -38,10 +38,12 @@ import { SmsFactory } from './factories/sms.factory';
|
|
|
38
38
|
import { WhatsAppFactory } from './factories/whatsapp.factory';
|
|
39
39
|
import { TelephoneFactory } from './factories/telephone.factory';
|
|
40
40
|
import { CommunicationFactory } from './factories/communication.factory';
|
|
41
|
+
import { GoogleController } from './controller/calender-event.controller';
|
|
42
|
+
import { GoogleService } from './service/calendar-event.service';
|
|
41
43
|
|
|
42
44
|
@Module({
|
|
43
45
|
imports: [TypeOrmModule.forFeature([CommunicationConfig, CommunicationHub])],
|
|
44
|
-
controllers: [CommunicationController],
|
|
46
|
+
controllers: [CommunicationController, GoogleController],
|
|
45
47
|
providers: [
|
|
46
48
|
// Main Services
|
|
47
49
|
CommunicationService,
|
|
@@ -75,6 +77,8 @@ import { CommunicationFactory } from './factories/communication.factory';
|
|
|
75
77
|
WhatsAppFactory,
|
|
76
78
|
TelephoneFactory,
|
|
77
79
|
CommunicationFactory,
|
|
80
|
+
|
|
81
|
+
GoogleService,
|
|
78
82
|
],
|
|
79
83
|
exports: [
|
|
80
84
|
CommunicationService,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/google/google.controller.ts
|
|
2
|
+
import { Body, Controller, Param, Patch, Post } from '@nestjs/common';
|
|
3
|
+
import { GoogleService } from '../service/calendar-event.service';
|
|
4
|
+
|
|
5
|
+
@Controller('google/calendar')
|
|
6
|
+
export class GoogleController {
|
|
7
|
+
constructor(private readonly googleService: GoogleService) {}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create calendar event
|
|
11
|
+
*/
|
|
12
|
+
@Post('create')
|
|
13
|
+
async createEvent(
|
|
14
|
+
@Body('googleCred') googleCred: any,
|
|
15
|
+
@Body('payload') payload: any,
|
|
16
|
+
) {
|
|
17
|
+
return this.googleService.createEvent(googleCred, payload);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Update calendar event
|
|
22
|
+
*/
|
|
23
|
+
@Patch('update/:eventId')
|
|
24
|
+
async updateEvent(
|
|
25
|
+
@Param('eventId') eventId: string,
|
|
26
|
+
@Body('googleCred') googleCred: any,
|
|
27
|
+
@Body('payload') payload: any,
|
|
28
|
+
) {
|
|
29
|
+
return this.googleService.updateEvent(googleCred, eventId, payload);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
GmailOAuthInitDto,
|
|
21
21
|
OutlookOAuthInitDto,
|
|
22
22
|
SendGridVerifiedSendersDto,
|
|
23
|
+
UpdateConfigDto,
|
|
23
24
|
UpdateConfigStatusDto,
|
|
24
25
|
} from '../dto/create-config.dto';
|
|
25
26
|
|
|
@@ -150,6 +151,39 @@ export class CommunicationController {
|
|
|
150
151
|
});
|
|
151
152
|
}
|
|
152
153
|
|
|
154
|
+
@Get('config/:id')
|
|
155
|
+
async getCommunicationConfigById(@Param('id', ParseIntPipe) hubId: number) {
|
|
156
|
+
try {
|
|
157
|
+
const config =
|
|
158
|
+
await this.communicationService.getCommunicationConfigById(hubId);
|
|
159
|
+
|
|
160
|
+
if (!config) {
|
|
161
|
+
throw new BadRequestException({
|
|
162
|
+
success: false,
|
|
163
|
+
error: 'NOT_FOUND',
|
|
164
|
+
message: 'Communication configuration not found',
|
|
165
|
+
code: 'CONFIGURATION_NOT_FOUND',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
success: true,
|
|
171
|
+
data: config,
|
|
172
|
+
};
|
|
173
|
+
} catch (error) {
|
|
174
|
+
if (error instanceof BadRequestException) {
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
throw new BadRequestException({
|
|
179
|
+
success: false,
|
|
180
|
+
error: 'FETCH_ERROR',
|
|
181
|
+
message: error.message || 'Failed to fetch communication configuration',
|
|
182
|
+
code: 'INTERNAL_ERROR',
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
153
187
|
@Put('config/:id/status')
|
|
154
188
|
async updateConfigStatus(
|
|
155
189
|
@Param('id', ParseIntPipe) hubId: number,
|
|
@@ -221,4 +255,32 @@ export class CommunicationController {
|
|
|
221
255
|
});
|
|
222
256
|
}
|
|
223
257
|
}
|
|
258
|
+
|
|
259
|
+
@Post('config/update/:hubId')
|
|
260
|
+
@HttpCode(HttpStatus.OK)
|
|
261
|
+
async updateConfig(
|
|
262
|
+
@Param('hubId', ParseIntPipe) hubId: number,
|
|
263
|
+
@Body() updateDto: UpdateConfigDto,
|
|
264
|
+
) {
|
|
265
|
+
try {
|
|
266
|
+
const result = await this.communicationService.updateConfiguration(
|
|
267
|
+
hubId,
|
|
268
|
+
updateDto,
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
success: true,
|
|
273
|
+
message: 'Communication configuration updated successfully',
|
|
274
|
+
data: result,
|
|
275
|
+
};
|
|
276
|
+
} catch (error) {
|
|
277
|
+
throw new BadRequestException({
|
|
278
|
+
success: false,
|
|
279
|
+
error: 'UPDATE_ERROR',
|
|
280
|
+
message:
|
|
281
|
+
error.message || 'Failed to update communication configuration',
|
|
282
|
+
code: 'CONFIGURATION_ERROR',
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
224
286
|
}
|
|
@@ -115,6 +115,77 @@ export class UpdateConfigStatusDto {
|
|
|
115
115
|
status: number;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
export class UpdateConfigDto {
|
|
119
|
+
@IsOptional()
|
|
120
|
+
@IsObject()
|
|
121
|
+
config?: {
|
|
122
|
+
// OAuth Control
|
|
123
|
+
useOAuth?: boolean;
|
|
124
|
+
|
|
125
|
+
// Gmail API Config
|
|
126
|
+
clientId?: string;
|
|
127
|
+
clientSecret?: string;
|
|
128
|
+
refreshToken?: string;
|
|
129
|
+
accessToken?: string;
|
|
130
|
+
|
|
131
|
+
// Outlook API Config
|
|
132
|
+
tenantId?: string;
|
|
133
|
+
|
|
134
|
+
// WhatsApp Config
|
|
135
|
+
phoneNumberId?: string;
|
|
136
|
+
apiVersion?: string;
|
|
137
|
+
|
|
138
|
+
// Twilio Config
|
|
139
|
+
accountSid?: string;
|
|
140
|
+
authToken?: string;
|
|
141
|
+
fromNumber?: string;
|
|
142
|
+
|
|
143
|
+
// AWS SES Config
|
|
144
|
+
accessKeyId?: string;
|
|
145
|
+
secretAccessKey?: string;
|
|
146
|
+
region?: string;
|
|
147
|
+
fromEmail?: string;
|
|
148
|
+
|
|
149
|
+
// SMTP Config (Gmail, Outlook, Generic)
|
|
150
|
+
email?: string;
|
|
151
|
+
password?: string;
|
|
152
|
+
host?: string;
|
|
153
|
+
port?: number;
|
|
154
|
+
secure?: boolean;
|
|
155
|
+
user?: string;
|
|
156
|
+
from?: string;
|
|
157
|
+
tls?: any;
|
|
158
|
+
|
|
159
|
+
// SendGrid SMTP Config
|
|
160
|
+
apiKey?: string;
|
|
161
|
+
templateId?: string;
|
|
162
|
+
dynamicTemplateData?: any;
|
|
163
|
+
|
|
164
|
+
// Knowlarity Config
|
|
165
|
+
callerNumber?: string;
|
|
166
|
+
apiSecret?: string;
|
|
167
|
+
baseUrl?: string;
|
|
168
|
+
callType?: 'voice' | 'sms';
|
|
169
|
+
voiceMessage?: string;
|
|
170
|
+
language?: string;
|
|
171
|
+
|
|
172
|
+
// Common optional fields
|
|
173
|
+
[key: string]: any;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
@IsOptional()
|
|
177
|
+
@IsNumber()
|
|
178
|
+
priority?: number;
|
|
179
|
+
|
|
180
|
+
@IsOptional()
|
|
181
|
+
@IsBoolean()
|
|
182
|
+
is_default?: boolean;
|
|
183
|
+
|
|
184
|
+
@IsOptional()
|
|
185
|
+
@IsNumber()
|
|
186
|
+
status?: number;
|
|
187
|
+
}
|
|
188
|
+
|
|
118
189
|
export class GenericSendMessageDto {
|
|
119
190
|
@IsNotEmpty()
|
|
120
191
|
@IsNumber()
|
|
@@ -2,10 +2,14 @@ import { Injectable } from '@nestjs/common';
|
|
|
2
2
|
import { BaseFactory } from './base.factory';
|
|
3
3
|
import { CommunicationStrategy } from '../strategies/communication.strategy';
|
|
4
4
|
import { WhatsAppStrategy } from '../strategies/whatsapp.strategy';
|
|
5
|
+
import { WhatsAppCloudStrategy } from '../strategies/whatsapp/whatsapp-cloud.strategy';
|
|
5
6
|
|
|
6
7
|
@Injectable()
|
|
7
8
|
export class WhatsAppFactory implements BaseFactory {
|
|
8
|
-
constructor(
|
|
9
|
+
constructor(
|
|
10
|
+
private whatsappStrategy: WhatsAppStrategy,
|
|
11
|
+
private whatsappCloudStrategy: WhatsAppCloudStrategy,
|
|
12
|
+
) {}
|
|
9
13
|
|
|
10
14
|
createProvider(service: string, provider: string): CommunicationStrategy {
|
|
11
15
|
const key = `${service.toLowerCase()}_${provider.toLowerCase()}`;
|
|
@@ -13,6 +17,9 @@ export class WhatsAppFactory implements BaseFactory {
|
|
|
13
17
|
switch (key) {
|
|
14
18
|
case 'api_whatsapp':
|
|
15
19
|
return this.whatsappStrategy;
|
|
20
|
+
case 'api_whatsapp-cloud':
|
|
21
|
+
case 'api_meta':
|
|
22
|
+
return this.whatsappCloudStrategy;
|
|
16
23
|
|
|
17
24
|
default:
|
|
18
25
|
throw new Error(
|
|
@@ -22,7 +29,11 @@ export class WhatsAppFactory implements BaseFactory {
|
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
getSupportedCombinations(): Array<{ service: string; provider: string }> {
|
|
25
|
-
return [
|
|
32
|
+
return [
|
|
33
|
+
{ service: 'API', provider: 'whatsapp' },
|
|
34
|
+
{ service: 'API', provider: 'whatsapp-cloud' },
|
|
35
|
+
{ service: 'API', provider: 'meta' },
|
|
36
|
+
];
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
validateCombination(service: string, provider: string): boolean {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// src/google/google.service.ts
|
|
2
|
+
import { Injectable, Logger } from '@nestjs/common';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import { GmailApiStrategy } from '../strategies/email/gmail-api.strategy';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class GoogleService {
|
|
8
|
+
private readonly logger = new Logger(GoogleService.name);
|
|
9
|
+
|
|
10
|
+
constructor(private readonly gmailApiStrategy: GmailApiStrategy) {}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a Google Calendar event
|
|
14
|
+
*/
|
|
15
|
+
async createEvent(googleCred: any, payload: any) {
|
|
16
|
+
if (!googleCred?.refreshToken) {
|
|
17
|
+
throw new Error('Missing refresh token');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const accessToken =
|
|
22
|
+
await this.gmailApiStrategy.refreshAccessToken(googleCred);
|
|
23
|
+
|
|
24
|
+
const event = {
|
|
25
|
+
summary: payload.title,
|
|
26
|
+
description: payload.description,
|
|
27
|
+
location: payload.location,
|
|
28
|
+
start: {
|
|
29
|
+
dateTime: payload.startTime,
|
|
30
|
+
timeZone: payload.timeZone || 'Asia/Kolkata',
|
|
31
|
+
},
|
|
32
|
+
end: {
|
|
33
|
+
dateTime: payload.endTime,
|
|
34
|
+
timeZone: payload.timeZone || 'Asia/Kolkata',
|
|
35
|
+
},
|
|
36
|
+
attendees: payload.attendees?.map((email) => ({ email })) || [],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const response = await axios.post(
|
|
40
|
+
'https://www.googleapis.com/calendar/v3/calendars/primary/events?sendUpdates=all',
|
|
41
|
+
event,
|
|
42
|
+
{
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${accessToken}`,
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
this.logger.log(`Event created: ${response.data.id}`);
|
|
51
|
+
return {
|
|
52
|
+
success: true,
|
|
53
|
+
eventId: response.data.id,
|
|
54
|
+
htmlLink: response.data.htmlLink,
|
|
55
|
+
accessToken,
|
|
56
|
+
};
|
|
57
|
+
} catch (error: any) {
|
|
58
|
+
this.logger.error('CreateEvent error', error.message);
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: error.response?.data?.error?.message || error.message,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Update a Google Calendar event
|
|
68
|
+
*/
|
|
69
|
+
async updateEvent(googleCred: any, eventId: string, payload: any) {
|
|
70
|
+
if (!googleCred?.refreshToken) {
|
|
71
|
+
throw new Error('Missing refresh token');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const accessToken =
|
|
76
|
+
await this.gmailApiStrategy.refreshAccessToken(googleCred);
|
|
77
|
+
|
|
78
|
+
const event = {
|
|
79
|
+
summary: payload.title,
|
|
80
|
+
description: payload.description,
|
|
81
|
+
location: payload.location,
|
|
82
|
+
start: {
|
|
83
|
+
dateTime: payload.startTime,
|
|
84
|
+
timeZone: payload.timeZone || 'Asia/Kolkata',
|
|
85
|
+
},
|
|
86
|
+
end: {
|
|
87
|
+
dateTime: payload.endTime,
|
|
88
|
+
timeZone: payload.timeZone || 'Asia/Kolkata',
|
|
89
|
+
},
|
|
90
|
+
attendees: payload.attendees?.map((email) => ({ email })) || [],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
if (payload.meetingType === 'online' && payload.meetingLink) {
|
|
94
|
+
event.description = `${event.description || ''}\nJoin here: ${payload.meetingLink}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const response = await axios.patch(
|
|
98
|
+
`https://www.googleapis.com/calendar/v3/calendars/primary/events/${eventId}?sendUpdates=all`,
|
|
99
|
+
event,
|
|
100
|
+
{
|
|
101
|
+
headers: {
|
|
102
|
+
Authorization: `Bearer ${accessToken}`,
|
|
103
|
+
'Content-Type': 'application/json',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
this.logger.log(`Event updated: ${response.data.id}`);
|
|
109
|
+
return {
|
|
110
|
+
success: true,
|
|
111
|
+
eventId: response.data.id,
|
|
112
|
+
htmlLink: response.data.htmlLink,
|
|
113
|
+
accessToken,
|
|
114
|
+
};
|
|
115
|
+
} catch (error: any) {
|
|
116
|
+
this.logger.error('UpdateEvent error', error.message);
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
error: error.response?.data?.error?.message || error.message,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
|
2
2
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
-
import { Repository } from 'typeorm';
|
|
3
|
+
import { Repository, Not } from 'typeorm';
|
|
4
4
|
import { ConfigService } from '@nestjs/config';
|
|
5
5
|
import { google } from 'googleapis';
|
|
6
6
|
import {
|
|
@@ -339,7 +339,7 @@ export class CommunicationService {
|
|
|
339
339
|
): Promise<
|
|
340
340
|
Array<CommunicationHub & { linkedSource?: string; configDetails?: any }>
|
|
341
341
|
> {
|
|
342
|
-
const where: any = { level_id: levelId, level_type: levelType
|
|
342
|
+
const where: any = { level_id: levelId, level_type: levelType };
|
|
343
343
|
|
|
344
344
|
if (filters?.communication_config_type) {
|
|
345
345
|
where.communication_config_type = filters.communication_config_type;
|
|
@@ -669,6 +669,95 @@ export class CommunicationService {
|
|
|
669
669
|
);
|
|
670
670
|
}
|
|
671
671
|
|
|
672
|
+
async updateConfiguration(
|
|
673
|
+
hubId: number,
|
|
674
|
+
updateData: {
|
|
675
|
+
config?: any;
|
|
676
|
+
priority?: number;
|
|
677
|
+
is_default?: boolean;
|
|
678
|
+
status?: number;
|
|
679
|
+
},
|
|
680
|
+
): Promise<CommunicationHub & { config?: any }> {
|
|
681
|
+
// Find the existing hub
|
|
682
|
+
const hub = await this.hubRepository.findOne({
|
|
683
|
+
where: { id: hubId },
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
if (!hub) {
|
|
687
|
+
throw new Error('Communication configuration not found');
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Update configuration JSON if provided
|
|
691
|
+
if (updateData.config) {
|
|
692
|
+
const existingConfig = await this.configRepository.findOne({
|
|
693
|
+
where: { id: hub.config_id },
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
if (!existingConfig) {
|
|
697
|
+
throw new Error('Configuration record not found');
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Merge the new config with existing config
|
|
701
|
+
const updatedConfigJson = {
|
|
702
|
+
...existingConfig.config_json,
|
|
703
|
+
...updateData.config,
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
await this.configRepository.update(hub.config_id, {
|
|
707
|
+
config_json: updatedConfigJson,
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Handle default configuration logic
|
|
712
|
+
if (updateData.is_default === true) {
|
|
713
|
+
// Remove default from other configurations of same type and level
|
|
714
|
+
await this.hubRepository.update(
|
|
715
|
+
{
|
|
716
|
+
level_id: hub.level_id,
|
|
717
|
+
level_type: hub.level_type,
|
|
718
|
+
communication_config_type: hub.communication_config_type,
|
|
719
|
+
id: Not(hubId), // Exclude current hub
|
|
720
|
+
},
|
|
721
|
+
{ is_default: false },
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Update hub metadata
|
|
726
|
+
const hubUpdateData: any = {};
|
|
727
|
+
if (updateData.priority !== undefined) {
|
|
728
|
+
hubUpdateData.priority = updateData.priority;
|
|
729
|
+
}
|
|
730
|
+
if (updateData.is_default !== undefined) {
|
|
731
|
+
hubUpdateData.is_default = updateData.is_default;
|
|
732
|
+
}
|
|
733
|
+
if (updateData.status !== undefined) {
|
|
734
|
+
hubUpdateData.status = updateData.status;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// Apply hub updates if any
|
|
738
|
+
if (Object.keys(hubUpdateData).length > 0) {
|
|
739
|
+
await this.hubRepository.update(hubId, hubUpdateData);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Fetch and return updated hub with config
|
|
743
|
+
const updatedHub = await this.hubRepository.findOne({
|
|
744
|
+
where: { id: hubId },
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
const updatedConfig = await this.configRepository.findOne({
|
|
748
|
+
where: { id: hub.config_id },
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
this.logger.log(
|
|
752
|
+
`Communication configuration updated: Hub ${hubId}, Type ${hub.communication_config_type}`,
|
|
753
|
+
);
|
|
754
|
+
|
|
755
|
+
return {
|
|
756
|
+
...updatedHub!,
|
|
757
|
+
config: updatedConfig?.config_json,
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
672
761
|
async sendGenericMessage(
|
|
673
762
|
messageDto: GenericMessageDto,
|
|
674
763
|
): Promise<CommunicationResult> {
|
|
@@ -1651,4 +1740,66 @@ export class CommunicationService {
|
|
|
1651
1740
|
throw new Error(`Failed to complete Outlook OAuth: ${error.message}`);
|
|
1652
1741
|
}
|
|
1653
1742
|
}
|
|
1743
|
+
|
|
1744
|
+
async getCommunicationConfigById(
|
|
1745
|
+
hubId: number,
|
|
1746
|
+
): Promise<(CommunicationHub & { config: CommunicationConfig; linkedSource?: string; configDetails?: any }) | null> {
|
|
1747
|
+
try {
|
|
1748
|
+
// Find the communication hub by ID
|
|
1749
|
+
const hub = await this.hubRepository.findOne({
|
|
1750
|
+
where: { id: hubId },
|
|
1751
|
+
});
|
|
1752
|
+
|
|
1753
|
+
if (!hub) {
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
// Find the associated config
|
|
1758
|
+
const config = await this.configRepository.findOne({
|
|
1759
|
+
where: { id: hub.config_id },
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1762
|
+
if (!config) {
|
|
1763
|
+
this.logger.warn(
|
|
1764
|
+
`Configuration not found for hub ${hubId} with config_id ${hub.config_id}`,
|
|
1765
|
+
);
|
|
1766
|
+
return {
|
|
1767
|
+
...hub,
|
|
1768
|
+
config: null as any,
|
|
1769
|
+
linkedSource: 'Configuration not found',
|
|
1770
|
+
configDetails: null,
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// Extract linked source and config details
|
|
1775
|
+
const linkedSource = this.extractLinkedSource(
|
|
1776
|
+
hub.communication_config_type,
|
|
1777
|
+
hub.service,
|
|
1778
|
+
hub.provider,
|
|
1779
|
+
config.config_json,
|
|
1780
|
+
);
|
|
1781
|
+
|
|
1782
|
+
const configDetails = this.extractConfigDetails(
|
|
1783
|
+
hub.communication_config_type,
|
|
1784
|
+
hub.service,
|
|
1785
|
+
hub.provider,
|
|
1786
|
+
config.config_json,
|
|
1787
|
+
);
|
|
1788
|
+
|
|
1789
|
+
return {
|
|
1790
|
+
...hub,
|
|
1791
|
+
config,
|
|
1792
|
+
linkedSource,
|
|
1793
|
+
configDetails,
|
|
1794
|
+
};
|
|
1795
|
+
} catch (error) {
|
|
1796
|
+
this.logger.error(
|
|
1797
|
+
`Error fetching communication config by ID ${hubId}:`,
|
|
1798
|
+
error.message,
|
|
1799
|
+
);
|
|
1800
|
+
throw new Error(
|
|
1801
|
+
`Failed to fetch communication configuration: ${error.message}`,
|
|
1802
|
+
);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1654
1805
|
}
|