@gamastudio/sendwave-provider 0.0.7-dev → 0.0.7-dev1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamastudio/sendwave-provider",
3
- "version": "0.0.7-dev",
3
+ "version": "0.0.7-dev1",
4
4
  "description": "Librería para interactuar con Sendwave usando configuración dinámica.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -178,12 +178,6 @@ class SendWaveProvider extends bot_1.ProviderClass {
178
178
  .then(() => {
179
179
  this.beforeHttpServerInit();
180
180
  this.start(methods, (routes) => {
181
- // Log the actual server binding info
182
- console.log(`🌐 Server binding: ${this.globalVendorArgs.host || 'localhost'}:${this.globalVendorArgs.port}`);
183
- if (this.globalVendorArgs.host === "0.0.0.0") {
184
- console.log(`🔗 External access: Server accessible from all network interfaces`);
185
- console.log(`📡 Webhook URL for external services: http://<your-ip>:${this.globalVendorArgs.port}/webhook`);
186
- }
187
181
  this.emit("notice", {
188
182
  title: "🛜 HTTP Server ON ",
189
183
  instructions: routes,
@@ -363,11 +357,6 @@ class SendWaveProvider extends bot_1.ProviderClass {
363
357
  detectorMedia_1.detectorMedia.updateLimits(this.globalVendorArgs.payloadLimits.media);
364
358
  }
365
359
  const { media, mediaType, fileName, size } = await detectorMedia_1.detectorMedia.processMedia(options.media);
366
- // Log large media processing
367
- if (size && size > 1024 * 1024) {
368
- const sizeMB = Math.round(size / 1024 / 1024 * 100) / 100;
369
- console.log(`[SendMessage] Processing ${mediaType} file: ${sizeMB}MB`);
370
- }
371
360
  switch (mediaType) {
372
361
  case "image":
373
362
  return await this.sender.sendImage({
@@ -8,6 +8,7 @@ export declare class SenderMessage implements ProviderInterface {
8
8
  sendText(data: SendMessage): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
9
9
  sendList(data: SendList): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
10
10
  sendMedia(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
11
+ private getDefaultMimeType;
11
12
  sendFile(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
12
13
  sendImage(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
13
14
  sendAudio(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
@@ -10,7 +10,7 @@ const detectorMedia_1 = require("../utils/detectorMedia");
10
10
  class SenderMessage {
11
11
  constructor(args) {
12
12
  const payloadLimits = args.payloadLimits || {};
13
- const maxContentLength = this.parseSize(payloadLimits.json || '50mb');
13
+ const maxContentLength = this.parseSize(payloadLimits.json || "50mb");
14
14
  this.sendwaveApi = axios_1.default.create({
15
15
  baseURL: args.url,
16
16
  httpsAgent: new https_1.Agent({ rejectUnauthorized: false }),
@@ -26,16 +26,16 @@ class SenderMessage {
26
26
  }
27
27
  parseSize(size) {
28
28
  const units = {
29
- 'b': 1,
30
- 'kb': 1024,
31
- 'mb': 1024 * 1024,
32
- 'gb': 1024 * 1024 * 1024
29
+ b: 1,
30
+ kb: 1024,
31
+ mb: 1024 * 1024,
32
+ gb: 1024 * 1024 * 1024,
33
33
  };
34
34
  const match = size.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);
35
35
  if (!match)
36
36
  return 50 * 1024 * 1024; // Default 50MB
37
37
  const value = parseFloat(match[1]);
38
- const unit = match[2] || 'b';
38
+ const unit = match[2] || "b";
39
39
  return Math.floor(value * units[unit]);
40
40
  }
41
41
  async sendPresence(data) {
@@ -121,12 +121,43 @@ class SenderMessage {
121
121
  if ((_b = (_a = this.globalVendorArgs) === null || _a === void 0 ? void 0 : _a.payloadLimits) === null || _b === void 0 ? void 0 : _b.media) {
122
122
  detectorMedia_1.detectorMedia.updateLimits(this.globalVendorArgs.payloadLimits.media);
123
123
  }
124
- const { media, mimeType, mediaType, size } = await detectorMedia_1.detectorMedia.processMedia(data.url);
125
- // Log large media processing
126
- if (size && size > 1024 * 1024) {
127
- const sizeMB = Math.round(size / 1024 / 1024 * 100) / 100;
128
- console.log(`[SendMedia] Processing ${mediaType} file: ${sizeMB}MB`);
124
+ let media;
125
+ let mimeType;
126
+ let mediaType;
127
+ // If mediaType is already specified (from sendImage, sendVideo, etc), use it
128
+ if (data.mediaType) {
129
+ console.log(`[SendMedia] Using predefined mediaType: ${data.mediaType}`);
130
+ // Just validate size and get media content without detection
131
+ if (detectorMedia_1.detectorMedia.isRemoteUrl(data.url)) {
132
+ // For remote URLs, validate size and use URL directly
133
+ await detectorMedia_1.detectorMedia.validateUrlSize(data.url, data.mediaType);
134
+ media = data.url;
135
+ // Get actual MIME type from server if possible
136
+ try {
137
+ const { mimeType: detectedMime } = await detectorMedia_1.detectorMedia.getMimeTypeFromUrl(data.url);
138
+ mimeType = detectedMime || this.getDefaultMimeType(data.mediaType);
139
+ }
140
+ catch {
141
+ mimeType = this.getDefaultMimeType(data.mediaType);
142
+ }
143
+ }
144
+ else {
145
+ // For local files, convert to base64
146
+ const result = await detectorMedia_1.detectorMedia.convertPathToBase64(data.url);
147
+ media = result.media;
148
+ mimeType = result.mimeType;
149
+ }
150
+ mediaType = data.mediaType;
129
151
  }
152
+ else {
153
+ // If no mediaType specified, detect it (for generic sendMedia calls)
154
+ console.log(`[SendMedia] Auto-detecting mediaType for: ${data.url}`);
155
+ const result = await detectorMedia_1.detectorMedia.processMedia(data.url);
156
+ media = result.media;
157
+ mimeType = result.mimeType;
158
+ mediaType = result.mediaType;
159
+ }
160
+ console.log(`[SendMedia] Final - MediaType: ${mediaType}, MimeType: ${mimeType}`);
130
161
  return await ((_c = this.sendwaveApi) === null || _c === void 0 ? void 0 : _c.post(`/message/sendMedia/${(_d = this.globalVendorArgs) === null || _d === void 0 ? void 0 : _d.name}`, {
131
162
  number: data.from.split("@")[0],
132
163
  caption: data.text,
@@ -139,25 +170,34 @@ class SenderMessage {
139
170
  }
140
171
  catch (e) {
141
172
  // Enhanced error handling for large files
142
- if (e.message && e.message.includes('exceeds limit')) {
173
+ if (e.message && e.message.includes("exceeds limit")) {
143
174
  console.error(`[SendMedia Error] File size validation failed: ${e.message}`);
144
175
  throw new Error(`File too large: ${e.message}`);
145
176
  }
146
177
  else if (((_e = e.response) === null || _e === void 0 ? void 0 : _e.status) === 413) {
147
- console.error('[SendMedia Error] Server rejected large payload');
148
- throw new Error('File too large for server');
178
+ console.error("[SendMedia Error] Server rejected large payload");
179
+ throw new Error("File too large for server");
149
180
  }
150
- else if (e.code === 'ECONNABORTED') {
151
- console.error('[SendMedia Error] Request timeout - file may be too large');
152
- throw new Error('Upload timeout - file may be too large');
181
+ else if (e.code === "ECONNABORTED") {
182
+ console.error("[SendMedia Error] Request timeout - file may be too large");
183
+ throw new Error("Upload timeout - file may be too large");
153
184
  }
154
185
  else {
155
- const errorMsg = ((_h = (_g = (_f = e.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.response) === null || _h === void 0 ? void 0 : _h.message) || e.message || 'Unknown error';
186
+ const errorMsg = ((_h = (_g = (_f = e.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.response) === null || _h === void 0 ? void 0 : _h.message) || e.message || "Unknown error";
156
187
  console.error(`[SendMedia Error] ${errorMsg}`);
157
188
  throw new Error(errorMsg);
158
189
  }
159
190
  }
160
191
  }
192
+ getDefaultMimeType(mediaType) {
193
+ const defaults = {
194
+ image: 'image/jpeg',
195
+ video: 'video/mp4',
196
+ audio: 'audio/mpeg',
197
+ document: 'application/octet-stream'
198
+ };
199
+ return defaults[mediaType] || 'application/octet-stream';
200
+ }
161
201
  async sendFile(data) {
162
202
  try {
163
203
  return await this.sendMedia({
@@ -210,12 +250,7 @@ class SenderMessage {
210
250
  if ((_b = (_a = this.globalVendorArgs) === null || _a === void 0 ? void 0 : _a.payloadLimits) === null || _b === void 0 ? void 0 : _b.media) {
211
251
  detectorMedia_1.detectorMedia.updateLimits(this.globalVendorArgs.payloadLimits.media);
212
252
  }
213
- const { media, size } = await detectorMedia_1.detectorMedia.processMedia(data.url);
214
- // Log large audio processing
215
- if (size && size > 1024 * 1024) {
216
- const sizeMB = Math.round(size / 1024 / 1024 * 100) / 100;
217
- console.log(`[SendVoice] Processing audio file: ${sizeMB}MB`);
218
- }
253
+ const { media } = await detectorMedia_1.detectorMedia.processMedia(data.url);
219
254
  await this.sendPresence({
220
255
  from: data.from,
221
256
  presence: "recording",
@@ -229,20 +264,20 @@ class SenderMessage {
229
264
  }
230
265
  catch (e) {
231
266
  // Enhanced error handling for large audio files
232
- if (e.message && e.message.includes('exceeds limit')) {
267
+ if (e.message && e.message.includes("exceeds limit")) {
233
268
  console.error(`[SendVoice Error] File size validation failed: ${e.message}`);
234
269
  throw new Error(`Audio file too large: ${e.message}`);
235
270
  }
236
271
  else if (((_e = e.response) === null || _e === void 0 ? void 0 : _e.status) === 413) {
237
- console.error('[SendVoice Error] Server rejected large payload');
238
- throw new Error('Audio file too large for server');
272
+ console.error("[SendVoice Error] Server rejected large payload");
273
+ throw new Error("Audio file too large for server");
239
274
  }
240
- else if (e.code === 'ECONNABORTED') {
241
- console.error('[SendVoice Error] Request timeout - audio file may be too large');
242
- throw new Error('Upload timeout - audio file may be too large');
275
+ else if (e.code === "ECONNABORTED") {
276
+ console.error("[SendVoice Error] Request timeout - audio file may be too large");
277
+ throw new Error("Upload timeout - audio file may be too large");
243
278
  }
244
279
  else {
245
- const errorMsg = ((_h = (_g = (_f = e.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.response) === null || _h === void 0 ? void 0 : _h.message) || e.message || 'Unknown error';
280
+ const errorMsg = ((_h = (_g = (_f = e.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.response) === null || _h === void 0 ? void 0 : _h.message) || e.message || "Unknown error";
246
281
  console.error(`[SendVoice Error] ${errorMsg}`);
247
282
  throw new Error(errorMsg);
248
283
  }
@@ -19,10 +19,13 @@ export declare class DetectorMedia {
19
19
  updateLimits(limits: MediaLimits): void;
20
20
  private parseSize;
21
21
  private validateFileSize;
22
- private validateUrlSize;
22
+ validateUrlSize(url: string, mediaType: string): Promise<number>;
23
23
  isRemoteUrl(url: string): boolean;
24
24
  convertPathToBase64(filePath: string): Promise<DetectorMediaProps>;
25
- getMimeTypeFromUrl(url: string): Promise<string | null>;
25
+ getMimeTypeFromUrl(url: string): Promise<{
26
+ mediaType: string | null;
27
+ mimeType: string | null;
28
+ }>;
26
29
  extractFileNameFromUrl(url: string): Promise<string>;
27
30
  /**
28
31
  * Método unificado que acepta path o url y devuelve:
@@ -11,11 +11,11 @@ const axios_1 = __importDefault(require("axios"));
11
11
  class DetectorMedia {
12
12
  constructor(limits) {
13
13
  this.mediaLimits = {
14
- image: '10mb',
15
- video: '100mb',
16
- audio: '50mb',
17
- document: '25mb',
18
- ...limits
14
+ image: "10mb",
15
+ video: "100mb",
16
+ audio: "50mb",
17
+ document: "25mb",
18
+ ...limits,
19
19
  };
20
20
  }
21
21
  static getInstance(limits) {
@@ -29,56 +29,56 @@ class DetectorMedia {
29
29
  }
30
30
  parseSize(size) {
31
31
  const units = {
32
- 'b': 1,
33
- 'kb': 1024,
34
- 'mb': 1024 * 1024,
35
- 'gb': 1024 * 1024 * 1024
32
+ b: 1,
33
+ kb: 1024,
34
+ mb: 1024 * 1024,
35
+ gb: 1024 * 1024 * 1024,
36
36
  };
37
37
  const match = size.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);
38
38
  if (!match)
39
39
  return 10 * 1024 * 1024; // Default 10MB
40
40
  const value = parseFloat(match[1]);
41
- const unit = match[2] || 'b';
41
+ const unit = match[2] || "b";
42
42
  return Math.floor(value * units[unit]);
43
43
  }
44
44
  validateFileSize(filePath, mediaType) {
45
45
  return new Promise((resolve, reject) => {
46
- promises_1.default.stat(filePath).then((stats) => {
46
+ promises_1.default.stat(filePath)
47
+ .then((stats) => {
47
48
  const fileSize = stats.size;
48
- const limitStr = this.mediaLimits[mediaType] || '10mb';
49
+ const limitStr = this.mediaLimits[mediaType] || "10mb";
49
50
  const limit = this.parseSize(limitStr);
50
51
  if (fileSize > limit) {
51
- const fileSizeMB = Math.round(fileSize / 1024 / 1024 * 100) / 100;
52
- const limitMB = Math.round(limit / 1024 / 1024 * 100) / 100;
52
+ const fileSizeMB = Math.round((fileSize / 1024 / 1024) * 100) / 100;
53
+ const limitMB = Math.round((limit / 1024 / 1024) * 100) / 100;
53
54
  reject(new Error(`File size ${fileSizeMB}MB exceeds limit of ${limitMB}MB for ${mediaType} files`));
54
55
  }
55
56
  else {
56
57
  resolve();
57
58
  }
58
- }).catch(reject);
59
+ })
60
+ .catch(reject);
59
61
  });
60
62
  }
61
63
  async validateUrlSize(url, mediaType) {
62
64
  try {
63
65
  const response = await axios_1.default.head(url);
64
- const contentLength = parseInt(response.headers['content-length'] || '0');
66
+ const contentLength = parseInt(response.headers["content-length"] || "0");
65
67
  if (contentLength > 0) {
66
- const limitStr = this.mediaLimits[mediaType] || '10mb';
68
+ const limitStr = this.mediaLimits[mediaType] || "10mb";
67
69
  const limit = this.parseSize(limitStr);
68
70
  if (contentLength > limit) {
69
- const fileSizeMB = Math.round(contentLength / 1024 / 1024 * 100) / 100;
70
- const limitMB = Math.round(limit / 1024 / 1024 * 100) / 100;
71
+ const fileSizeMB = Math.round((contentLength / 1024 / 1024) * 100) / 100;
72
+ const limitMB = Math.round((limit / 1024 / 1024) * 100) / 100;
71
73
  throw new Error(`Remote file size ${fileSizeMB}MB exceeds limit of ${limitMB}MB for ${mediaType} files`);
72
74
  }
73
75
  }
74
76
  return contentLength;
75
77
  }
76
78
  catch (error) {
77
- if (error.message.includes('exceeds limit')) {
79
+ if (error.message.includes("exceeds limit")) {
78
80
  throw error;
79
81
  }
80
- // If we can't get size, assume it's valid but warn
81
- console.warn(`[DetectorMedia] Could not validate size for URL: ${url}`);
82
82
  return 0;
83
83
  }
84
84
  }
@@ -113,11 +113,15 @@ class DetectorMedia {
113
113
  async getMimeTypeFromUrl(url) {
114
114
  try {
115
115
  const res = await axios_1.default.head(url);
116
- const mediaType = this.mapMimeToCategory(res.headers["content-type"]);
117
- return mediaType || null;
116
+ const contentType = res.headers["content-type"];
117
+ const mediaType = this.mapMimeToCategory(contentType);
118
+ return {
119
+ mediaType: mediaType || null,
120
+ mimeType: contentType || null,
121
+ };
118
122
  }
119
123
  catch {
120
- return null;
124
+ return { mediaType: null, mimeType: null };
121
125
  }
122
126
  }
123
127
  async extractFileNameFromUrl(url) {
@@ -135,15 +139,15 @@ class DetectorMedia {
135
139
  */
136
140
  async processMedia(input) {
137
141
  if (this.isRemoteUrl(input)) {
138
- const mediaType = await this.getMimeTypeFromUrl(input);
139
- if (!mediaType)
142
+ const { mediaType, mimeType } = await this.getMimeTypeFromUrl(input);
143
+ if (!mediaType || !mimeType)
140
144
  throw new Error("No se pudo determinar el tipo MIME de la URL remota");
141
145
  // Validate remote file size
142
146
  const size = await this.validateUrlSize(input, mediaType);
143
147
  const fileName = await this.extractFileNameFromUrl(input);
144
148
  return {
145
149
  media: input,
146
- mimeType: mime_types_1.default.lookup(input).toString(),
150
+ mimeType: mimeType,
147
151
  fileName,
148
152
  mediaType,
149
153
  size,
@@ -152,15 +156,20 @@ class DetectorMedia {
152
156
  return this.convertPathToBase64(input);
153
157
  }
154
158
  mapMimeToCategory(mimeType) {
155
- if (mimeType.startsWith("image/"))
159
+ if (!mimeType) {
160
+ return "unknown";
161
+ }
162
+ const normalizedMimeType = mimeType.toLowerCase().split(";")[0].trim();
163
+ if (normalizedMimeType.startsWith("image/"))
156
164
  return "image";
157
- if (mimeType.startsWith("video/"))
165
+ if (normalizedMimeType.startsWith("video/"))
158
166
  return "video";
159
- if (mimeType.startsWith("audio/"))
167
+ if (normalizedMimeType.startsWith("audio/"))
160
168
  return "audio";
161
- if (mimeType.startsWith("application/") || mimeType.startsWith("text/"))
169
+ if (normalizedMimeType.startsWith("application/") ||
170
+ normalizedMimeType.startsWith("text/"))
162
171
  return "document";
163
- return "unknown";
172
+ return "document"; // Default to document instead of unknown for better compatibility
164
173
  }
165
174
  }
166
175
  exports.DetectorMedia = DetectorMedia;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamastudio/sendwave-provider",
3
- "version": "0.0.7-dev",
3
+ "version": "0.0.7-dev1",
4
4
  "description": "Librería para interactuar con Sendwave usando configuración dinámica.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
File without changes