rez_core 2.2.190 → 2.2.191

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 (36) hide show
  1. package/dist/module/communication/communication.module.js +4 -1
  2. package/dist/module/communication/communication.module.js.map +1 -1
  3. package/dist/module/communication/controller/calender-event.controller.d.ts +31 -0
  4. package/dist/module/communication/controller/calender-event.controller.js +51 -0
  5. package/dist/module/communication/controller/calender-event.controller.js.map +1 -0
  6. package/dist/module/communication/controller/communication.controller.d.ts +8 -1
  7. package/dist/module/communication/controller/communication.controller.js +27 -0
  8. package/dist/module/communication/controller/communication.controller.js.map +1 -1
  9. package/dist/module/communication/dto/create-config.dto.d.ts +40 -0
  10. package/dist/module/communication/dto/create-config.dto.js +24 -1
  11. package/dist/module/communication/dto/create-config.dto.js.map +1 -1
  12. package/dist/module/communication/factories/whatsapp.factory.d.ts +3 -1
  13. package/dist/module/communication/factories/whatsapp.factory.js +13 -3
  14. package/dist/module/communication/factories/whatsapp.factory.js.map +1 -1
  15. package/dist/module/communication/service/calendar-event.service.d.ts +32 -0
  16. package/dist/module/communication/service/calendar-event.service.js +115 -0
  17. package/dist/module/communication/service/calendar-event.service.js.map +1 -0
  18. package/dist/module/communication/service/communication.service.d.ts +8 -0
  19. package/dist/module/communication/service/communication.service.js +56 -1
  20. package/dist/module/communication/service/communication.service.js.map +1 -1
  21. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.d.ts +15 -0
  22. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js +233 -16
  23. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js.map +1 -1
  24. package/dist/module/workflow/service/task.service.js +0 -1
  25. package/dist/module/workflow/service/task.service.js.map +1 -1
  26. package/dist/tsconfig.build.tsbuildinfo +1 -1
  27. package/package.json +1 -1
  28. package/src/module/communication/communication.module.ts +5 -1
  29. package/src/module/communication/controller/calender-event.controller.ts +31 -0
  30. package/src/module/communication/controller/communication.controller.ts +29 -0
  31. package/src/module/communication/dto/create-config.dto.ts +71 -0
  32. package/src/module/communication/factories/whatsapp.factory.ts +13 -2
  33. package/src/module/communication/service/calendar-event.service.ts +123 -0
  34. package/src/module/communication/service/communication.service.ts +91 -2
  35. package/src/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.ts +373 -19
  36. package/src/module/workflow/service/task.service.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.2.190",
3
+ "version": "2.2.191",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
@@ -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
 
@@ -221,4 +222,32 @@ export class CommunicationController {
221
222
  });
222
223
  }
223
224
  }
225
+
226
+ @Post('config/update/:hubId')
227
+ @HttpCode(HttpStatus.OK)
228
+ async updateConfig(
229
+ @Param('hubId', ParseIntPipe) hubId: number,
230
+ @Body() updateDto: UpdateConfigDto,
231
+ ) {
232
+ try {
233
+ const result = await this.communicationService.updateConfiguration(
234
+ hubId,
235
+ updateDto,
236
+ );
237
+
238
+ return {
239
+ success: true,
240
+ message: 'Communication configuration updated successfully',
241
+ data: result,
242
+ };
243
+ } catch (error) {
244
+ throw new BadRequestException({
245
+ success: false,
246
+ error: 'UPDATE_ERROR',
247
+ message:
248
+ error.message || 'Failed to update communication configuration',
249
+ code: 'CONFIGURATION_ERROR',
250
+ });
251
+ }
252
+ }
224
253
  }
@@ -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(private whatsappStrategy: WhatsAppStrategy) {}
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 [{ service: 'API', provider: 'whatsapp' }];
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, status: 1 };
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> {