@gamastudio/sendwave-provider 1.0.3 → 1.0.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 (103) hide show
  1. package/.github/workflows/build.yml +31 -31
  2. package/README.md +261 -25
  3. package/build/application/connection/connection-polling.service.d.ts +16 -0
  4. package/build/application/connection/connection-polling.service.js +49 -0
  5. package/build/application/message-buffer/message-buffer.service.d.ts +11 -0
  6. package/build/application/message-buffer/message-buffer.service.js +79 -0
  7. package/build/application/messaging/message-sender.service.d.ts +40 -0
  8. package/build/application/messaging/message-sender.service.js +101 -0
  9. package/build/application/messaging/strategies/interactive.strategy.d.ts +14 -0
  10. package/build/application/messaging/strategies/interactive.strategy.js +88 -0
  11. package/build/application/messaging/strategies/list.strategy.d.ts +8 -0
  12. package/build/application/messaging/strategies/list.strategy.js +61 -0
  13. package/build/application/messaging/strategies/media.strategy.d.ts +32 -0
  14. package/build/application/messaging/strategies/media.strategy.js +97 -0
  15. package/build/application/messaging/strategies/misc.strategy.d.ts +23 -0
  16. package/build/application/messaging/strategies/misc.strategy.js +95 -0
  17. package/build/application/messaging/strategies/presence.strategy.d.ts +8 -0
  18. package/build/application/messaging/strategies/presence.strategy.js +24 -0
  19. package/build/application/messaging/strategies/send-strategy.interface.d.ts +4 -0
  20. package/build/application/messaging/strategies/send-strategy.interface.js +2 -0
  21. package/build/application/messaging/strategies/text.strategy.d.ts +8 -0
  22. package/build/application/messaging/strategies/text.strategy.js +22 -0
  23. package/build/application/messaging/strategies/voice.strategy.d.ts +8 -0
  24. package/build/application/messaging/strategies/voice.strategy.js +37 -0
  25. package/build/application/queue-flow/queue-flow.service.d.ts +34 -0
  26. package/build/application/queue-flow/queue-flow.service.js +68 -0
  27. package/build/config/constants.d.ts +14 -0
  28. package/build/config/constants.js +17 -0
  29. package/build/config/defaults.d.ts +8 -0
  30. package/build/config/defaults.js +110 -0
  31. package/build/constants/html/error.js +34 -34
  32. package/build/constants/html/home.js +23 -23
  33. package/build/constants/svg/wave-error.js +88 -88
  34. package/build/constants/svg/wave.js +88 -88
  35. package/build/core/interface/provider.interface.d.ts +2 -1
  36. package/build/core/interface/types.d.ts +12 -0
  37. package/build/domain/interfaces/index.d.ts +2 -0
  38. package/build/domain/interfaces/index.js +18 -0
  39. package/build/domain/interfaces/parsed-message.interface.d.ts +16 -0
  40. package/build/domain/interfaces/parsed-message.interface.js +2 -0
  41. package/build/domain/interfaces/provider.interface.d.ts +21 -0
  42. package/build/domain/interfaces/provider.interface.js +2 -0
  43. package/build/domain/types/config.types.d.ts +43 -0
  44. package/build/domain/types/config.types.js +2 -0
  45. package/build/domain/types/index.d.ts +2 -0
  46. package/build/domain/types/index.js +18 -0
  47. package/build/domain/types/message.types.d.ts +134 -0
  48. package/build/domain/types/message.types.js +2 -0
  49. package/build/index.d.ts +5 -4
  50. package/build/index.js +7 -6
  51. package/build/infrastructure/http/axios/retry.interceptor.d.ts +2 -0
  52. package/build/infrastructure/http/axios/retry.interceptor.js +21 -0
  53. package/build/infrastructure/http/axios/sendwave-api.factory.d.ts +15 -0
  54. package/build/infrastructure/http/axios/sendwave-api.factory.js +50 -0
  55. package/build/infrastructure/http/middleware/body-parser.middleware.d.ts +2 -0
  56. package/build/infrastructure/http/middleware/body-parser.middleware.js +28 -0
  57. package/build/infrastructure/http/middleware/cors.middleware.d.ts +6 -0
  58. package/build/infrastructure/http/middleware/cors.middleware.js +8 -0
  59. package/build/infrastructure/http/middleware/global-args.middleware.d.ts +2 -0
  60. package/build/infrastructure/http/middleware/global-args.middleware.js +9 -0
  61. package/build/infrastructure/http/middleware/rate-limiter.middleware.d.ts +4 -0
  62. package/build/infrastructure/http/middleware/rate-limiter.middleware.js +31 -0
  63. package/build/infrastructure/http/middleware/static-assets.middleware.d.ts +2 -0
  64. package/build/infrastructure/http/middleware/static-assets.middleware.js +8 -0
  65. package/build/infrastructure/http/routes/routes.d.ts +4 -0
  66. package/build/infrastructure/http/routes/routes.js +56 -0
  67. package/build/infrastructure/media/media-detector.service.d.ts +27 -0
  68. package/build/infrastructure/media/media-detector.service.js +123 -0
  69. package/build/infrastructure/parser/incoming-message.parser.d.ts +2 -0
  70. package/build/infrastructure/parser/incoming-message.parser.js +41 -0
  71. package/build/infrastructure/persistence/instance.registry.d.ts +21 -0
  72. package/build/infrastructure/persistence/instance.registry.js +44 -0
  73. package/build/infrastructure/persistence/sendwave-api.repository.d.ts +21 -0
  74. package/build/infrastructure/persistence/sendwave-api.repository.js +64 -0
  75. package/build/package.json +48 -48
  76. package/build/presentation/pages/assets/logo.svg.d.ts +1 -0
  77. package/build/presentation/pages/assets/logo.svg.js +4 -0
  78. package/build/presentation/pages/assets/wave-error.svg.d.ts +1 -0
  79. package/build/presentation/pages/assets/wave-error.svg.js +92 -0
  80. package/build/presentation/pages/assets/wave.svg.d.ts +1 -0
  81. package/build/presentation/pages/assets/wave.svg.js +92 -0
  82. package/build/presentation/pages/connect.page.d.ts +1 -0
  83. package/build/presentation/pages/connect.page.js +182 -0
  84. package/build/presentation/pages/error.page.d.ts +1 -0
  85. package/build/presentation/pages/error.page.js +42 -0
  86. package/build/presentation/pages/home.page.d.ts +1 -0
  87. package/build/presentation/pages/home.page.js +29 -0
  88. package/build/presentation/provider/index.d.ts +2 -0
  89. package/build/presentation/provider/index.js +18 -0
  90. package/build/presentation/provider/sendwave-core.d.ts +25 -0
  91. package/build/presentation/provider/sendwave-core.js +125 -0
  92. package/build/presentation/provider/sendwave.provider.d.ts +73 -0
  93. package/build/presentation/provider/sendwave.provider.js +359 -0
  94. package/build/provider/sender.d.ts +3 -1
  95. package/build/provider/sender.js +52 -34
  96. package/build/shared/exceptions/payload-too-large.exception.d.ts +4 -0
  97. package/build/shared/exceptions/payload-too-large.exception.js +11 -0
  98. package/build/shared/utils/error-extractor.d.ts +1 -0
  99. package/build/shared/utils/error-extractor.js +7 -0
  100. package/build/shared/utils/size-parser.d.ts +1 -0
  101. package/build/shared/utils/size-parser.js +17 -0
  102. package/package.json +48 -48
  103. package/tsconfig.json +7 -5
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SendWaveProvider = void 0;
7
+ const bot_1 = require("@builderbot/bot");
8
+ const queue_promise_1 = __importDefault(require("queue-promise"));
9
+ const defaults_1 = require("../../config/defaults");
10
+ const constants_1 = require("../../config/constants");
11
+ const sendwave_core_1 = require("./sendwave-core");
12
+ const connection_polling_service_1 = require("../../application/connection/connection-polling.service");
13
+ const queue_flow_service_1 = require("../../application/queue-flow/queue-flow.service");
14
+ const instance_registry_1 = require("../../infrastructure/persistence/instance.registry");
15
+ const body_parser_middleware_1 = require("../../infrastructure/http/middleware/body-parser.middleware");
16
+ const cors_middleware_1 = require("../../infrastructure/http/middleware/cors.middleware");
17
+ const global_args_middleware_1 = require("../../infrastructure/http/middleware/global-args.middleware");
18
+ const static_assets_middleware_1 = require("../../infrastructure/http/middleware/static-assets.middleware");
19
+ const rate_limiter_middleware_1 = require("../../infrastructure/http/middleware/rate-limiter.middleware");
20
+ const routes_1 = require("../../infrastructure/http/routes/routes");
21
+ class SendWaveProvider extends bot_1.ProviderClass {
22
+ constructor(args) {
23
+ var _a;
24
+ super();
25
+ this.queue = new queue_promise_1.default();
26
+ this.state = false;
27
+ this.instanceConnected = false;
28
+ this.rateLimiter = new rate_limiter_middleware_1.RateLimiterMiddleware();
29
+ this.beforeHttpServerInit = async () => {
30
+ for (const middleware of (0, body_parser_middleware_1.bodyParserMiddleware)(this.globalVendorArgs)) {
31
+ this.server = this.server.use(middleware);
32
+ }
33
+ this.server = this.server
34
+ .use((0, global_args_middleware_1.globalArgsMiddleware)(this.globalVendorArgs))
35
+ .use(cors_middleware_1.corsMiddleware)
36
+ .use("/assets", static_assets_middleware_1.staticAssetsMiddleware)
37
+ .use(this.rateLimiter.handle)
38
+ .get("/qr/:instanceName?", (0, routes_1.createQrRouteHandler)(this.registry))
39
+ .get("/state/:instanceName?", (0, routes_1.createConnectionStateRouteHandler)(this.registry))
40
+ .get("/", this.createRootHandler())
41
+ .post("/webhook", (0, routes_1.createWebhookRouteHandler)(this.vendor));
42
+ };
43
+ this.busEvents = () => [
44
+ {
45
+ event: "auth_failure",
46
+ func: (payload) => this.emit("auth_failure", payload),
47
+ },
48
+ {
49
+ event: "notice",
50
+ func: ({ instructions, title }) => this.emit("notice", { instructions, title }),
51
+ },
52
+ {
53
+ event: "ready",
54
+ func: () => this.emit("ready", true),
55
+ },
56
+ {
57
+ event: "message",
58
+ func: (payload) => {
59
+ var _a;
60
+ if (((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled) &&
61
+ !payload.from.includes("@")) {
62
+ this.resetUserTimeout(payload.from, payload.name);
63
+ }
64
+ this.emit("message", payload);
65
+ },
66
+ },
67
+ {
68
+ event: "flow-message",
69
+ func: (payload) => {
70
+ this.emit("flow-message", payload);
71
+ },
72
+ },
73
+ {
74
+ event: "host",
75
+ func: (payload) => {
76
+ this.emit("host", payload);
77
+ },
78
+ },
79
+ {
80
+ event: "qr-update-request",
81
+ func: () => {
82
+ this.poller.start();
83
+ },
84
+ },
85
+ ];
86
+ this.initAll = (port, opts) => {
87
+ this.globalVendorArgs.port = port;
88
+ if (this.globalVendorArgs.host === "0.0.0.0") {
89
+ process.env.HOST = "0.0.0.0";
90
+ process.env.HOSTNAME = "0.0.0.0";
91
+ }
92
+ const methods = {
93
+ sendMessage: this.sendMessage,
94
+ sendList: this.sendList,
95
+ sendText: this.sendText,
96
+ sendImage: this.sendImage,
97
+ sendVideo: this.sendVideo,
98
+ sendAudio: this.sendAudio,
99
+ sendFile: this.sendFile,
100
+ sendVoice: this.sendVoice,
101
+ sendPresence: this.sendPresence,
102
+ sendButton: this.sendButton,
103
+ sendCarousel: this.sendCarousel,
104
+ sendPoll: this.sendPoll,
105
+ readMessages: this.readMessages,
106
+ sendLocation: this.sendLocation,
107
+ sendReaction: this.sendReaction,
108
+ provider: this,
109
+ blacklist: opts === null || opts === void 0 ? void 0 : opts.blacklist,
110
+ dispatch: (customEvent, payload) => {
111
+ this.emit("message", {
112
+ ...payload,
113
+ body: bot_1.utils.setEvent(customEvent),
114
+ name: payload.name,
115
+ from: bot_1.utils.removePlus(payload.from),
116
+ });
117
+ },
118
+ };
119
+ this.initVendor()
120
+ .then((v) => this.listenOnEvents(v))
121
+ .then(() => {
122
+ this.beforeHttpServerInit();
123
+ this.start(methods, (routes) => {
124
+ this.emit("notice", {
125
+ title: "🛜 HTTP Server ON ",
126
+ instructions: routes,
127
+ });
128
+ this.afterHttpServerInit();
129
+ });
130
+ })
131
+ .catch((error) => {
132
+ console.error("[Provider Error]:", error);
133
+ if (error.type === "entity.too.large") {
134
+ console.error("[Provider] PayloadTooLarge error caught at provider level");
135
+ }
136
+ });
137
+ };
138
+ this.globalVendorArgs = (0, defaults_1.mergeDefaults)(args);
139
+ this.queue = new queue_promise_1.default({
140
+ concurrent: constants_1.QUEUE_OPTIONS.concurrent,
141
+ interval: constants_1.QUEUE_OPTIONS.interval,
142
+ start: true,
143
+ });
144
+ if ((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled) {
145
+ queue_flow_service_1.queueFlow.updateConfig({
146
+ warningTimeout: this.globalVendorArgs.queueFlow.warningTimeout,
147
+ endTimeout: this.globalVendorArgs.queueFlow.endTimeout,
148
+ warningMessage: this.globalVendorArgs.queueFlow.warningMessage,
149
+ });
150
+ }
151
+ this.registry = new instance_registry_1.InstanceRegistry({
152
+ url: this.globalVendorArgs.url,
153
+ payloadLimits: this.globalVendorArgs.payloadLimits,
154
+ });
155
+ this.registry.registerMany(this.globalVendorArgs.instances || []);
156
+ const defaultInstance = this.registry.getDefault();
157
+ if (!defaultInstance) {
158
+ throw new Error("SendWaveProvider: At least one instance must be configured");
159
+ }
160
+ this.sender = defaultInstance.sender;
161
+ this.poller = new connection_polling_service_1.ConnectionPollingService(defaultInstance.api, {
162
+ onConnected: () => {
163
+ this.instanceConnected = true;
164
+ this.state = true;
165
+ this.emit("ready", true);
166
+ },
167
+ onDisconnected: () => {
168
+ this.instanceConnected = true;
169
+ this.state = false;
170
+ this.emit("ready", false);
171
+ this.poller.start();
172
+ },
173
+ onAuthFailure: (error) => {
174
+ var _a, _b;
175
+ this.instanceConnected = false;
176
+ this.emit("auth_failure", {
177
+ instructions: `Error al autenticar: ${(_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error}`,
178
+ });
179
+ },
180
+ });
181
+ this.on("ready", (isReady) => {
182
+ if (this.lastReadyState !== isReady) {
183
+ if (isReady) {
184
+ console.log("Instance connection status:", "Connected to server");
185
+ }
186
+ this.lastReadyState = isReady;
187
+ }
188
+ });
189
+ this.setupGlobalErrorHandlers();
190
+ }
191
+ setupGlobalErrorHandlers() {
192
+ process.on("uncaughtException", (error) => {
193
+ if (error.name === "PayloadTooLargeError" ||
194
+ error.type === "entity.too.large") {
195
+ console.error("[Global] PayloadTooLarge error intercepted:", error.message);
196
+ return;
197
+ }
198
+ console.error("[Global] Uncaught exception:", error);
199
+ });
200
+ process.on("unhandledRejection", (reason) => {
201
+ if (reason &&
202
+ (reason.name === "PayloadTooLargeError" ||
203
+ reason.type === "entity.too.large")) {
204
+ console.error("[Global] PayloadTooLarge rejection intercepted:", reason.message);
205
+ return;
206
+ }
207
+ console.error("[Global] Unhandled rejection:", reason);
208
+ });
209
+ }
210
+ initVendor() {
211
+ const deps = {
212
+ queue: this.queue,
213
+ globalVendorArgs: this.globalVendorArgs,
214
+ registry: this.registry,
215
+ };
216
+ const vendor = new sendwave_core_1.SendWaveCore(this.globalVendorArgs.port, deps);
217
+ this.vendor = vendor;
218
+ this.vendor.on("user-message", (data) => this.emit("user-message", data));
219
+ this.vendor.on("flow-message", (data) => this.emit("flow-message", data));
220
+ return Promise.resolve(this.vendor);
221
+ }
222
+ createRootHandler() {
223
+ return async (req, res) => {
224
+ if (this.state && this.instanceConnected) {
225
+ await this.afterHttpServerInit();
226
+ return this.vendor.indexHome(req, res);
227
+ }
228
+ if (!this.state && this.instanceConnected) {
229
+ await this.afterHttpServerInit();
230
+ return this.vendor.indexConnect(req, res);
231
+ }
232
+ return this.vendor.indexError()(req, res);
233
+ };
234
+ }
235
+ async afterHttpServerInit() {
236
+ await this.poller.check();
237
+ }
238
+ getInstance(name) {
239
+ const instance = name ? this.registry.get(name) : this.registry.getDefault();
240
+ if (!instance)
241
+ throw new Error(`Instance not found: ${name}`);
242
+ return instance;
243
+ }
244
+ getInstances() {
245
+ return this.registry.getAll();
246
+ }
247
+ saveFile(_, options) {
248
+ return Promise.resolve((options === null || options === void 0 ? void 0 : options.path) || "");
249
+ }
250
+ async listenOnEvents(vendor) {
251
+ const listEvents = this.busEvents();
252
+ for (const { event, func } of listEvents) {
253
+ vendor.on(event, func);
254
+ }
255
+ }
256
+ sendFlow(data) {
257
+ this.emit("message", {
258
+ body: bot_1.utils.setEvent(data.event),
259
+ name: data.name,
260
+ from: data.from,
261
+ });
262
+ }
263
+ async sendMessage(from, text, options) {
264
+ return this.sendToDefault((sender) => sender.dispatch(from, text, options));
265
+ }
266
+ sendText(data, instanceName) {
267
+ return this.sendToInstance(instanceName, (sender) => sender.sendText(data));
268
+ }
269
+ sendList(data, instanceName) {
270
+ return this.sendToInstance(instanceName, (sender) => sender.sendList(data));
271
+ }
272
+ sendImage(data, instanceName) {
273
+ return this.sendToInstance(instanceName, (sender) => sender.sendImage(data));
274
+ }
275
+ sendVideo(data, instanceName) {
276
+ return this.sendToInstance(instanceName, (sender) => sender.sendVideo(data));
277
+ }
278
+ sendAudio(data, instanceName) {
279
+ return this.sendToInstance(instanceName, (sender) => sender.sendAudio(data));
280
+ }
281
+ sendFile(data, instanceName) {
282
+ return this.sendToInstance(instanceName, (sender) => sender.sendFile(data));
283
+ }
284
+ sendPresence(data, instanceName) {
285
+ return this.sendToInstance(instanceName, (sender) => sender.sendPresence(data));
286
+ }
287
+ sendVoice(data, instanceName) {
288
+ return this.sendToInstance(instanceName, (sender) => sender.sendVoice(data));
289
+ }
290
+ sendButton(data, instanceName) {
291
+ return this.sendToInstance(instanceName, (sender) => sender.sendButton(data));
292
+ }
293
+ sendCarousel(data, instanceName) {
294
+ return this.sendToInstance(instanceName, (sender) => sender.sendCarousel(data));
295
+ }
296
+ sendPoll(data, instanceName) {
297
+ return this.sendToInstance(instanceName, (sender) => sender.sendPoll(data));
298
+ }
299
+ sendReaction(data, instanceName) {
300
+ return this.sendToInstance(instanceName, (sender) => sender.sendReaction(data));
301
+ }
302
+ sendLocation(data, instanceName) {
303
+ return this.sendToInstance(instanceName, (sender) => sender.sendLocation(data));
304
+ }
305
+ sendMedia(data, instanceName) {
306
+ return this.sendToInstance(instanceName, (sender) => sender.sendMedia(data));
307
+ }
308
+ readMessages(data, instanceName) {
309
+ return this.sendToInstance(instanceName, (sender) => sender.readMessages(data));
310
+ }
311
+ sendToInstance(instanceName, action) {
312
+ const instance = this.getInstance(instanceName);
313
+ return action(instance.sender);
314
+ }
315
+ sendToDefault(action) {
316
+ return action(this.sender);
317
+ }
318
+ resetUserTimeout(from, name) {
319
+ var _a;
320
+ if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
321
+ return;
322
+ return queue_flow_service_1.queueFlow.resetUserTimeout({
323
+ sendText: (to, text) => this.sender.sendText({ from: to, text }),
324
+ sendFlow: (event, name, from) => this.sendFlow({ event, name, from }),
325
+ from,
326
+ name,
327
+ });
328
+ }
329
+ clearUserTimeout(from) {
330
+ var _a;
331
+ if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
332
+ return;
333
+ queue_flow_service_1.queueFlow.clearUserTimeout(from);
334
+ }
335
+ forceClearUser(from) {
336
+ var _a;
337
+ if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
338
+ return;
339
+ queue_flow_service_1.queueFlow.forceClearUser(from);
340
+ }
341
+ isUserIgnored(from) {
342
+ var _a;
343
+ if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
344
+ return false;
345
+ return queue_flow_service_1.queueFlow.isUserIgnored(from);
346
+ }
347
+ onQueueFlowEvent(event, callback) {
348
+ queue_flow_service_1.queueFlow.on(event, callback);
349
+ }
350
+ offQueueFlowEvent(event, callback) {
351
+ if (callback) {
352
+ queue_flow_service_1.queueFlow.off(event, callback);
353
+ }
354
+ else {
355
+ queue_flow_service_1.queueFlow.removeAllListeners(event);
356
+ }
357
+ }
358
+ }
359
+ exports.SendWaveProvider = SendWaveProvider;
@@ -1,4 +1,4 @@
1
- import { GlobalVendorArgs, ProviderInterface, SendButton, SendList, SendMedia, SendMessage, SendPresence, SendPoll, SendLocation, SendReaction, ReadMessage } from "../core/interface";
1
+ import { GlobalVendorArgs, ProviderInterface, SendButton, SendCarousel, SendList, SendMedia, SendMessage, SendPresence, SendPoll, SendLocation, SendReaction, ReadMessage } from "../core/interface";
2
2
  export declare class SenderMessage implements ProviderInterface {
3
3
  private sendwaveApi?;
4
4
  private globalVendorArgs?;
@@ -14,7 +14,9 @@ export declare class SenderMessage implements ProviderInterface {
14
14
  sendAudio(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
15
15
  sendVideo(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
16
16
  sendVoice(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
17
+ private normalizeButton;
17
18
  sendButton(data: SendButton): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
19
+ sendCarousel(data: SendCarousel): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
18
20
  sendPoll(data: SendPoll): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
19
21
  sendLocation(data: SendLocation): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
20
22
  sendReaction(data: SendReaction): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
@@ -312,6 +312,23 @@ class SenderMessage {
312
312
  }
313
313
  }
314
314
  }
315
+ normalizeButton(button, index) {
316
+ if (typeof button === "string") {
317
+ return { type: "reply", displayText: button, id: `${index + 1}` };
318
+ }
319
+ const raw = button;
320
+ const { type = "reply", displayText, ...rest } = raw;
321
+ const base = {
322
+ type,
323
+ displayText: displayText || raw.text || "",
324
+ id: `${index + 1}`,
325
+ ...rest,
326
+ };
327
+ delete base.text;
328
+ delete base.body;
329
+ delete base.reply;
330
+ return base;
331
+ }
315
332
  async sendButton(data) {
316
333
  var _a, _b, _c, _d, _e, _f;
317
334
  try {
@@ -322,40 +339,7 @@ class SenderMessage {
322
339
  body: data.body,
323
340
  description: data.description,
324
341
  footer: data.footer,
325
- buttons: data.buttons.map((button, index) => {
326
- let type = "reply";
327
- let displayText = "";
328
- let rest = {};
329
- if (typeof button === "string") {
330
- displayText = button;
331
- }
332
- else if (button.displayText) {
333
- displayText = button.displayText;
334
- type = button.type || "reply";
335
- rest = button;
336
- }
337
- else if (button.type === "reply") {
338
- displayText = button.displayText;
339
- type = "reply";
340
- rest = button;
341
- }
342
- else {
343
- displayText = button.displayText || button.text || button;
344
- type = button.type || "reply";
345
- rest = button;
346
- }
347
- const base = {
348
- type,
349
- displayText,
350
- id: `${index + 1}`,
351
- ...rest
352
- };
353
- // Clean up unwanted properties
354
- delete base.text;
355
- delete base.body;
356
- delete base.reply;
357
- return base;
358
- }),
342
+ buttons: data.buttons.map((button, index) => this.normalizeButton(button, index)),
359
343
  delay: data.delay || 2000,
360
344
  quoted: data.quoted,
361
345
  everyOne: data.everyOne || false,
@@ -371,6 +355,40 @@ class SenderMessage {
371
355
  throw new Error(msg);
372
356
  }
373
357
  }
358
+ async sendCarousel(data) {
359
+ var _a, _b, _c, _d, _e, _f;
360
+ try {
361
+ if (!(data === null || data === void 0 ? void 0 : data.from))
362
+ throw new Error("sendCarousel: falta 'from'");
363
+ if (!Array.isArray(data.cards) || data.cards.length === 0)
364
+ throw new Error("sendCarousel: 'cards' debe ser un array no vacío");
365
+ const cards = data.cards.map((card, cardIndex) => ({
366
+ text: card.text,
367
+ thumbnailUrl: card.thumbnailUrl,
368
+ footerText: card.footerText,
369
+ buttons: (card.buttons || []).map((button, buttonIndex) => this.normalizeButton(button, cardIndex * 100 + buttonIndex)),
370
+ }));
371
+ return await ((_a = this.sendwaveApi) === null || _a === void 0 ? void 0 : _a.post(`/message/sendCarousel/${(_b = this.globalVendorArgs) === null || _b === void 0 ? void 0 : _b.name}`, {
372
+ number: data.from,
373
+ title: data.title,
374
+ description: data.description,
375
+ footer: data.footer,
376
+ cards,
377
+ delay: data.delay || 2000,
378
+ quoted: data.quoted,
379
+ everyOne: data.everyOne || false,
380
+ mentioned: ((_c = data.mentioned) === null || _c === void 0 ? void 0 : _c.length) ? data.mentioned : [data.from],
381
+ ...this.globalVendorArgs,
382
+ }));
383
+ }
384
+ catch (error) {
385
+ const msg = ((_f = (_e = (_d = error === null || error === void 0 ? void 0 : error.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.response) === null || _f === void 0 ? void 0 : _f.message) ||
386
+ (error === null || error === void 0 ? void 0 : error.message) ||
387
+ "Unknown error";
388
+ console.error(`[sendCarousel Error] ${msg}`);
389
+ throw new Error(msg);
390
+ }
391
+ }
374
392
  async sendPoll(data) {
375
393
  var _a, _b, _c, _d, _e, _f;
376
394
  try {
@@ -0,0 +1,4 @@
1
+ export declare class PayloadTooLargeError extends Error {
2
+ readonly code = "PAYLOAD_TOO_LARGE";
3
+ constructor(message?: string);
4
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PayloadTooLargeError = void 0;
4
+ class PayloadTooLargeError extends Error {
5
+ constructor(message = "Payload too large") {
6
+ super(message);
7
+ this.code = "PAYLOAD_TOO_LARGE";
8
+ this.name = "PayloadTooLargeError";
9
+ }
10
+ }
11
+ exports.PayloadTooLargeError = PayloadTooLargeError;
@@ -0,0 +1 @@
1
+ export declare function extractApiError(error: any, fallback?: string): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractApiError = extractApiError;
4
+ function extractApiError(error, fallback = "Unknown error") {
5
+ var _a, _b, _c;
6
+ return ((_c = (_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.response) === null || _c === void 0 ? void 0 : _c.message) || (error === null || error === void 0 ? void 0 : error.message) || fallback;
7
+ }
@@ -0,0 +1 @@
1
+ export declare function parseSize(size: string, defaultValue?: number): number;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSize = parseSize;
4
+ const units = {
5
+ b: 1,
6
+ kb: 1024,
7
+ mb: 1024 * 1024,
8
+ gb: 1024 * 1024 * 1024,
9
+ };
10
+ function parseSize(size, defaultValue = 50 * 1024 * 1024) {
11
+ const match = size.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);
12
+ if (!match)
13
+ return defaultValue;
14
+ const value = parseFloat(match[1]);
15
+ const unit = match[2] || "b";
16
+ return Math.floor(value * (units[unit] || 1));
17
+ }
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
- {
2
- "name": "@gamastudio/sendwave-provider",
3
- "version": "1.0.3",
4
- "description": "Librería para interactuar con Sendwave usando configuración dinámica.",
5
- "main": "build/index.js",
6
- "types": "build/index.d.ts",
7
- "publishConfig": {
8
- "access": "public"
9
- },
10
- "scripts": {
11
- "build": "tsc && tsc-alias && copyfiles package.json build",
12
- "test": "ts-node -r tsconfig-paths/register test/test.ts",
13
- "dev": "ts-node-dev --respawn --transpile-only -r tsconfig-paths/register test/test.ts",
14
- "prepublishOnly": "npm run build"
15
- },
16
- "keywords": [
17
- "Sendwave",
18
- "Provider",
19
- "Gamastudio",
20
- "Bot"
21
- ],
22
- "author": "Ameth Galarcio <amethgm@gmail.com>",
23
- "license": "ISC",
24
- "dependencies": {
25
- "@builderbot/bot": "^1.3.15",
26
- "@gamastudio/colorslog": "^0.1.8",
27
- "@types/mime-types": "^3.0.1",
28
- "axios": "^1.13.2",
29
- "body-parser": "^2.2.2",
30
- "cors": "^2.8.5",
31
- "file-type": "^21.3.0",
32
- "mime-types": "^3.0.2",
33
- "queue-promise": "^2.2.1",
34
- "sirv": "^3.0.2"
35
- },
36
- "devDependencies": {
37
- "@types/axios": "^0.14.4",
38
- "@types/body-parser": "^1.19.6",
39
- "@types/cors": "^2.8.19",
40
- "@types/node": "^24.10.9",
41
- "copyfiles": "^2.4.1",
42
- "ts-node": "^10.9.2",
43
- "ts-node-dev": "^2.0.0",
44
- "tsc-alias": "^1.8.16",
45
- "tsconfig-paths": "^4.2.0",
46
- "typescript": "^5.9.3"
47
- }
48
- }
1
+ {
2
+ "name": "@gamastudio/sendwave-provider",
3
+ "version": "1.0.4",
4
+ "description": "Official Sendwaves provider for BuilderBot. Multi-instance WhatsApp messaging library with intelligent message merging, media support, interactive buttons, lists, carousels, polls, and automatic queue flow.",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc && tsc-alias && copyfiles package.json build",
12
+ "test": "ts-node -r tsconfig-paths/register test/test.ts",
13
+ "dev": "ts-node-dev --respawn --transpile-only -r tsconfig-paths/register test/test.ts",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "Sendwave",
18
+ "Provider",
19
+ "Gamastudio",
20
+ "Bot"
21
+ ],
22
+ "author": "Ameth Galarcio <amethgm@gmail.com>",
23
+ "license": "ISC",
24
+ "dependencies": {
25
+ "@builderbot/bot": "^1.3.15",
26
+ "@gamastudio/colorslog": "^0.1.8",
27
+ "@types/mime-types": "^3.0.1",
28
+ "axios": "^1.13.2",
29
+ "body-parser": "^2.2.2",
30
+ "cors": "^2.8.5",
31
+ "file-type": "^21.3.0",
32
+ "mime-types": "^3.0.2",
33
+ "queue-promise": "^2.2.1",
34
+ "sirv": "^3.0.2"
35
+ },
36
+ "devDependencies": {
37
+ "@types/axios": "^0.14.4",
38
+ "@types/body-parser": "^1.19.6",
39
+ "@types/cors": "^2.8.19",
40
+ "@types/node": "^24.10.9",
41
+ "copyfiles": "^2.4.1",
42
+ "ts-node": "^10.9.2",
43
+ "ts-node-dev": "^2.0.0",
44
+ "tsc-alias": "^1.8.16",
45
+ "tsconfig-paths": "^4.2.0",
46
+ "typescript": "^5.9.3"
47
+ }
48
+ }
package/tsconfig.json CHANGED
@@ -2,10 +2,12 @@
2
2
  "compilerOptions": {
3
3
  "baseUrl": "./src",
4
4
  "paths": {
5
- "@provider/*": ["provider/*"],
6
- "@interface/*": ["interface/*"],
7
- "@utils/*": ["utils/*"],
8
- "@core/*": ["core/*"]
5
+ "@config/*": ["config/*"],
6
+ "@domain/*": ["domain/*"],
7
+ "@infrastructure/*": ["infrastructure/*"],
8
+ "@application/*": ["application/*"],
9
+ "@presentation/*": ["presentation/*"],
10
+ "@shared/*": ["shared/*"]
9
11
  },
10
12
  "outDir": "build",
11
13
  "module": "CommonJS",
@@ -16,4 +18,4 @@
16
18
  "skipLibCheck": true
17
19
  },
18
20
  "include": ["src/**/*"]
19
- }
21
+ }