rez_core 2.3.1 → 2.3.4

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 (151) hide show
  1. package/dist/app.module.js +2 -0
  2. package/dist/app.module.js.map +1 -1
  3. package/dist/module/enterprise/repository/school.repository.js +0 -1
  4. package/dist/module/enterprise/repository/school.repository.js.map +1 -1
  5. package/dist/module/filter/repository/saved-filter.repository.js +0 -1
  6. package/dist/module/filter/repository/saved-filter.repository.js.map +1 -1
  7. package/dist/module/integration/controller/integration.controller.d.ts +8 -1
  8. package/dist/module/integration/controller/integration.controller.js +22 -0
  9. package/dist/module/integration/controller/integration.controller.js.map +1 -1
  10. package/dist/module/integration/dto/create-config.dto.d.ts +7 -0
  11. package/dist/module/integration/dto/create-config.dto.js +29 -1
  12. package/dist/module/integration/dto/create-config.dto.js.map +1 -1
  13. package/dist/module/integration/factories/sms.factory.d.ts +9 -1
  14. package/dist/module/integration/factories/sms.factory.js +36 -4
  15. package/dist/module/integration/factories/sms.factory.js.map +1 -1
  16. package/dist/module/integration/factories/whatsapp.factory.d.ts +5 -1
  17. package/dist/module/integration/factories/whatsapp.factory.js +14 -2
  18. package/dist/module/integration/factories/whatsapp.factory.js.map +1 -1
  19. package/dist/module/integration/integration.module.js +10 -0
  20. package/dist/module/integration/integration.module.js.map +1 -1
  21. package/dist/module/integration/service/integration.service.d.ts +7 -0
  22. package/dist/module/integration/service/integration.service.js +51 -0
  23. package/dist/module/integration/service/integration.service.js.map +1 -1
  24. package/dist/module/integration/strategies/sms/gupshup-sms.strategy.d.ts +9 -0
  25. package/dist/module/integration/strategies/sms/gupshup-sms.strategy.js +104 -0
  26. package/dist/module/integration/strategies/sms/gupshup-sms.strategy.js.map +1 -0
  27. package/dist/module/integration/strategies/sms/msg91-sms.strategy.d.ts +9 -0
  28. package/dist/module/integration/strategies/sms/msg91-sms.strategy.js +113 -0
  29. package/dist/module/integration/strategies/sms/msg91-sms.strategy.js.map +1 -0
  30. package/dist/module/integration/strategies/sms/tubelight-sms.strategy.d.ts +9 -0
  31. package/dist/module/integration/strategies/sms/tubelight-sms.strategy.js +109 -0
  32. package/dist/module/integration/strategies/sms/tubelight-sms.strategy.js.map +1 -0
  33. package/dist/module/integration/strategies/telephone/ozonetel-voice.strategy.d.ts +7 -2
  34. package/dist/module/integration/strategies/telephone/ozonetel-voice.strategy.js +52 -5
  35. package/dist/module/integration/strategies/telephone/ozonetel-voice.strategy.js.map +1 -1
  36. package/dist/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.d.ts +19 -0
  37. package/dist/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.js +257 -0
  38. package/dist/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.js.map +1 -0
  39. package/dist/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.d.ts +22 -0
  40. package/dist/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.js +295 -0
  41. package/dist/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.js.map +1 -0
  42. package/dist/module/layout_preference/service/layout_preference.service.js +0 -2
  43. package/dist/module/layout_preference/service/layout_preference.service.js.map +1 -1
  44. package/dist/module/listmaster/service/list-master.service.js +0 -1
  45. package/dist/module/listmaster/service/list-master.service.js.map +1 -1
  46. package/dist/module/mapper/controller/field-mapper.controller.d.ts +6 -0
  47. package/dist/module/mapper/controller/field-mapper.controller.js +45 -0
  48. package/dist/module/mapper/controller/field-mapper.controller.js.map +1 -0
  49. package/dist/module/mapper/dto/field-mapper.dto.d.ts +11 -0
  50. package/dist/module/mapper/dto/field-mapper.dto.js +8 -0
  51. package/dist/module/mapper/dto/field-mapper.dto.js.map +1 -0
  52. package/dist/module/mapper/entity/field-lovs.entity.d.ts +7 -0
  53. package/dist/module/mapper/entity/field-lovs.entity.js +38 -0
  54. package/dist/module/mapper/entity/field-lovs.entity.js.map +1 -0
  55. package/dist/module/mapper/entity/field-mapper.entity.d.ts +12 -0
  56. package/dist/module/mapper/entity/field-mapper.entity.js +58 -0
  57. package/dist/module/mapper/entity/field-mapper.entity.js.map +1 -0
  58. package/dist/module/mapper/mapper.module.d.ts +2 -0
  59. package/dist/module/mapper/mapper.module.js +38 -0
  60. package/dist/module/mapper/mapper.module.js.map +1 -0
  61. package/dist/module/mapper/repository/field-lovs.repository.d.ts +8 -0
  62. package/dist/module/mapper/repository/field-lovs.repository.js +41 -0
  63. package/dist/module/mapper/repository/field-lovs.repository.js.map +1 -0
  64. package/dist/module/mapper/repository/field-mapper.repository.d.ts +9 -0
  65. package/dist/module/mapper/repository/field-mapper.repository.js +42 -0
  66. package/dist/module/mapper/repository/field-mapper.repository.js.map +1 -0
  67. package/dist/module/mapper/service/field-mapper.service.d.ts +16 -0
  68. package/dist/module/mapper/service/field-mapper.service.js +92 -0
  69. package/dist/module/mapper/service/field-mapper.service.js.map +1 -0
  70. package/dist/module/master/service/master.service.js +0 -2
  71. package/dist/module/master/service/master.service.js.map +1 -1
  72. package/dist/module/meta/repository/entity-table.repository.js +0 -1
  73. package/dist/module/meta/repository/entity-table.repository.js.map +1 -1
  74. package/dist/module/meta/service/entity-dynamic.service.js +0 -1
  75. package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
  76. package/dist/module/meta/service/entity-service-impl.service.js +0 -2
  77. package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
  78. package/dist/module/meta/service/entity-table.service.js +0 -2
  79. package/dist/module/meta/service/entity-table.service.js.map +1 -1
  80. package/dist/module/meta/service/field-group.service.js +0 -1
  81. package/dist/module/meta/service/field-group.service.js.map +1 -1
  82. package/dist/module/module/service/module-access.service.js +0 -6
  83. package/dist/module/module/service/module-access.service.js.map +1 -1
  84. package/dist/module/notification/service/email.service.js +0 -1
  85. package/dist/module/notification/service/email.service.js.map +1 -1
  86. package/dist/module/user/service/login.service.js +0 -1
  87. package/dist/module/user/service/login.service.js.map +1 -1
  88. package/dist/module/workflow/entity/action.entity.d.ts +2 -0
  89. package/dist/module/workflow/entity/action.entity.js +8 -0
  90. package/dist/module/workflow/entity/action.entity.js.map +1 -1
  91. package/dist/module/workflow/repository/stage.repository.js +0 -1
  92. package/dist/module/workflow/repository/stage.repository.js.map +1 -1
  93. package/dist/module/workflow/service/action.service.js +0 -1
  94. package/dist/module/workflow/service/action.service.js.map +1 -1
  95. package/dist/module/workflow/service/comm-template.service.js +0 -1
  96. package/dist/module/workflow/service/comm-template.service.js.map +1 -1
  97. package/dist/module/workflow/service/populate-workflow.service.js +0 -5
  98. package/dist/module/workflow/service/populate-workflow.service.js.map +1 -1
  99. package/dist/module/workflow/service/task.service.js +0 -1
  100. package/dist/module/workflow/service/task.service.js.map +1 -1
  101. package/dist/module/workflow/service/workflow-meta.service.js +0 -2
  102. package/dist/module/workflow/service/workflow-meta.service.js.map +1 -1
  103. package/dist/module/workflow-automation/service/workflow-automation-engine.service.js +0 -1
  104. package/dist/module/workflow-automation/service/workflow-automation-engine.service.js.map +1 -1
  105. package/dist/tsconfig.build.tsbuildinfo +1 -1
  106. package/docs/modules/integration.md +55 -1
  107. package/package.json +1 -1
  108. package/src/app.module.ts +2 -0
  109. package/src/module/enterprise/repository/school.repository.ts +0 -1
  110. package/src/module/filter/repository/saved-filter.repository.ts +0 -1
  111. package/src/module/integration/controller/integration.controller.ts +24 -0
  112. package/src/module/integration/dto/create-config.dto.ts +22 -0
  113. package/src/module/integration/factories/sms.factory.ts +39 -6
  114. package/src/module/integration/factories/whatsapp.factory.ts +10 -0
  115. package/src/module/integration/integration.module.ts +14 -0
  116. package/src/module/integration/service/integration.service.ts +107 -0
  117. package/src/module/integration/strategies/sms/gupshup-sms.strategy.ts +146 -0
  118. package/src/module/integration/strategies/sms/msg91-sms.strategy.ts +164 -0
  119. package/src/module/integration/strategies/sms/tubelight-sms.strategy.ts +163 -0
  120. package/src/module/integration/strategies/telephone/ozonetel-voice.strategy.ts +80 -7
  121. package/src/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.ts +360 -0
  122. package/src/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.ts +419 -0
  123. package/src/module/layout_preference/service/layout_preference.service.ts +0 -2
  124. package/src/module/listmaster/service/list-master.service.ts +1 -10
  125. package/src/module/mapper/controller/field-mapper.controller.ts +19 -0
  126. package/src/module/mapper/dto/field-mapper.dto.ts +14 -0
  127. package/src/module/mapper/entity/field-lovs.entity.ts +21 -0
  128. package/src/module/mapper/entity/field-mapper.entity.ts +36 -0
  129. package/src/module/mapper/mapper.module.ts +26 -0
  130. package/src/module/mapper/repository/field-lovs.repository.ts +22 -0
  131. package/src/module/mapper/repository/field-mapper.repository.ts +27 -0
  132. package/src/module/mapper/service/field-mapper.service.ts +91 -0
  133. package/src/module/master/service/master.service.ts +0 -2
  134. package/src/module/meta/repository/entity-table.repository.ts +0 -1
  135. package/src/module/meta/service/entity-dynamic.service.ts +1 -5
  136. package/src/module/meta/service/entity-service-impl.service.ts +0 -4
  137. package/src/module/meta/service/entity-table.service.ts +0 -2
  138. package/src/module/meta/service/field-group.service.ts +0 -1
  139. package/src/module/module/service/module-access.service.ts +0 -13
  140. package/src/module/notification/service/email.service.ts +0 -1
  141. package/src/module/user/service/login.service.ts +0 -1
  142. package/src/module/workflow/entity/action.entity.ts +6 -0
  143. package/src/module/workflow/repository/stage.repository.ts +1 -2
  144. package/src/module/workflow/service/action.service.ts +0 -1
  145. package/src/module/workflow/service/comm-template.service.ts +0 -1
  146. package/src/module/workflow/service/populate-workflow.service.ts +2 -12
  147. package/src/module/workflow/service/task.service.ts +0 -1
  148. package/src/module/workflow/service/workflow-meta.service.ts +1 -4
  149. package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +0 -1
  150. package/src/resources/dev.properties.yaml +1 -1
  151. package/.vscode/extensions.json +0 -5
