rez_core 2.2.154 → 2.2.156

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 (142) hide show
  1. package/dist/app.module.js +2 -0
  2. package/dist/app.module.js.map +1 -1
  3. package/dist/constant/global.constant.d.ts +1 -1
  4. package/dist/constant/global.constant.js +1 -1
  5. package/dist/constant/global.constant.js.map +1 -1
  6. package/dist/module/auth/strategies/google.strategy.js +1 -1
  7. package/dist/module/auth/strategies/google.strategy.js.map +1 -1
  8. package/dist/module/communication/communication.module.d.ts +2 -0
  9. package/dist/module/communication/communication.module.js +69 -0
  10. package/dist/module/communication/communication.module.js.map +1 -0
  11. package/dist/module/communication/controller/communication.controller.d.ts +54 -0
  12. package/dist/module/communication/controller/communication.controller.js +148 -0
  13. package/dist/module/communication/controller/communication.controller.js.map +1 -0
  14. package/dist/module/communication/dto/create-config.dto.d.ts +91 -0
  15. package/dist/module/communication/dto/create-config.dto.js +243 -0
  16. package/dist/module/communication/dto/create-config.dto.js.map +1 -0
  17. package/dist/module/communication/entity/communication-config.entity.d.ts +44 -0
  18. package/dist/module/communication/entity/communication-config.entity.js +45 -0
  19. package/dist/module/communication/entity/communication-config.entity.js.map +1 -0
  20. package/dist/module/communication/entity/communication-hub.entity.d.ts +20 -0
  21. package/dist/module/communication/entity/communication-hub.entity.js +105 -0
  22. package/dist/module/communication/entity/communication-hub.entity.js.map +1 -0
  23. package/dist/module/communication/examples/usage.example.d.ts +11 -0
  24. package/dist/module/communication/examples/usage.example.js +89 -0
  25. package/dist/module/communication/examples/usage.example.js.map +1 -0
  26. package/dist/module/communication/factories/base.factory.d.ts +9 -0
  27. package/dist/module/communication/factories/base.factory.js +3 -0
  28. package/dist/module/communication/factories/base.factory.js.map +1 -0
  29. package/dist/module/communication/factories/communication.factory.d.ts +33 -0
  30. package/dist/module/communication/factories/communication.factory.js +104 -0
  31. package/dist/module/communication/factories/communication.factory.js.map +1 -0
  32. package/dist/module/communication/factories/email.factory.d.ts +19 -0
  33. package/dist/module/communication/factories/email.factory.js +61 -0
  34. package/dist/module/communication/factories/email.factory.js.map +1 -0
  35. package/dist/module/communication/factories/sms.factory.d.ts +15 -0
  36. package/dist/module/communication/factories/sms.factory.js +49 -0
  37. package/dist/module/communication/factories/sms.factory.js.map +1 -0
  38. package/dist/module/communication/factories/telephone.factory.d.ts +13 -0
  39. package/dist/module/communication/factories/telephone.factory.js +43 -0
  40. package/dist/module/communication/factories/telephone.factory.js.map +1 -0
  41. package/dist/module/communication/factories/whatsapp.factory.d.ts +13 -0
  42. package/dist/module/communication/factories/whatsapp.factory.js +43 -0
  43. package/dist/module/communication/factories/whatsapp.factory.js.map +1 -0
  44. package/dist/module/communication/service/communication.service.d.ts +111 -0
  45. package/dist/module/communication/service/communication.service.js +726 -0
  46. package/dist/module/communication/service/communication.service.js.map +1 -0
  47. package/dist/module/communication/service/oauth.service.d.ts +18 -0
  48. package/dist/module/communication/service/oauth.service.js +185 -0
  49. package/dist/module/communication/service/oauth.service.js.map +1 -0
  50. package/dist/module/communication/strategies/communication.strategy.d.ts +17 -0
  51. package/dist/module/communication/strategies/communication.strategy.js +3 -0
  52. package/dist/module/communication/strategies/communication.strategy.js.map +1 -0
  53. package/dist/module/communication/strategies/email/gmail-api.strategy.d.ts +7 -0
  54. package/dist/module/communication/strategies/email/gmail-api.strategy.js +135 -0
  55. package/dist/module/communication/strategies/email/gmail-api.strategy.js.map +1 -0
  56. package/dist/module/communication/strategies/email/gmail-smtp.strategy.d.ts +5 -0
  57. package/dist/module/communication/strategies/email/gmail-smtp.strategy.js +49 -0
  58. package/dist/module/communication/strategies/email/gmail-smtp.strategy.js.map +1 -0
  59. package/dist/module/communication/strategies/email/outlook-api.strategy.d.ts +5 -0
  60. package/dist/module/communication/strategies/email/outlook-api.strategy.js +44 -0
  61. package/dist/module/communication/strategies/email/outlook-api.strategy.js.map +1 -0
  62. package/dist/module/communication/strategies/gmail-smtp.strategy.d.ts +5 -0
  63. package/dist/module/communication/strategies/gmail-smtp.strategy.js +61 -0
  64. package/dist/module/communication/strategies/gmail-smtp.strategy.js.map +1 -0
  65. package/dist/module/communication/strategies/gmail.strategy.d.ts +5 -0
  66. package/dist/module/communication/strategies/gmail.strategy.js +71 -0
  67. package/dist/module/communication/strategies/gmail.strategy.js.map +1 -0
  68. package/dist/module/communication/strategies/knowlarity.strategy.d.ts +6 -0
  69. package/dist/module/communication/strategies/knowlarity.strategy.js +115 -0
  70. package/dist/module/communication/strategies/knowlarity.strategy.js.map +1 -0
  71. package/dist/module/communication/strategies/outlook-smtp.strategy.d.ts +5 -0
  72. package/dist/module/communication/strategies/outlook-smtp.strategy.js +66 -0
  73. package/dist/module/communication/strategies/outlook-smtp.strategy.js.map +1 -0
  74. package/dist/module/communication/strategies/outlook.strategy.d.ts +5 -0
  75. package/dist/module/communication/strategies/outlook.strategy.js +64 -0
  76. package/dist/module/communication/strategies/outlook.strategy.js.map +1 -0
  77. package/dist/module/communication/strategies/sms/knowlarity.strategy.d.ts +5 -0
  78. package/dist/module/communication/strategies/sms/knowlarity.strategy.js +44 -0
  79. package/dist/module/communication/strategies/sms/knowlarity.strategy.js.map +1 -0
  80. package/dist/module/communication/strategies/sms/twilio.strategy.d.ts +5 -0
  81. package/dist/module/communication/strategies/sms/twilio.strategy.js +44 -0
  82. package/dist/module/communication/strategies/sms/twilio.strategy.js.map +1 -0
  83. package/dist/module/communication/strategies/sms.strategy.d.ts +5 -0
  84. package/dist/module/communication/strategies/sms.strategy.js +50 -0
  85. package/dist/module/communication/strategies/sms.strategy.js.map +1 -0
  86. package/dist/module/communication/strategies/telephone/knowlarity-voice.strategy.d.ts +5 -0
  87. package/dist/module/communication/strategies/telephone/knowlarity-voice.strategy.js +44 -0
  88. package/dist/module/communication/strategies/telephone/knowlarity-voice.strategy.js.map +1 -0
  89. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.d.ts +5 -0
  90. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js +47 -0
  91. package/dist/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.js.map +1 -0
  92. package/dist/module/communication/strategies/whatsapp.strategy.d.ts +5 -0
  93. package/dist/module/communication/strategies/whatsapp.strategy.js +58 -0
  94. package/dist/module/communication/strategies/whatsapp.strategy.js.map +1 -0
  95. package/dist/module/meta/entity.module.js +2 -1
  96. package/dist/module/meta/entity.module.js.map +1 -1
  97. package/dist/module/user/controller/login.controller.d.ts +4 -2
  98. package/dist/module/user/controller/login.controller.js +26 -4
  99. package/dist/module/user/controller/login.controller.js.map +1 -1
  100. package/dist/module/workflow/service/populate-workflow.service.js +2 -2
  101. package/dist/module/workflow/service/populate-workflow.service.js.map +1 -1
  102. package/dist/module/workflow/service/stage.service.js +1 -1
  103. package/dist/module/workflow/service/stage.service.js.map +1 -1
  104. package/dist/tsconfig.build.tsbuildinfo +1 -1
  105. package/package.json +4 -1
  106. package/src/app.module.ts +2 -0
  107. package/src/constant/global.constant.ts +1 -1
  108. package/src/module/auth/strategies/google.strategy.ts +1 -1
  109. package/src/module/communication/communication.module.ts +77 -0
  110. package/src/module/communication/controller/communication.controller.ts +122 -0
  111. package/src/module/communication/dto/create-config.dto.ts +234 -0
  112. package/src/module/communication/entity/communication-config.entity.ts +80 -0
  113. package/src/module/communication/entity/communication-hub.entity.ts +77 -0
  114. package/src/module/communication/examples/usage.example.ts +169 -0
  115. package/src/module/communication/factories/base.factory.ts +7 -0
  116. package/src/module/communication/factories/communication.factory.ts +103 -0
  117. package/src/module/communication/factories/email.factory.ts +51 -0
  118. package/src/module/communication/factories/sms.factory.ts +41 -0
  119. package/src/module/communication/factories/telephone.factory.ts +34 -0
  120. package/src/module/communication/factories/whatsapp.factory.ts +34 -0
  121. package/src/module/communication/service/communication.service.ts +1118 -0
  122. package/src/module/communication/service/oauth.service.ts +203 -0
  123. package/src/module/communication/strategies/communication.strategy.ts +23 -0
  124. package/src/module/communication/strategies/email/gmail-api.strategy.ts +161 -0
  125. package/src/module/communication/strategies/email/gmail-smtp.strategy.ts +51 -0
  126. package/src/module/communication/strategies/email/outlook-api.strategy.ts +44 -0
  127. package/src/module/communication/strategies/gmail-smtp.strategy.ts +64 -0
  128. package/src/module/communication/strategies/gmail.strategy.ts +68 -0
  129. package/src/module/communication/strategies/knowlarity.strategy.ts +124 -0
  130. package/src/module/communication/strategies/outlook-smtp.strategy.ts +69 -0
  131. package/src/module/communication/strategies/outlook.strategy.ts +57 -0
  132. package/src/module/communication/strategies/sms/knowlarity.strategy.ts +44 -0
  133. package/src/module/communication/strategies/sms/twilio.strategy.ts +44 -0
  134. package/src/module/communication/strategies/sms.strategy.ts +44 -0
  135. package/src/module/communication/strategies/telephone/knowlarity-voice.strategy.ts +44 -0
  136. package/src/module/communication/strategies/whatsapp/whatsapp-cloud.strategy.ts +49 -0
  137. package/src/module/communication/strategies/whatsapp.strategy.ts +53 -0
  138. package/src/module/meta/entity.module.ts +2 -1
  139. package/src/module/user/controller/login.controller.ts +34 -3
  140. package/src/module/workflow/service/populate-workflow.service.ts +3 -3
  141. package/src/module/workflow/service/stage.service.ts +1 -1
  142. package/src/resources/dev.properties.yaml +1 -0
