@solidxai/core 0.1.10-beta.15 → 0.1.10-beta.21

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 (116) hide show
  1. package/dist/commands/test-data.command.d.ts +2 -0
  2. package/dist/commands/test-data.command.d.ts.map +1 -1
  3. package/dist/commands/test-data.command.js +32 -6
  4. package/dist/commands/test-data.command.js.map +1 -1
  5. package/dist/controllers/chatter-message.controller.d.ts +2 -0
  6. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  7. package/dist/controllers/chatter-message.controller.js +17 -0
  8. package/dist/controllers/chatter-message.controller.js.map +1 -1
  9. package/dist/controllers/gupshup-webhook.controller.d.ts +11 -0
  10. package/dist/controllers/gupshup-webhook.controller.d.ts.map +1 -0
  11. package/dist/controllers/gupshup-webhook.controller.js +87 -0
  12. package/dist/controllers/gupshup-webhook.controller.js.map +1 -0
  13. package/dist/controllers/meta-cloud-whatsapp-webhook.controller.d.ts +16 -0
  14. package/dist/controllers/meta-cloud-whatsapp-webhook.controller.d.ts.map +1 -0
  15. package/dist/controllers/meta-cloud-whatsapp-webhook.controller.js +133 -0
  16. package/dist/controllers/meta-cloud-whatsapp-webhook.controller.js.map +1 -0
  17. package/dist/dtos/update-chatter-note-message.dto.d.ts +5 -0
  18. package/dist/dtos/update-chatter-note-message.dto.d.ts.map +1 -0
  19. package/dist/dtos/update-chatter-note-message.dto.js +34 -0
  20. package/dist/dtos/update-chatter-note-message.dto.js.map +1 -0
  21. package/dist/factories/whatsapp.factory.d.ts.map +1 -1
  22. package/dist/factories/whatsapp.factory.js +13 -11
  23. package/dist/factories/whatsapp.factory.js.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/interfaces.d.ts +1 -0
  29. package/dist/interfaces.d.ts.map +1 -1
  30. package/dist/interfaces.js.map +1 -1
  31. package/dist/listeners/user-registration.listener.d.ts +5 -2
  32. package/dist/listeners/user-registration.listener.d.ts.map +1 -1
  33. package/dist/listeners/user-registration.listener.js +37 -4
  34. package/dist/listeners/user-registration.listener.js.map +1 -1
  35. package/dist/seeders/module-test-data.service.d.ts +2 -0
  36. package/dist/seeders/module-test-data.service.d.ts.map +1 -1
  37. package/dist/seeders/module-test-data.service.js +61 -0
  38. package/dist/seeders/module-test-data.service.js.map +1 -1
  39. package/dist/seeders/seed-data/solid-core-metadata.json +1 -0
  40. package/dist/services/authentication.service.d.ts +6 -1
  41. package/dist/services/authentication.service.d.ts.map +1 -1
  42. package/dist/services/authentication.service.js +144 -14
  43. package/dist/services/authentication.service.js.map +1 -1
  44. package/dist/services/chatter-message.service.d.ts +7 -1
  45. package/dist/services/chatter-message.service.d.ts.map +1 -1
  46. package/dist/services/chatter-message.service.js +94 -2
  47. package/dist/services/chatter-message.service.js.map +1 -1
  48. package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts +1 -0
  49. package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
  50. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +11 -0
  51. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
  52. package/dist/services/mediaStorageProviders/file-storage-provider.d.ts +1 -0
  53. package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
  54. package/dist/services/mediaStorageProviders/file-storage-provider.js +6 -0
  55. package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
  56. package/dist/services/settings/default-settings-provider.service.d.ts +174 -0
  57. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  58. package/dist/services/settings/default-settings-provider.service.js +98 -0
  59. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  60. package/dist/services/user.service.js +1 -1
  61. package/dist/services/user.service.js.map +1 -1
  62. package/dist/services/whatsapp/GupshupOtpWhatsappService.d.ts +11 -0
  63. package/dist/services/whatsapp/GupshupOtpWhatsappService.d.ts.map +1 -0
  64. package/dist/services/whatsapp/GupshupOtpWhatsappService.js +127 -0
  65. package/dist/services/whatsapp/GupshupOtpWhatsappService.js.map +1 -0
  66. package/dist/services/whatsapp/MetaCloudWhatsappService.d.ts +17 -0
  67. package/dist/services/whatsapp/MetaCloudWhatsappService.d.ts.map +1 -0
  68. package/dist/services/whatsapp/MetaCloudWhatsappService.js +209 -0
  69. package/dist/services/whatsapp/MetaCloudWhatsappService.js.map +1 -0
  70. package/dist/solid-core.module.d.ts +2 -2
  71. package/dist/solid-core.module.d.ts.map +1 -1
  72. package/dist/solid-core.module.js +14 -6
  73. package/dist/solid-core.module.js.map +1 -1
  74. package/dist-tests/api/authenticate.spec.js +119 -0
  75. package/dist-tests/api/authenticate.spec.js.map +1 -0
  76. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
  77. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
  78. package/dist-tests/api/ping.spec.js +21 -0
  79. package/dist-tests/api/ping.spec.js.map +1 -0
  80. package/dist-tests/helpers/auth.js +41 -0
  81. package/dist-tests/helpers/auth.js.map +1 -0
  82. package/dist-tests/helpers/env.js +11 -0
  83. package/dist-tests/helpers/env.js.map +1 -0
  84. package/docs/grouping-enhancements.md +89 -0
  85. package/docs/java-spring/README.md +3 -0
  86. package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
  87. package/docs/seed-changes.md +65 -0
  88. package/docs/test-data-workflow.md +200 -0
  89. package/docs/type-declaration-import-issue.md +24 -0
  90. package/package.json +1 -1
  91. package/src/commands/test-data.command.ts +29 -6
  92. package/src/controllers/chatter-message.controller.ts +12 -0
  93. package/src/controllers/gupshup-webhook.controller.ts +91 -0
  94. package/src/controllers/meta-cloud-whatsapp-webhook.controller.ts +155 -0
  95. package/src/dtos/update-chatter-note-message.dto.ts +14 -0
  96. package/src/factories/whatsapp.factory.ts +33 -32
  97. package/src/helpers/field-crud-managers/field-quality-check-fixes.md +178 -0
  98. package/src/index.ts +2 -0
  99. package/src/interfaces.ts +1 -1
  100. package/src/listeners/user-registration.listener.ts +49 -6
  101. package/src/seeders/module-test-data.service.ts +79 -2
  102. package/src/seeders/seed-data/solid-core-metadata.json +1 -0
  103. package/src/services/authentication.service.ts +281 -46
  104. package/src/services/chatter-message.service.ts +112 -2
  105. package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +12 -0
  106. package/src/services/mediaStorageProviders/file-storage-provider.ts +8 -1
  107. package/src/services/settings/default-settings-provider.service.ts +98 -0
  108. package/src/services/user.service.ts +1 -1
  109. package/src/services/whatsapp/GupshupOtpWhatsappService.ts +174 -0
  110. package/src/services/whatsapp/MetaCloudWhatsappService.ts +253 -0
  111. package/src/solid-core.module.ts +205 -196
  112. package/src/testing/README.md +15 -0
  113. package/.claude/settings.local.json +0 -15
  114. package/CLAUDE.md +0 -18
  115. package/CURRENT_PROMPT +0 -6
  116. package/src/services/1.js +0 -6
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var GupshupOtpWhatsappService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.GupshupOtpWhatsappService = void 0;
14
+ const axios_1 = require("@nestjs/axios");
15
+ const common_1 = require("@nestjs/common");
16
+ const whatsapp_provider_decorator_1 = require("../../decorators/whatsapp-provider.decorator");
17
+ let GupshupOtpWhatsappService = GupshupOtpWhatsappService_1 = class GupshupOtpWhatsappService {
18
+ constructor(httpService) {
19
+ this.httpService = httpService;
20
+ this.logger = new common_1.Logger(GupshupOtpWhatsappService_1.name);
21
+ }
22
+ async sendWhatsAppMessage(to, templateId, parameters, parentEntity, parentEntityId) {
23
+ if (!to) {
24
+ throw new Error("WhatsApp destination number is required");
25
+ }
26
+ const payload = parameters?.payload;
27
+ if (payload?.message?.type === "text" && payload?.message?.text) {
28
+ await this.sendTextMessage(payload.destination || to, payload.message.text, payload.source, payload["src.name"]);
29
+ return { to, templateId, parameters, parentEntity, parentEntityId };
30
+ }
31
+ if (parameters?.type === "text" && parameters?.text) {
32
+ await this.sendTextMessage(to, parameters.text);
33
+ return { to, templateId, parameters, parentEntity, parentEntityId };
34
+ }
35
+ if (!templateId) {
36
+ throw new Error("WhatsApp templateId is required for template message");
37
+ }
38
+ const bodyParams = Array.isArray(parameters)
39
+ ? parameters
40
+ : Array.isArray(parameters?.body)
41
+ ? parameters.body
42
+ : [];
43
+ await this.sendOtpTemplate(to, templateId, bodyParams.map((x) => String(x)));
44
+ return { to, templateId, parameters, parentEntity, parentEntityId };
45
+ }
46
+ async sendTextMessage(destination, text, sourceOverride, appNameOverride) {
47
+ const apiKey = process.env.COMMON_GUPSHUP_WHATSAPP_API_KEY ||
48
+ process.env.GUPSHUP_API_KEY;
49
+ const msgUrl = process.env.COMMON_GUPSHUP_WHATSAPP_API_URL ||
50
+ process.env.GUPSHUP_API_URL ||
51
+ "https://api.gupshup.io/wa/api/v1/msg";
52
+ const source = sourceOverride ||
53
+ process.env.COMMON_GUPSHUP_WHATSAPP_SOURCE ||
54
+ process.env.GUPSHUP_SOURCE_NUMBER;
55
+ const appName = appNameOverride || process.env.COMMON_GUPSHUP_APP_NAME || "solidx";
56
+ if (!apiKey || !msgUrl || !source) {
57
+ throw new Error("Missing Gupshup WhatsApp configuration for text message");
58
+ }
59
+ const rawDestination = destination.replace(/\D/g, "");
60
+ const params = new URLSearchParams();
61
+ params.append("channel", "whatsapp");
62
+ params.append("source", source);
63
+ params.append("destination", rawDestination);
64
+ params.append("src.name", appName);
65
+ params.append("message", JSON.stringify({ type: "text", text }));
66
+ await this.httpService.axiosRef.post(msgUrl, params.toString(), {
67
+ headers: {
68
+ apikey: apiKey,
69
+ "Content-Type": "application/x-www-form-urlencoded",
70
+ },
71
+ });
72
+ }
73
+ async sendOtpTemplate(destination, templateId, bodyParams) {
74
+ const apiKey = process.env.COMMON_GUPSHUP_WHATSAPP_API_KEY ||
75
+ process.env.GUPSHUP_API_KEY;
76
+ const baseUrl = process.env.COMMON_GUPSHUP_WHATSAPP_API_URL ||
77
+ process.env.GUPSHUP_API_URL ||
78
+ "https://api.gupshup.io/wa/api/v1/msg";
79
+ const templateUrl = process.env.COMMON_GUPSHUP_WHATSAPP_TEMPLATE_API_URL ||
80
+ baseUrl.replace(/\/msg$/, "/template/msg");
81
+ const source = process.env.COMMON_GUPSHUP_WHATSAPP_SOURCE ||
82
+ process.env.GUPSHUP_SOURCE_NUMBER;
83
+ const appName = process.env.COMMON_GUPSHUP_APP_NAME || "solidx";
84
+ if (!apiKey || !templateUrl || !source) {
85
+ throw new Error("Missing Gupshup OTP WhatsApp configuration");
86
+ }
87
+ if (!destination || !String(destination).trim()) {
88
+ throw new Error("WhatsApp destination is empty");
89
+ }
90
+ try {
91
+ const rawDestination = destination.replace(/\D/g, "");
92
+ const params = new URLSearchParams();
93
+ params.append("channel", "whatsapp");
94
+ params.append("source", source);
95
+ params.append("destination", rawDestination);
96
+ params.append("to", rawDestination.startsWith("+")
97
+ ? rawDestination
98
+ : `+${rawDestination}`);
99
+ params.append("src.name", appName);
100
+ params.append("template", JSON.stringify({
101
+ id: templateId,
102
+ params: bodyParams,
103
+ }));
104
+ this.logger.debug(`Gupshup OTP outbound (template): endpoint=${templateUrl}, source=${source}, destination=${rawDestination}, to=${rawDestination.startsWith("+") ? rawDestination : `+${rawDestination}`}, templateId=${templateId}, params=${JSON.stringify(bodyParams)}`);
105
+ const response = await this.httpService.axiosRef.post(templateUrl, params.toString(), {
106
+ headers: {
107
+ apikey: apiKey,
108
+ "Content-Type": "application/x-www-form-urlencoded",
109
+ },
110
+ });
111
+ this.logger.debug(`Gupshup response: ${response.status}, data=${JSON.stringify(response.data)}`);
112
+ this.logger.debug(`Independent OTP WhatsApp sent to ${rawDestination} template=${templateId} via template endpoint`);
113
+ }
114
+ catch (error) {
115
+ const axiosError = error;
116
+ this.logger.error(`Independent OTP WhatsApp failed: destination=${destination}, templateId=${templateId}, status=${axiosError.response?.status ?? "unknown"}, response=${typeof axiosError.response?.data === "object" ? JSON.stringify(axiosError.response?.data) : axiosError.response?.data}, url=${templateUrl}`);
117
+ throw error;
118
+ }
119
+ }
120
+ };
121
+ exports.GupshupOtpWhatsappService = GupshupOtpWhatsappService;
122
+ exports.GupshupOtpWhatsappService = GupshupOtpWhatsappService = GupshupOtpWhatsappService_1 = __decorate([
123
+ (0, common_1.Injectable)(),
124
+ (0, whatsapp_provider_decorator_1.WhatsAppProvider)(),
125
+ __metadata("design:paramtypes", [axios_1.HttpService])
126
+ ], GupshupOtpWhatsappService);
127
+ //# sourceMappingURL=GupshupOtpWhatsappService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GupshupOtpWhatsappService.js","sourceRoot":"","sources":["../../../src/services/whatsapp/GupshupOtpWhatsappService.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpService } from \"@nestjs/axios\";\nimport { Injectable, Logger } from \"@nestjs/common\";\nimport { AxiosError } from \"axios\";\nimport { WhatsAppProvider } from \"src/decorators/whatsapp-provider.decorator\";\nimport { IWhatsAppTransport } from \"src/interfaces\";\n\n@Injectable()\n@WhatsAppProvider()\nexport class GupshupOtpWhatsappService implements IWhatsAppTransport {\n private readonly logger = new Logger(GupshupOtpWhatsappService.name);\n\n constructor(private readonly httpService: HttpService) {}\n\n async sendWhatsAppMessage(\n to: string,\n templateId: string,\n parameters: any,\n parentEntity?: any,\n parentEntityId?: any,\n ): Promise<any> {\n if (!to) {\n throw new Error(\"WhatsApp destination number is required\");\n }\n\n const payload = parameters?.payload;\n if (payload?.message?.type === \"text\" && payload?.message?.text) {\n await this.sendTextMessage(\n payload.destination || to,\n payload.message.text,\n payload.source,\n payload[\"src.name\"],\n );\n return { to, templateId, parameters, parentEntity, parentEntityId };\n }\n\n if (parameters?.type === \"text\" && parameters?.text) {\n await this.sendTextMessage(to, parameters.text);\n return { to, templateId, parameters, parentEntity, parentEntityId };\n }\n\n if (!templateId) {\n throw new Error(\"WhatsApp templateId is required for template message\");\n }\n\n const bodyParams = Array.isArray(parameters)\n ? parameters\n : Array.isArray(parameters?.body)\n ? parameters.body\n : [];\n\n await this.sendOtpTemplate(to, templateId, bodyParams.map((x) => String(x)));\n return { to, templateId, parameters, parentEntity, parentEntityId };\n }\n\n private async sendTextMessage(\n destination: string,\n text: string,\n sourceOverride?: string,\n appNameOverride?: string,\n ): Promise<void> {\n const apiKey =\n process.env.COMMON_GUPSHUP_WHATSAPP_API_KEY ||\n process.env.GUPSHUP_API_KEY;\n const msgUrl =\n process.env.COMMON_GUPSHUP_WHATSAPP_API_URL ||\n process.env.GUPSHUP_API_URL ||\n \"https://api.gupshup.io/wa/api/v1/msg\";\n const source =\n sourceOverride ||\n process.env.COMMON_GUPSHUP_WHATSAPP_SOURCE ||\n process.env.GUPSHUP_SOURCE_NUMBER;\n const appName =\n appNameOverride || process.env.COMMON_GUPSHUP_APP_NAME || \"solidx\";\n\n if (!apiKey || !msgUrl || !source) {\n throw new Error(\"Missing Gupshup WhatsApp configuration for text message\");\n }\n\n const rawDestination = destination.replace(/\\D/g, \"\");\n const params = new URLSearchParams();\n params.append(\"channel\", \"whatsapp\");\n params.append(\"source\", source);\n params.append(\"destination\", rawDestination);\n params.append(\"src.name\", appName);\n params.append(\"message\", JSON.stringify({ type: \"text\", text }));\n\n await this.httpService.axiosRef.post(msgUrl, params.toString(), {\n headers: {\n apikey: apiKey,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n });\n }\n\n async sendOtpTemplate(\n destination: string,\n templateId: string,\n bodyParams: string[],\n ): Promise<void> {\n const apiKey =\n process.env.COMMON_GUPSHUP_WHATSAPP_API_KEY ||\n process.env.GUPSHUP_API_KEY;\n const baseUrl =\n process.env.COMMON_GUPSHUP_WHATSAPP_API_URL ||\n process.env.GUPSHUP_API_URL ||\n \"https://api.gupshup.io/wa/api/v1/msg\";\n const templateUrl =\n process.env.COMMON_GUPSHUP_WHATSAPP_TEMPLATE_API_URL ||\n baseUrl.replace(/\\/msg$/, \"/template/msg\");\n const source =\n process.env.COMMON_GUPSHUP_WHATSAPP_SOURCE ||\n process.env.GUPSHUP_SOURCE_NUMBER;\n const appName = process.env.COMMON_GUPSHUP_APP_NAME || \"solidx\";\n\n if (!apiKey || !templateUrl || !source) {\n throw new Error(\"Missing Gupshup OTP WhatsApp configuration\");\n }\n\n if (!destination || !String(destination).trim()) {\n throw new Error(\"WhatsApp destination is empty\");\n }\n\n try {\n const rawDestination = destination.replace(/\\D/g, \"\");\n const params = new URLSearchParams();\n params.append(\"channel\", \"whatsapp\");\n params.append(\"source\", source);\n params.append(\"destination\", rawDestination);\n params.append(\n \"to\",\n rawDestination.startsWith(\"+\")\n ? rawDestination\n : `+${rawDestination}`,\n );\n params.append(\"src.name\", appName);\n params.append(\n \"template\",\n JSON.stringify({\n id: templateId,\n params: bodyParams,\n }),\n );\n\n this.logger.debug(\n `Gupshup OTP outbound (template): endpoint=${templateUrl}, source=${source}, destination=${rawDestination}, to=${rawDestination.startsWith(\"+\") ? rawDestination : `+${rawDestination}`}, templateId=${templateId}, params=${JSON.stringify(bodyParams)}`,\n );\n\n const response = await this.httpService.axiosRef.post(\n templateUrl,\n params.toString(),\n {\n headers: {\n apikey: apiKey,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n },\n );\n\n this.logger.debug(\n `Gupshup response: ${response.status}, data=${JSON.stringify(response.data)}`,\n );\n\n this.logger.debug(\n `Independent OTP WhatsApp sent to ${rawDestination} template=${templateId} via template endpoint`,\n );\n } catch (error) {\n const axiosError = error as AxiosError;\n this.logger.error(\n `Independent OTP WhatsApp failed: destination=${destination}, templateId=${templateId}, status=${axiosError.response?.status ?? \"unknown\"}, response=${typeof axiosError.response?.data === \"object\" ? JSON.stringify(axiosError.response?.data) : axiosError.response?.data}, url=${templateUrl}`,\n );\n throw error;\n }\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { HttpService } from "@nestjs/axios";
2
+ import { Logger } from "@nestjs/common";
3
+ import { IWhatsAppTransport } from "../../interfaces";
4
+ import { QueueMessage } from "../../interfaces/mq";
5
+ import { SettingService } from "../../services/setting.service";
6
+ export declare class MetaCloudWhatsappService implements IWhatsAppTransport {
7
+ private readonly httpService;
8
+ private readonly settingService;
9
+ readonly logger: Logger;
10
+ constructor(httpService: HttpService, settingService: SettingService);
11
+ sendWhatsAppMessage(to: string, templateId: string, parameters: any, parentEntity?: any, parentEntityId?: any): Promise<any>;
12
+ sendWhatsAppMessageSynchronously(message: QueueMessage<any>): Promise<void>;
13
+ private createWhatsappRequest;
14
+ private normalizeWrappedPayload;
15
+ private normalizePhone;
16
+ }
17
+ //# sourceMappingURL=MetaCloudWhatsappService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetaCloudWhatsappService.d.ts","sourceRoot":"","sources":["../../../src/services/whatsapp/MetaCloudWhatsappService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAc,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAmB9D,qBAEa,wBAAyB,YAAW,kBAAkB;IAI/D,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAJjC,QAAQ,CAAC,MAAM,SAA6C;gBAGzC,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,cAAc;IAG3C,mBAAmB,CACvB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,GAAG,EACf,YAAY,CAAC,EAAE,GAAG,EAClB,cAAc,CAAC,EAAE,GAAG,GACnB,OAAO,CAAC,GAAG,CAAC;IAeT,gCAAgC,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CjF,OAAO,CAAC,qBAAqB;IAmF7B,OAAO,CAAC,uBAAuB;IA8D/B,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var MetaCloudWhatsappService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.MetaCloudWhatsappService = void 0;
14
+ const axios_1 = require("@nestjs/axios");
15
+ const common_1 = require("@nestjs/common");
16
+ const whatsapp_provider_decorator_1 = require("../../decorators/whatsapp-provider.decorator");
17
+ const setting_service_1 = require("../setting.service");
18
+ let MetaCloudWhatsappService = MetaCloudWhatsappService_1 = class MetaCloudWhatsappService {
19
+ constructor(httpService, settingService) {
20
+ this.httpService = httpService;
21
+ this.settingService = settingService;
22
+ this.logger = new common_1.Logger(MetaCloudWhatsappService_1.name);
23
+ }
24
+ async sendWhatsAppMessage(to, templateId, parameters, parentEntity, parentEntityId) {
25
+ const message = {
26
+ payload: {
27
+ to,
28
+ templateId,
29
+ ...parameters,
30
+ },
31
+ parentEntity,
32
+ parentEntityId,
33
+ };
34
+ await this.sendWhatsAppMessageSynchronously(message);
35
+ return message;
36
+ }
37
+ async sendWhatsAppMessageSynchronously(message) {
38
+ const phoneNumberId = this.settingService.getConfigValue("metaWhatsappPhoneNumberId");
39
+ const apiVersion = this.settingService.getConfigValue("metaWhatsappApiVersion");
40
+ const apiBaseUrl = this.settingService.getConfigValue("metaWhatsappApiUrl");
41
+ const accessToken = this.settingService.getConfigValue("metaWhatsappAccessToken");
42
+ if (!phoneNumberId || !apiVersion || !apiBaseUrl || !accessToken) {
43
+ throw new Error("Missing Meta WhatsApp configuration. Set metaWhatsappApiUrl, metaWhatsappApiVersion, metaWhatsappPhoneNumberId, metaWhatsappAccessToken.");
44
+ }
45
+ const requestBody = this.createWhatsappRequest(message);
46
+ const url = `${String(apiBaseUrl).replace(/\/$/, "")}/${apiVersion}/${phoneNumberId}/messages`;
47
+ try {
48
+ await this.httpService.axiosRef.post(url, requestBody, {
49
+ headers: {
50
+ Authorization: `Bearer ${accessToken}`,
51
+ "Content-Type": "application/json",
52
+ },
53
+ });
54
+ this.logger.debug(`Sent Meta WhatsApp message to ${message.payload?.to} with type ${requestBody.type}`);
55
+ }
56
+ catch (error) {
57
+ const axiosError = error;
58
+ const status = axiosError.response?.status;
59
+ const data = axiosError.response?.data;
60
+ this.logger.error(`Meta WhatsApp send failed: status=${status ?? "unknown"}, url=${url}, response=${typeof data === "object" ? JSON.stringify(data) : data}`);
61
+ throw error;
62
+ }
63
+ }
64
+ createWhatsappRequest(message) {
65
+ const payload = message?.payload ?? {};
66
+ if (payload?.payload) {
67
+ const normalizedFromWrappedPayload = this.normalizeWrappedPayload(payload.payload);
68
+ if (normalizedFromWrappedPayload) {
69
+ return normalizedFromWrappedPayload;
70
+ }
71
+ return payload.payload;
72
+ }
73
+ const to = this.normalizePhone(payload.to);
74
+ const templatePayload = payload;
75
+ const textPayload = payload;
76
+ if (textPayload.type === "text" || textPayload.text) {
77
+ return {
78
+ messaging_product: "whatsapp",
79
+ recipient_type: "individual",
80
+ to,
81
+ type: "text",
82
+ text: {
83
+ body: textPayload.text ?? "",
84
+ preview_url: Boolean(textPayload.previewUrl),
85
+ },
86
+ };
87
+ }
88
+ const templateName = payload.templateId || templatePayload.templateId || templatePayload.templateName;
89
+ if (!templateName) {
90
+ throw new Error("Meta WhatsApp template name is missing. Provide templateId or parameters.templateName.");
91
+ }
92
+ const components = [];
93
+ if (templatePayload.headerText) {
94
+ components.push({
95
+ type: "header",
96
+ parameters: [
97
+ {
98
+ type: "text",
99
+ text: templatePayload.headerText,
100
+ },
101
+ ],
102
+ });
103
+ }
104
+ else if (templatePayload.imageLink) {
105
+ components.push({
106
+ type: "header",
107
+ parameters: [
108
+ {
109
+ type: "image",
110
+ image: { link: templatePayload.imageLink },
111
+ },
112
+ ],
113
+ });
114
+ }
115
+ if (Array.isArray(templatePayload.body) && templatePayload.body.length > 0) {
116
+ components.push({
117
+ type: "body",
118
+ parameters: templatePayload.body.map((entry) => ({
119
+ type: "text",
120
+ text: String(entry),
121
+ })),
122
+ });
123
+ }
124
+ return {
125
+ messaging_product: "whatsapp",
126
+ recipient_type: "individual",
127
+ to,
128
+ type: "template",
129
+ template: {
130
+ name: templateName,
131
+ language: {
132
+ code: templatePayload.languageCode || "en",
133
+ },
134
+ ...(components.length > 0 ? { components } : {}),
135
+ },
136
+ };
137
+ }
138
+ normalizeWrappedPayload(payload) {
139
+ if (!payload || typeof payload !== "object") {
140
+ return null;
141
+ }
142
+ if (payload.messaging_product && payload.to && payload.type) {
143
+ return payload;
144
+ }
145
+ const destination = payload.destination || payload.to;
146
+ const message = payload.message || {};
147
+ if (!destination || !message.type) {
148
+ return null;
149
+ }
150
+ if (message.type === "text" && message.text) {
151
+ return {
152
+ messaging_product: "whatsapp",
153
+ recipient_type: "individual",
154
+ to: this.normalizePhone(destination),
155
+ type: "text",
156
+ text: {
157
+ body: String(message.text),
158
+ preview_url: false,
159
+ },
160
+ };
161
+ }
162
+ if (message.type === "template" && message.template?.id) {
163
+ const params = Array.isArray(message.template?.params)
164
+ ? message.template.params
165
+ : [];
166
+ return {
167
+ messaging_product: "whatsapp",
168
+ recipient_type: "individual",
169
+ to: this.normalizePhone(destination),
170
+ type: "template",
171
+ template: {
172
+ name: String(message.template.id),
173
+ language: {
174
+ code: "en",
175
+ },
176
+ ...(params.length > 0
177
+ ? {
178
+ components: [
179
+ {
180
+ type: "body",
181
+ parameters: params.map((entry) => ({
182
+ type: "text",
183
+ text: String(entry),
184
+ })),
185
+ },
186
+ ],
187
+ }
188
+ : {}),
189
+ },
190
+ };
191
+ }
192
+ return null;
193
+ }
194
+ normalizePhone(phone) {
195
+ const digits = String(phone || "").replace(/\D/g, "");
196
+ if (!digits) {
197
+ throw new Error("Destination phone number is required for WhatsApp message.");
198
+ }
199
+ return digits;
200
+ }
201
+ };
202
+ exports.MetaCloudWhatsappService = MetaCloudWhatsappService;
203
+ exports.MetaCloudWhatsappService = MetaCloudWhatsappService = MetaCloudWhatsappService_1 = __decorate([
204
+ (0, common_1.Injectable)(),
205
+ (0, whatsapp_provider_decorator_1.WhatsAppProvider)(),
206
+ __metadata("design:paramtypes", [axios_1.HttpService,
207
+ setting_service_1.SettingService])
208
+ ], MetaCloudWhatsappService);
209
+ //# sourceMappingURL=MetaCloudWhatsappService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetaCloudWhatsappService.js","sourceRoot":"","sources":["../../../src/services/whatsapp/MetaCloudWhatsappService.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpService } from \"@nestjs/axios\";\nimport { Injectable, Logger } from \"@nestjs/common\";\nimport { AxiosError } from \"axios\";\nimport { WhatsAppProvider } from \"src/decorators/whatsapp-provider.decorator\";\nimport { IWhatsAppTransport } from \"src/interfaces\";\nimport { QueueMessage } from \"src/interfaces/mq\";\nimport { SettingService } from \"src/services/setting.service\";\nimport type { SolidCoreSetting } from \"src/services/settings/default-settings-provider.service\";\n\ntype MetaTemplatePayload = {\n type?: \"template\";\n templateName?: string;\n templateId?: string;\n languageCode?: string;\n body?: string[];\n headerText?: string;\n imageLink?: string;\n};\n\ntype MetaTextPayload = {\n type?: \"text\";\n text?: string;\n previewUrl?: boolean;\n};\n\n@Injectable()\n@WhatsAppProvider()\nexport class MetaCloudWhatsappService implements IWhatsAppTransport {\n readonly logger = new Logger(MetaCloudWhatsappService.name);\n\n constructor(\n private readonly httpService: HttpService,\n private readonly settingService: SettingService,\n ) {}\n\n async sendWhatsAppMessage(\n to: string,\n templateId: string,\n parameters: any,\n parentEntity?: any,\n parentEntityId?: any,\n ): Promise<any> {\n const message: QueueMessage<any> = {\n payload: {\n to,\n templateId,\n ...parameters,\n },\n parentEntity,\n parentEntityId,\n };\n\n await this.sendWhatsAppMessageSynchronously(message);\n return message;\n }\n\n async sendWhatsAppMessageSynchronously(message: QueueMessage<any>): Promise<void> {\n const phoneNumberId = this.settingService.getConfigValue<SolidCoreSetting>(\n \"metaWhatsappPhoneNumberId\",\n );\n const apiVersion = this.settingService.getConfigValue<SolidCoreSetting>(\n \"metaWhatsappApiVersion\",\n );\n const apiBaseUrl = this.settingService.getConfigValue<SolidCoreSetting>(\n \"metaWhatsappApiUrl\",\n );\n const accessToken = this.settingService.getConfigValue<SolidCoreSetting>(\n \"metaWhatsappAccessToken\",\n );\n\n if (!phoneNumberId || !apiVersion || !apiBaseUrl || !accessToken) {\n throw new Error(\n \"Missing Meta WhatsApp configuration. Set metaWhatsappApiUrl, metaWhatsappApiVersion, metaWhatsappPhoneNumberId, metaWhatsappAccessToken.\",\n );\n }\n\n const requestBody = this.createWhatsappRequest(message);\n const url = `${String(apiBaseUrl).replace(/\\/$/, \"\")}/${apiVersion}/${phoneNumberId}/messages`;\n\n try {\n await this.httpService.axiosRef.post(url, requestBody, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n });\n this.logger.debug(\n `Sent Meta WhatsApp message to ${message.payload?.to} with type ${requestBody.type}`,\n );\n } catch (error) {\n const axiosError = error as AxiosError;\n const status = axiosError.response?.status;\n const data = axiosError.response?.data;\n this.logger.error(\n `Meta WhatsApp send failed: status=${status ?? \"unknown\"}, url=${url}, response=${typeof data === \"object\" ? JSON.stringify(data) : data}`,\n );\n throw error;\n }\n }\n\n private createWhatsappRequest(message: QueueMessage<any>): any {\n const payload = message?.payload ?? {};\n\n if (payload?.payload) {\n const normalizedFromWrappedPayload = this.normalizeWrappedPayload(payload.payload);\n if (normalizedFromWrappedPayload) {\n return normalizedFromWrappedPayload;\n }\n return payload.payload;\n }\n\n const to = this.normalizePhone(payload.to);\n const templatePayload: MetaTemplatePayload = payload;\n const textPayload: MetaTextPayload = payload;\n\n if (textPayload.type === \"text\" || textPayload.text) {\n return {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to,\n type: \"text\",\n text: {\n body: textPayload.text ?? \"\",\n preview_url: Boolean(textPayload.previewUrl),\n },\n };\n }\n\n const templateName = payload.templateId || templatePayload.templateId || templatePayload.templateName;\n if (!templateName) {\n throw new Error(\n \"Meta WhatsApp template name is missing. Provide templateId or parameters.templateName.\",\n );\n }\n\n const components: any[] = [];\n if (templatePayload.headerText) {\n components.push({\n type: \"header\",\n parameters: [\n {\n type: \"text\",\n text: templatePayload.headerText,\n },\n ],\n });\n } else if (templatePayload.imageLink) {\n components.push({\n type: \"header\",\n parameters: [\n {\n type: \"image\",\n image: { link: templatePayload.imageLink },\n },\n ],\n });\n }\n\n if (Array.isArray(templatePayload.body) && templatePayload.body.length > 0) {\n components.push({\n type: \"body\",\n parameters: templatePayload.body.map((entry) => ({\n type: \"text\",\n text: String(entry),\n })),\n });\n }\n\n return {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to,\n type: \"template\",\n template: {\n name: templateName,\n language: {\n code: templatePayload.languageCode || \"en\",\n },\n ...(components.length > 0 ? { components } : {}),\n },\n };\n }\n\n private normalizeWrappedPayload(payload: any): any | null {\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n\n if (payload.messaging_product && payload.to && payload.type) {\n return payload;\n }\n\n const destination = payload.destination || payload.to;\n const message = payload.message || {};\n if (!destination || !message.type) {\n return null;\n }\n\n if (message.type === \"text\" && message.text) {\n return {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: this.normalizePhone(destination),\n type: \"text\",\n text: {\n body: String(message.text),\n preview_url: false,\n },\n };\n }\n\n if (message.type === \"template\" && message.template?.id) {\n const params = Array.isArray(message.template?.params)\n ? message.template.params\n : [];\n return {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: this.normalizePhone(destination),\n type: \"template\",\n template: {\n name: String(message.template.id),\n language: {\n code: \"en\",\n },\n ...(params.length > 0\n ? {\n components: [\n {\n type: \"body\",\n parameters: params.map((entry: any) => ({\n type: \"text\",\n text: String(entry),\n })),\n },\n ],\n }\n : {}),\n },\n };\n }\n\n return null;\n }\n\n private normalizePhone(phone: string): string {\n const digits = String(phone || \"\").replace(/\\D/g, \"\");\n if (!digits) {\n throw new Error(\"Destination phone number is required for WhatsApp message.\");\n }\n return digits;\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import 'multer';
2
- import { MiddlewareConsumer, NestModule } from '@nestjs/common';
1
+ import "multer";
2
+ import { MiddlewareConsumer, NestModule } from "@nestjs/common";
3
3
  export declare class SolidCoreModule implements NestModule {
4
4
  configure(consumer: MiddlewareConsumer): void;
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"solid-core.module.d.ts","sourceRoot":"","sources":["../src/solid-core.module.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAC;AAChB,OAAO,EAAU,kBAAkB,EAAU,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA6YhF,qBAifa,eAAgB,YAAW,UAAU;IAChD,SAAS,CAAC,QAAQ,EAAE,kBAAkB;CAQvC"}
1
+ {"version":3,"file":"solid-core.module.d.ts","sourceRoot":"","sources":["../src/solid-core.module.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAC;AAChB,OAAO,EAAU,kBAAkB,EAAU,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAkZhF,qBAqfa,eAAgB,YAAW,UAAU;IAChD,SAAS,CAAC,QAAQ,EAAE,kBAAkB;CAQvC"}
@@ -89,6 +89,10 @@ const facebook_authentication_controller_1 = require("./controllers/facebook-aut
89
89
  const microsoft_authentication_controller_1 = require("./controllers/microsoft-authentication.controller");
90
90
  const facebook_oauth_strategy_1 = require("./passport-strategies/facebook-oauth.strategy");
91
91
  const microsoft_oauth_strategy_1 = require("./passport-strategies/microsoft-oauth.strategy");
92
+ const GupshupOtpWhatsappService_1 = require("./services/whatsapp/GupshupOtpWhatsappService");
93
+ const MetaCloudWhatsappService_1 = require("./services/whatsapp/MetaCloudWhatsappService");
94
+ const gupshup_webhook_controller_1 = require("./controllers/gupshup-webhook.controller");
95
+ const meta_cloud_whatsapp_webhook_controller_1 = require("./controllers/meta-cloud-whatsapp-webhook.controller");
92
96
  const axios_1 = require("@nestjs/axios");
93
97
  const jwt_1 = require("@nestjs/jwt");
94
98
  const seed_command_1 = require("./commands/seed.command");
@@ -408,8 +412,8 @@ const list_of_roles_selectionproviders_service_1 = require("./services/selection
408
412
  let SolidCoreModule = class SolidCoreModule {
409
413
  configure(consumer) {
410
414
  consumer
411
- .apply(express.json({ limit: '10mb' }), express.urlencoded({ limit: '10mb', extended: true }))
412
- .forRoutes('*');
415
+ .apply(express.json({ limit: "10mb" }), express.urlencoded({ limit: "10mb", extended: true }))
416
+ .forRoutes("*");
413
417
  }
414
418
  };
415
419
  exports.SolidCoreModule = SolidCoreModule;
@@ -463,18 +467,18 @@ exports.SolidCoreModule = SolidCoreModule = __decorate([
463
467
  cache_manager_1.CacheModule.registerAsync(cache_options_1.CacheManagerOptions),
464
468
  schedule_1.ScheduleModule.forRoot(),
465
469
  serve_static_1.ServeStaticModule.forRoot({
466
- rootPath: (0, path_1.join)(process.cwd(), 'media-files-storage'),
467
- serveRoot: '/media-files-storage',
470
+ rootPath: (0, path_1.join)(process.cwd(), "media-files-storage"),
471
+ serveRoot: "/media-files-storage",
468
472
  serveStaticOptions: {
469
473
  setHeaders: (res) => {
470
- res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
474
+ res.setHeader("Cross-Origin-Resource-Policy", "cross-origin");
471
475
  },
472
476
  },
473
477
  }),
474
478
  platform_express_1.MulterModule.registerAsync({
475
479
  imports: [config_1.ConfigModule],
476
480
  useFactory: async (configService) => ({
477
- dest: process.env.AB_MEDIA_UPLOAD_DIR ?? 'media-uploads',
481
+ dest: process.env.AB_MEDIA_UPLOAD_DIR ?? "media-uploads",
478
482
  }),
479
483
  inject: [config_1.ConfigService],
480
484
  }),
@@ -514,6 +518,8 @@ exports.SolidCoreModule = SolidCoreModule = __decorate([
514
518
  module_metadata_controller_1.ModuleMetadataController,
515
519
  mq_message_controller_1.MqMessageController,
516
520
  mq_message_queue_controller_1.MqMessageQueueController,
521
+ gupshup_webhook_controller_1.GupshupWebhookController,
522
+ meta_cloud_whatsapp_webhook_controller_1.MetaCloudWhatsappWebhookController,
517
523
  otp_authentication_controller_1.OTPAuthenticationController,
518
524
  permission_metadata_controller_1.PermissionMetadataController,
519
525
  role_metadata_controller_1.RoleMetadataController,
@@ -609,6 +615,8 @@ exports.SolidCoreModule = SolidCoreModule = __decorate([
609
615
  Msg91SMSService_1.Msg91SMSService,
610
616
  Msg91OTPService_1.Msg91OTPService,
611
617
  Msg91WhatsappService_1.Msg91WhatsappService,
618
+ MetaCloudWhatsappService_1.MetaCloudWhatsappService,
619
+ GupshupOtpWhatsappService_1.GupshupOtpWhatsappService,
612
620
  TwilioSMSService_1.TwilioSMSService,
613
621
  sms_template_service_1.SmsTemplateService,
614
622
  email_template_service_1.EmailTemplateService,