@@ -0,0 +1,360 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import axios, { AxiosResponse } from 'axios';
3
+ import {
4
+ IntegrationStrategy,
5
+ IntegrationResult,
6
+ } from '../integration.strategy';
7
+
8
+ interface GupshupConfig {
9
+ apiKey: string;
10
+ appName: string;
11
+ sourceNumber: string;
12
+ baseUrl?: string;
13
+ }
14
+
15
+ interface GupshupMessage {
16
+ channel: string;
17
+ source: string;
18
+ destination: string;
19
+ 'src.name': string;
20
+ message: {
21
+ type: string;
22
+ text?: string;
23
+ url?: string;
24
+ caption?: string;
25
+ filename?: string;
26
+ };
27
+ }
28
+
29
+ interface GupshupApiResponse {
30
+ status: string;
31
+ messageId?: string;
32
+ response?: {
33
+ id: string;
34
+ phone: string;
35
+ details: string;
36
+ };
37
+ error?: {
38
+ code: number;
39
+ message: string;
40
+ };
41
+ }
42
+
43
+ @Injectable()
44
+ export class GupshupWhatsAppStrategy implements IntegrationStrategy {
45
+ private readonly logger = new Logger(GupshupWhatsAppStrategy.name);
46
+ private readonly defaultBaseUrl = 'https://api.gupshup.io/sm/api/v1';
47
+
48
+ async sendMessage(
49
+ to: string,
50
+ message: string,
51
+ config: any,
52
+ ): Promise<IntegrationResult> {
53
+ try {
54
+ if (!this.validateConfig(config)) {
55
+ throw new Error('Invalid Gupshup WhatsApp configuration');
56
+ }
57
+
58
+ const gupshupConfig = config as GupshupConfig;
59
+ const baseUrl = gupshupConfig.baseUrl || this.defaultBaseUrl;
60
+ const url = `${baseUrl}/msg`;
61
+
62
+ const payload = this.prepareMessagePayload(to, message, config);
63
+
64
+ const response: AxiosResponse<GupshupApiResponse> = await axios.post(
65
+ url,
66
+ payload,
67
+ {
68
+ headers: {
69
+ apikey: gupshupConfig.apiKey,
70
+ 'Content-Type': 'application/x-www-form-urlencoded',
71
+ },
72
+ timeout: 30000,
73
+ },
74
+ );
75
+
76
+ if (response.data?.status === 'submitted' && response.data?.messageId) {
77
+ this.logger.log(
78
+ `Gupshup WhatsApp message sent successfully to ${to}, messageId: ${response.data.messageId}`,
79
+ );
80
+
81
+ return {
82
+ success: true,
83
+ messageId: response.data.messageId,
84
+ provider: 'gupshup',
85
+ service: 'API',
86
+ timestamp: new Date(),
87
+ };
88
+ } else if (response.data?.response?.id) {
89
+ this.logger.log(
90
+ `Gupshup WhatsApp message sent successfully to ${to}, messageId: ${response.data.response.id}`,
91
+ );
92
+
93
+ return {
94
+ success: true,
95
+ messageId: response.data.response.id,
96
+ provider: 'gupshup',
97
+ service: 'API',
98
+ timestamp: new Date(),
99
+ };
100
+ } else {
101
+ throw new Error(
102
+ response.data?.error?.message || 'Invalid response from Gupshup API',
103
+ );
104
+ }
105
+ } catch (error) {
106
+ this.logger.error(
107
+ `Failed to send Gupshup WhatsApp message to ${to}`,
108
+ error.response?.data || error.message,
109
+ );
110
+
111
+ return {
112
+ success: false,
113
+ provider: 'gupshup',
114
+ service: 'API',
115
+ error: this.extractErrorMessage(error),
116
+ timestamp: new Date(),
117
+ };
118
+ }
119
+ }
120
+
121
+ private prepareMessagePayload(
122
+ to: string,
123
+ message: string,
124
+ config: any,
125
+ ): URLSearchParams {
126
+ const gupshupConfig = config as GupshupConfig;
127
+ const params = new URLSearchParams();
128
+
129
+ params.append('channel', 'whatsapp');
130
+ params.append('source', gupshupConfig.sourceNumber);
131
+ params.append('destination', this.formatPhoneNumber(to));
132
+ params.append('src.name', gupshupConfig.appName);
133
+
134
+ // Handle different message types based on config
135
+ if (config.messageType) {
136
+ switch (config.messageType) {
137
+ case 'template':
138
+ params.append('message', JSON.stringify({
139
+ type: 'template',
140
+ template: {
141
+ id: config.templateId,
142
+ params: config.templateParams || [],
143
+ },
144
+ }));
145
+ break;
146
+
147
+ case 'image':
148
+ params.append('message', JSON.stringify({
149
+ type: 'image',
150
+ originalUrl: config.mediaUrl,
151
+ previewUrl: config.previewUrl || config.mediaUrl,
152
+ caption: message || config.caption || '',
153
+ }));
154
+ break;
155
+
156
+ case 'document':
157
+ params.append('message', JSON.stringify({
158
+ type: 'file',
159
+ url: config.mediaUrl,
160
+ filename: config.filename || 'document',
161
+ caption: message || config.caption || '',
162
+ }));
163
+ break;
164
+
165
+ case 'audio':
166
+ params.append('message', JSON.stringify({
167
+ type: 'audio',
168
+ url: config.mediaUrl,
169
+ }));
170
+ break;
171
+
172
+ case 'video':
173
+ params.append('message', JSON.stringify({
174
+ type: 'video',
175
+ url: config.mediaUrl,
176
+ caption: message || config.caption || '',
177
+ }));
178
+ break;
179
+
180
+ case 'location':
181
+ params.append('message', JSON.stringify({
182
+ type: 'location',
183
+ longitude: config.longitude,
184
+ latitude: config.latitude,
185
+ name: config.locationName || '',
186
+ address: config.locationAddress || '',
187
+ }));
188
+ break;
189
+
190
+ case 'list':
191
+ params.append('message', JSON.stringify({
192
+ type: 'list',
193
+ title: config.listTitle || 'Select an option',
194
+ body: message,
195
+ globalButtons: config.globalButtons || [],
196
+ items: config.listItems || [],
197
+ }));
198
+ break;
199
+
200
+ case 'quick_reply':
201
+ params.append('message', JSON.stringify({
202
+ type: 'quick_reply',
203
+ content: {
204
+ type: 'text',
205
+ text: message,
206
+ },
207
+ options: config.quickReplyOptions || [],
208
+ }));
209
+ break;
210
+
211
+ default:
212
+ // Fall back to text message
213
+ break;
214
+ }
215
+ }
216
+
217
+ // Default text message if no specific type or fallback
218
+ if (!config.messageType || !['template', 'image', 'document', 'audio', 'video', 'location', 'list', 'quick_reply'].includes(config.messageType)) {
219
+ params.append('message', JSON.stringify({
220
+ type: 'text',
221
+ text: message,
222
+ }));
223
+ }
224
+
225
+ return params;
226
+ }
227
+
228
+ private formatPhoneNumber(phoneNumber: string): string {
229
+ // Remove any non-digit characters except +
230
+ let formatted = phoneNumber.replace(/[^\d+]/g, '');
231
+
232
+ // If it doesn't start with +, assume it needs country code
233
+ if (!formatted.startsWith('+')) {
234
+ // Add + if missing
235
+ formatted = `+${formatted}`;
236
+ }
237
+
238
+ return formatted;
239
+ }
240
+
241
+ private extractErrorMessage(error: any): string {
242
+ if (error.response?.data?.error?.message) {
243
+ return error.response.data.error.message;
244
+ }
245
+
246
+ if (error.response?.data?.message) {
247
+ return error.response.data.message;
248
+ }
249
+
250
+ if (error.response?.data?.response?.details) {
251
+ return error.response.data.response.details;
252
+ }
253
+
254
+ if (error.message) {
255
+ return error.message;
256
+ }
257
+
258
+ return 'Unknown Gupshup API error';
259
+ }
260
+
261
+ validateConfig(config: any): boolean {
262
+ if (!config || typeof config !== 'object') {
263
+ return false;
264
+ }
265
+
266
+ // Required fields
267
+ if (!config.apiKey || !config.appName || !config.sourceNumber) {
268
+ return false;
269
+ }
270
+
271
+ // Validate message type specific requirements
272
+ if (config.messageType) {
273
+ switch (config.messageType) {
274
+ case 'template':
275
+ if (!config.templateId) {
276
+ return false;
277
+ }
278
+ break;
279
+
280
+ case 'image':
281
+ case 'document':
282
+ case 'audio':
283
+ case 'video':
284
+ if (!config.mediaUrl) {
285
+ return false;
286
+ }
287
+ break;
288
+
289
+ case 'location':
290
+ if (
291
+ typeof config.latitude !== 'number' ||
292
+ typeof config.longitude !== 'number'
293
+ ) {
294
+ return false;
295
+ }
296
+ break;
297
+
298
+ case 'list':
299
+ if (!config.listItems || !Array.isArray(config.listItems)) {
300
+ return false;
301
+ }
302
+ break;
303
+
304
+ case 'quick_reply':
305
+ if (!config.quickReplyOptions || !Array.isArray(config.quickReplyOptions)) {
306
+ return false;
307
+ }
308
+ break;
309
+ }
310
+ }
311
+
312
+ return true;
313
+ }
314
+
315
+ async getAppInfo(config: GupshupConfig): Promise<any> {
316
+ try {
317
+ const baseUrl = config.baseUrl || this.defaultBaseUrl;
318
+ const url = `${baseUrl}/app`;
319
+
320
+ const response = await axios.get(url, {
321
+ headers: {
322
+ apikey: config.apiKey,
323
+ },
324
+ });
325
+
326
+ return response.data;
327
+ } catch (error) {
328
+ this.logger.error(
329
+ 'Failed to get Gupshup app info',
330
+ error.response?.data || error.message,
331
+ );
332
+ throw new Error(
333
+ `Failed to get app info: ${this.extractErrorMessage(error)}`,
334
+ );
335
+ }
336
+ }
337
+
338
+ async getTemplates(config: GupshupConfig): Promise<any> {
339
+ try {
340
+ const baseUrl = config.baseUrl || this.defaultBaseUrl;
341
+ const url = `${baseUrl}/template/list/${config.appName}`;
342
+
343
+ const response = await axios.get(url, {
344
+ headers: {
345
+ apikey: config.apiKey,
346
+ },
347
+ });
348
+
349
+ return response.data;
350
+ } catch (error) {
351
+ this.logger.error(
352
+ 'Failed to get Gupshup templates',
353
+ error.response?.data || error.message,
354
+ );
355
+ throw new Error(
356
+ `Failed to get templates: ${this.extractErrorMessage(error)}`,
357
+ );
358
+ }
359
+ }
360
+ }