@@ -0,0 +1,203 @@
1
+ import { Injectable, BadRequestException } from '@nestjs/common';
2
+ import { google } from 'googleapis';
3
+ import { Client } from '@microsoft/microsoft-graph-client';
4
+
5
+ @Injectable()
6
+ export class OAuthService {
7
+ private readonly gmailOAuth2Client = new google.auth.OAuth2(
8
+ process.env.GMAIL_CLIENT_ID,
9
+ process.env.GMAIL_CLIENT_SECRET,
10
+ process.env.GMAIL_REDIRECT_URI || 'http://localhost:3000/api/communication/oauth/callback/gmail'
11
+ );
12
+
13
+ private readonly outlookScopes = [
14
+ 'https://graph.microsoft.com/mail.send',
15
+ 'https://graph.microsoft.com/user.read'
16
+ ];
17
+
18
+ private readonly gmailScopes = [
19
+ 'https://www.googleapis.com/auth/gmail.send',
20
+ 'https://www.googleapis.com/auth/gmail.readonly'
21
+ ];
22
+
23
+ generateGmailAuthUrl(state: string): string {
24
+ return this.gmailOAuth2Client.generateAuthUrl({
25
+ access_type: 'offline',
26
+ scope: this.gmailScopes,
27
+ state: state,
28
+ prompt: 'consent'
29
+ });
30
+ }
31
+
32
+ generateOutlookAuthUrl(state: string): string {
33
+ const clientId = process.env.OUTLOOK_CLIENT_ID;
34
+ const redirectUri = encodeURIComponent(process.env.OUTLOOK_REDIRECT_URI || 'http://localhost:3000/api/communication/oauth/callback/outlook');
35
+ const scope = encodeURIComponent(this.outlookScopes.join(' '));
36
+
37
+ return `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?` +
38
+ `client_id=${clientId}&` +
39
+ `response_type=code&` +
40
+ `redirect_uri=${redirectUri}&` +
41
+ `scope=${scope}&` +
42
+ `response_mode=query&` +
43
+ `state=${state}`;
44
+ }
45
+
46
+ async exchangeGmailCode(code: string): Promise<any> {
47
+ try {
48
+ const { tokens } = await this.gmailOAuth2Client.getToken(code);
49
+
50
+ this.gmailOAuth2Client.setCredentials(tokens);
51
+
52
+ // Get user info
53
+ const oauth2 = google.oauth2({
54
+ auth: this.gmailOAuth2Client,
55
+ version: 'v2'
56
+ });
57
+ const userInfo = await oauth2.userinfo.get();
58
+
59
+ return {
60
+ accessToken: tokens.access_token,
61
+ refreshToken: tokens.refresh_token,
62
+ expiresIn: tokens.expiry_date,
63
+ email: userInfo.data.email,
64
+ tokenType: tokens.token_type,
65
+ scope: tokens.scope
66
+ };
67
+ } catch (error) {
68
+ throw new BadRequestException('Failed to exchange Gmail authorization code');
69
+ }
70
+ }
71
+
72
+ async exchangeOutlookCode(code: string): Promise<any> {
73
+ try {
74
+ const clientId = process.env.OUTLOOK_CLIENT_ID;
75
+ const clientSecret = process.env.OUTLOOK_CLIENT_SECRET;
76
+ const redirectUri = process.env.OUTLOOK_REDIRECT_URI || 'http://localhost:3000/api/communication/oauth/callback/outlook';
77
+
78
+ const tokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
79
+
80
+ const response = await fetch(tokenUrl, {
81
+ method: 'POST',
82
+ headers: {
83
+ 'Content-Type': 'application/x-www-form-urlencoded',
84
+ },
85
+ body: new URLSearchParams({
86
+ client_id: clientId!,
87
+ client_secret: clientSecret!,
88
+ code: code,
89
+ redirect_uri: redirectUri,
90
+ grant_type: 'authorization_code',
91
+ scope: this.outlookScopes.join(' ')
92
+ })
93
+ });
94
+
95
+ const tokenData = await response.json();
96
+
97
+ if (!response.ok) {
98
+ throw new Error(tokenData.error_description || 'Token exchange failed');
99
+ }
100
+
101
+ // Get user info using the access token
102
+ const graphClient = Client.init({
103
+ authProvider: {
104
+ getAccessToken: async () => tokenData.access_token,
105
+ } as any,
106
+ });
107
+
108
+ const userInfo = await graphClient.api('/me').get();
109
+
110
+ return {
111
+ accessToken: tokenData.access_token,
112
+ refreshToken: tokenData.refresh_token,
113
+ expiresIn: tokenData.expires_in,
114
+ email: userInfo.mail || userInfo.userPrincipalName,
115
+ tokenType: tokenData.token_type,
116
+ scope: tokenData.scope
117
+ };
118
+ } catch (error) {
119
+ throw new BadRequestException('Failed to exchange Outlook authorization code');
120
+ }
121
+ }
122
+
123
+ async refreshGmailToken(refreshToken: string): Promise<any> {
124
+ try {
125
+ this.gmailOAuth2Client.setCredentials({
126
+ refresh_token: refreshToken
127
+ });
128
+
129
+ const { credentials } = await this.gmailOAuth2Client.refreshAccessToken();
130
+
131
+ return {
132
+ accessToken: credentials.access_token,
133
+ refreshToken: credentials.refresh_token || refreshToken,
134
+ expiresIn: credentials.expiry_date,
135
+ tokenType: credentials.token_type
136
+ };
137
+ } catch (error) {
138
+ throw new BadRequestException('Failed to refresh Gmail token');
139
+ }
140
+ }
141
+
142
+ async refreshOutlookToken(refreshToken: string): Promise<any> {
143
+ try {
144
+ const clientId = process.env.OUTLOOK_CLIENT_ID;
145
+ const clientSecret = process.env.OUTLOOK_CLIENT_SECRET;
146
+
147
+ const tokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
148
+
149
+ const response = await fetch(tokenUrl, {
150
+ method: 'POST',
151
+ headers: {
152
+ 'Content-Type': 'application/x-www-form-urlencoded',
153
+ },
154
+ body: new URLSearchParams({
155
+ client_id: clientId!,
156
+ client_secret: clientSecret!,
157
+ refresh_token: refreshToken,
158
+ grant_type: 'refresh_token',
159
+ scope: this.outlookScopes.join(' ')
160
+ })
161
+ });
162
+
163
+ const tokenData = await response.json();
164
+
165
+ if (!response.ok) {
166
+ throw new Error(tokenData.error_description || 'Token refresh failed');
167
+ }
168
+
169
+ return {
170
+ accessToken: tokenData.access_token,
171
+ refreshToken: tokenData.refresh_token || refreshToken,
172
+ expiresIn: tokenData.expires_in,
173
+ tokenType: tokenData.token_type
174
+ };
175
+ } catch (error) {
176
+ throw new BadRequestException('Failed to refresh Outlook token');
177
+ }
178
+ }
179
+
180
+ generateState(prefix: string, additionalData?: any): string {
181
+ const timestamp = Date.now();
182
+ const random = Math.random().toString(36).substring(7);
183
+ const data = additionalData ? JSON.stringify(additionalData) : '';
184
+ return `${prefix}:${timestamp}:${random}:${Buffer.from(data).toString('base64')}`;
185
+ }
186
+
187
+ parseState(state: string): { prefix: string; timestamp: number; random: string; data: any } {
188
+ const parts = state.split(':');
189
+ if (parts.length !== 4) {
190
+ throw new BadRequestException('Invalid state parameter');
191
+ }
192
+
193
+ const [prefix, timestamp, random, encodedData] = parts;
194
+ const data = encodedData ? JSON.parse(Buffer.from(encodedData, 'base64').toString()) : null;
195
+
196
+ return {
197
+ prefix,
198
+ timestamp: parseInt(timestamp),
199
+ random,
200
+ data
201
+ };
202
+ }
203
+ }
@@ -0,0 +1,23 @@
1
+ export interface CommunicationStrategy {
2
+ sendMessage(
3
+ to: string,
4
+ message: string,
5
+ config: any,
6
+ ): Promise<CommunicationResult>;
7
+ validateConfig(config: any): boolean;
8
+ }
9
+
10
+ export interface CommunicationResult {
11
+ success: boolean;
12
+ messageId?: string;
13
+ provider: string;
14
+ service: string;
15
+ error?: string;
16
+ timestamp: Date;
17
+ }
18
+
19
+ export interface MessageTemplate {
20
+ subject?: string;
21
+ body: string;
22
+ attachments?: any[];
23
+ }
@@ -0,0 +1,161 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import axios from 'axios';
3
+ import {
4
+ CommunicationStrategy,
5
+ CommunicationResult,
6
+ } from '../communication.strategy';
7
+
8
+ @Injectable()
9
+ export class GmailApiStrategy implements CommunicationStrategy {
10
+ async sendMessage(
11
+ to: string | string[],
12
+ message: string,
13
+ config: any,
14
+ ): Promise<CommunicationResult> {
15
+ try {
16
+ if (!this.validateConfig(config)) {
17
+ throw new Error('Invalid Gmail API configuration');
18
+ }
19
+
20
+ const { accessToken, subject, html, cc, bcc } = config;
21
+
22
+ console.log('---- Using HTTP Gmail API ----');
23
+ console.log('accessToken:', accessToken ? 'Present' : 'Missing');
24
+
25
+ const toRecipients = Array.isArray(to) ? to.join(', ') : to;
26
+ const ccRecipients = cc ? (Array.isArray(cc) ? cc.join(', ') : cc) : undefined;
27
+ const bccRecipients = bcc ? (Array.isArray(bcc) ? bcc.join(', ') : bcc) : undefined;
28
+
29
+ const emailLines = [
30
+ `To: ${toRecipients}`,
31
+ `Subject: ${subject || 'Notification'}`,
32
+ ];
33
+
34
+ if (ccRecipients) {
35
+ emailLines.push(`Cc: ${ccRecipients}`);
36
+ }
37
+
38
+ if (bccRecipients) {
39
+ emailLines.push(`Bcc: ${bccRecipients}`);
40
+ }
41
+
42
+ emailLines.push('Content-Type: text/html; charset=utf-8');
43
+ emailLines.push('');
44
+
45
+ if (html) {
46
+ emailLines.push(html);
47
+ } else {
48
+ emailLines.push(message);
49
+ }
50
+
51
+ const emailContent = emailLines.join('\n');
52
+ const encodedMessage = Buffer.from(emailContent)
53
+ .toString('base64')
54
+ .replace(/\+/g, '-')
55
+ .replace(/\//g, '_')
56
+ .replace(/=+$/, '');
57
+
58
+ // Direct HTTP call to Gmail API
59
+ const response = await axios.post(
60
+ 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send',
61
+ {
62
+ raw: encodedMessage,
63
+ },
64
+ {
65
+ headers: {
66
+ 'Authorization': `Bearer ${accessToken}`,
67
+ 'Content-Type': 'application/json',
68
+ },
69
+ timeout: 30000, // 30 second timeout
70
+ }
71
+ );
72
+
73
+ console.log('---- Gmail HTTP API Success ----');
74
+ console.log('Response status:', response.status);
75
+ console.log('Message ID:', response.data?.id);
76
+
77
+ return {
78
+ success: true,
79
+ messageId: response.data?.id || undefined,
80
+ provider: 'gmail',
81
+ service: 'API',
82
+ timestamp: new Date(),
83
+ };
84
+ } catch (error) {
85
+ console.error('---- Gmail HTTP API Error ----');
86
+ console.error('Error message:', error.message);
87
+ console.error('Status:', error.response?.status);
88
+ console.error('Response data:', error.response?.data);
89
+
90
+ return {
91
+ success: false,
92
+ provider: 'gmail',
93
+ service: 'API',
94
+ error: error.response?.data?.error?.message || error.message || 'Gmail API error',
95
+ timestamp: new Date(),
96
+ };
97
+ }
98
+ }
99
+
100
+ validateConfig(config: any): boolean {
101
+ if (!config) return false;
102
+
103
+ // For HTTP API, we just need accessToken
104
+ return (
105
+ config.accessToken &&
106
+ typeof config.accessToken === 'string'
107
+ );
108
+ }
109
+
110
+ async refreshAccessToken(config: any): Promise<string> {
111
+ try {
112
+ const { clientId, clientSecret, refreshToken } = config;
113
+
114
+ if (!clientId || !clientSecret || !refreshToken) {
115
+ throw new Error('Missing OAuth credentials for token refresh');
116
+ }
117
+
118
+ const response = await axios.post('https://oauth2.googleapis.com/token', {
119
+ client_id: clientId,
120
+ client_secret: clientSecret,
121
+ refresh_token: refreshToken,
122
+ grant_type: 'refresh_token',
123
+ }, {
124
+ headers: {
125
+ 'Content-Type': 'application/json',
126
+ },
127
+ });
128
+
129
+ return response.data.access_token || '';
130
+ } catch (error) {
131
+ console.error('Failed to refresh access token:', error.response?.data || error.message);
132
+ throw new Error(`Failed to refresh Gmail access token: ${error.response?.data?.error_description || error.message}`);
133
+ }
134
+ }
135
+
136
+ async validateConnection(config: any): Promise<boolean> {
137
+ try {
138
+ if (!this.validateConfig(config)) {
139
+ return false;
140
+ }
141
+
142
+ const { accessToken } = config;
143
+
144
+ // Test the connection by getting user profile
145
+ const response = await axios.get(
146
+ 'https://gmail.googleapis.com/gmail/v1/users/me/profile',
147
+ {
148
+ headers: {
149
+ 'Authorization': `Bearer ${accessToken}`,
150
+ },
151
+ timeout: 10000, // 10 second timeout for validation
152
+ }
153
+ );
154
+
155
+ return response.status === 200 && response.data.emailAddress;
156
+ } catch (error) {
157
+ console.error('Gmail connection validation failed:', error.response?.data || error.message);
158
+ return false;
159
+ }
160
+ }
161
+ }
@@ -0,0 +1,51 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import {
3
+ CommunicationStrategy,
4
+ CommunicationResult,
5
+ } from '../communication.strategy';
6
+
7
+ @Injectable()
8
+ export class GmailSmtpStrategy implements CommunicationStrategy {
9
+ async sendMessage(
10
+ to: string,
11
+ message: string,
12
+ config: any,
13
+ ): Promise<CommunicationResult> {
14
+ try {
15
+ if (!this.validateConfig(config)) {
16
+ throw new Error('Invalid Gmail SMTP configuration');
17
+ }
18
+
19
+ // SMTP implementation would go here using nodemailer
20
+ // This is a placeholder for actual SMTP integration
21
+ console.log('Sending email via Gmail SMTP to:', to);
22
+
23
+ return {
24
+ success: true,
25
+ messageId: `gmail-smtp-${Date.now()}`,
26
+ provider: 'gmail',
27
+ service: 'SMTP',
28
+ timestamp: new Date(),
29
+ };
30
+ } catch (error) {
31
+ return {
32
+ success: false,
33
+ provider: 'gmail',
34
+ service: 'SMTP',
35
+ error: error.message,
36
+ timestamp: new Date(),
37
+ };
38
+ }
39
+ }
40
+
41
+ validateConfig(config: any): boolean {
42
+ return (
43
+ config &&
44
+ config.host &&
45
+ config.port &&
46
+ config.auth &&
47
+ config.auth.user &&
48
+ config.auth.pass
49
+ );
50
+ }
51
+ }
@@ -0,0 +1,44 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import {
3
+ CommunicationStrategy,
4
+ CommunicationResult,
5
+ } from '../communication.strategy';
6
+
7
+ @Injectable()
8
+ export class OutlookApiStrategy implements CommunicationStrategy {
9
+ async sendMessage(
10
+ to: string,
11
+ message: string,
12
+ config: any,
13
+ ): Promise<CommunicationResult> {
14
+ try {
15
+ if (!this.validateConfig(config)) {
16
+ throw new Error('Invalid Outlook API configuration');
17
+ }
18
+
19
+ // Microsoft Graph API implementation would go here
20
+ // This is a placeholder for actual Outlook API integration
21
+ console.log('Sending email via Outlook API to:', to);
22
+
23
+ return {
24
+ success: true,
25
+ messageId: `outlook-${Date.now()}`,
26
+ provider: 'outlook',
27
+ service: 'API',
28
+ timestamp: new Date(),
29
+ };
30
+ } catch (error) {
31
+ return {
32
+ success: false,
33
+ provider: 'outlook',
34
+ service: 'API',
35
+ error: error.message,
36
+ timestamp: new Date(),
37
+ };
38
+ }
39
+ }
40
+
41
+ validateConfig(config: any): boolean {
42
+ return config && config.clientId && config.clientSecret && config.tenantId;
43
+ }
44
+ }
@@ -0,0 +1,64 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import * as nodemailer from 'nodemailer';
3
+ import { CommunicationStrategy, CommunicationResult } from './communication.strategy';
4
+
5
+ @Injectable()
6
+ export class GmailSMTPStrategy implements CommunicationStrategy {
7
+ async sendMessage(to: string, message: string, config: any): Promise<CommunicationResult> {
8
+ try {
9
+ const {
10
+ email,
11
+ password,
12
+ subject = 'Notification',
13
+ html,
14
+ attachments,
15
+ cc,
16
+ bcc
17
+ } = config;
18
+
19
+ const transporter = nodemailer.createTransport({
20
+ service: 'gmail',
21
+ auth: {
22
+ user: email,
23
+ pass: password,
24
+ },
25
+ });
26
+
27
+ const mailOptions = {
28
+ from: email,
29
+ to: Array.isArray(to) ? to.join(',') : to,
30
+ cc: cc ? (Array.isArray(cc) ? cc.join(',') : cc) : undefined,
31
+ bcc: bcc ? (Array.isArray(bcc) ? bcc.join(',') : bcc) : undefined,
32
+ subject,
33
+ text: message,
34
+ html: html || message,
35
+ attachments: attachments || [],
36
+ };
37
+
38
+ const result = await transporter.sendMail(mailOptions);
39
+
40
+ return {
41
+ success: true,
42
+ provider: 'gmail',
43
+ service: 'SMTP',
44
+ messageId: result.messageId,
45
+ timestamp: new Date(),
46
+ };
47
+ } catch (error) {
48
+ return {
49
+ success: false,
50
+ provider: 'gmail',
51
+ service: 'SMTP',
52
+ error: error.message,
53
+ timestamp: new Date(),
54
+ };
55
+ }
56
+ }
57
+
58
+ validateConfig(config: any): boolean {
59
+ return !!(
60
+ config.email &&
61
+ config.password
62
+ );
63
+ }
64
+ }
@@ -0,0 +1,68 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { google } from 'googleapis';
3
+ import { CommunicationStrategy, CommunicationResult } from './communication.strategy';
4
+
5
+ @Injectable()
6
+ export class GmailStrategy implements CommunicationStrategy {
7
+ async sendMessage(to: string, message: string, config: any): Promise<CommunicationResult> {
8
+ try {
9
+ const { clientId, clientSecret, refreshToken, accessToken, email } = config;
10
+
11
+ const oauth2Client = new google.auth.OAuth2(clientId, clientSecret);
12
+ oauth2Client.setCredentials({
13
+ refresh_token: refreshToken,
14
+ access_token: accessToken,
15
+ });
16
+
17
+ const gmail = google.gmail({ version: 'v1', auth: oauth2Client });
18
+
19
+ const subject = config.subject || 'Notification';
20
+ const emailContent = [
21
+ `From: ${email}`,
22
+ `To: ${to}`,
23
+ `Subject: ${subject}`,
24
+ 'Content-Type: text/html; charset=utf-8',
25
+ '',
26
+ config.html || message,
27
+ ].join('\n');
28
+
29
+ const encodedMessage = Buffer.from(emailContent)
30
+ .toString('base64')
31
+ .replace(/\+/g, '-')
32
+ .replace(/\//g, '_')
33
+ .replace(/=+$/, '');
34
+
35
+ const result = await gmail.users.messages.send({
36
+ userId: 'me',
37
+ requestBody: {
38
+ raw: encodedMessage,
39
+ },
40
+ });
41
+
42
+ return {
43
+ success: true,
44
+ provider: 'gmail',
45
+ service: 'API',
46
+ messageId: result.data.id || undefined,
47
+ timestamp: new Date(),
48
+ };
49
+ } catch (error) {
50
+ return {
51
+ success: false,
52
+ provider: 'gmail',
53
+ service: 'API',
54
+ error: error.message,
55
+ timestamp: new Date(),
56
+ };
57
+ }
58
+ }
59
+
60
+ validateConfig(config: any): boolean {
61
+ return !!(
62
+ config.clientId &&
63
+ config.clientSecret &&
64
+ config.refreshToken &&
65
+ config.email
66
+ );
67
+ }
68
+ }