@soyaxell09/zenbot-scraper 1.0.5 → 1.0.7

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.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # @axeldev09/zenbot-scraper
1
+ # @soyaxell09/zenbot-scraper
2
2
 
3
3
  Módulo npm de scrapers y herramientas para bots de WhatsApp. Incluye descargadores, buscadores y utilidades.
4
4
 
5
5
  ## Instalación
6
6
 
7
7
  ```bash
8
- npm install @axeldev09/zenbot-scraper
8
+ npm install @soyaxell09/zenbot-scraper
9
9
  ```
10
10
 
11
11
  ---
@@ -26,7 +26,7 @@ src/
26
26
  ### YouTube
27
27
 
28
28
  ```js
29
- import { ytSearch, ytDownload, ytInfo } from '@axeldev09/zenbot-scraper'
29
+ import { ytSearch, ytDownload, ytInfo } from '@soyaxell09/zenbot-scraper'
30
30
 
31
31
  // Buscar videos
32
32
  const results = await ytSearch('bad bunny', 5)
@@ -41,7 +41,26 @@ const audio = await ytDownload('nicki nicole wapo traketero', 'mp3')
41
41
  ### YouTube v2 (via ytdown.to — más calidades)
42
42
 
43
43
  ```js
44
- import { ytDownloadV2, ytInfoV2, getFileSizeV2 } from '@axeldev09/zenbot-scraper'
44
+ import { ytDownloadV2, ytInfoV2, getFileSizeV2 } from '@soyaxell09/zenbot-scraper'
45
+
46
+ // Ver calidades disponibles
47
+ const info = await ytInfoV2('https://youtu.be/dQw4w9WgXcQ')
48
+ // → { title, uploader, views, thumb, qualities: [{ id, type, quality, size, sizeB, duration }] }
49
+
50
+ // Descargar con calidad específica
51
+ const video = await ytDownloadV2('https://youtu.be/dQw4w9WgXcQ', 'video', '1080p')
52
+ const audio = await ytDownloadV2('https://youtu.be/dQw4w9WgXcQ', 'mp3', '128k')
53
+ // → { title, uploader, views, thumb, type, quality, size, sizeB, duration, url }
54
+
55
+ // Obtener tamaño de un archivo por URL
56
+ const size = await getFileSizeV2('https://example.com/file.mp4')
57
+ // → '14.5 MB'
58
+ ```
59
+
60
+ ### YouTube v2 (via ytdown.to — más calidades)
61
+
62
+ ```js
63
+ import { ytDownloadV2, ytInfoV2, getFileSizeV2 } from '@soyaxell09/zenbot-scraper'
45
64
 
46
65
  // Ver calidades disponibles
47
66
  const info = await ytInfoV2('https://youtu.be/dQw4w9WgXcQ')
@@ -60,7 +79,7 @@ const size = await getFileSizeV2('https://example.com/file.mp4')
60
79
  ### TikTok
61
80
 
62
81
  ```js
63
- import { tiktokDownload, tiktokInfo } from '@axeldev09/zenbot-scraper'
82
+ import { tiktokDownload, tiktokInfo } from '@soyaxell09/zenbot-scraper'
64
83
 
65
84
  const result = await tiktokDownload('https://www.tiktok.com/@user/video/123')
66
85
  // → { nowatermark, watermark, audio, music: { title, author, url }, stats: { plays, likes, comments, shares } }
@@ -69,7 +88,7 @@ const result = await tiktokDownload('https://www.tiktok.com/@user/video/123')
69
88
  ### Facebook
70
89
 
71
90
  ```js
72
- import { fbDownload } from '@axeldev09/zenbot-scraper'
91
+ import { fbDownload } from '@soyaxell09/zenbot-scraper'
73
92
 
74
93
  const result = await fbDownload('https://www.facebook.com/watch?v=123')
75
94
  // → { hd, sd, thumb, title }
@@ -78,7 +97,7 @@ const result = await fbDownload('https://www.facebook.com/watch?v=123')
78
97
  ### Twitter / X
79
98
 
80
99
  ```js
81
- import { tweetInfo, tweetDownload } from '@axeldev09/zenbot-scraper'
100
+ import { tweetInfo, tweetDownload } from '@soyaxell09/zenbot-scraper'
82
101
 
83
102
  // Info completa del tweet
84
103
  const info = await tweetInfo('https://x.com/user/status/123')
@@ -89,10 +108,24 @@ const media = await tweetDownload('https://x.com/user/status/123')
89
108
  // → { id, text, author, videos: [{ type, url, thumbnail, variants }], photos: [{ type, url, width, height }] }
90
109
  ```
91
110
 
111
+ ### Twitter / X
112
+
113
+ ```js
114
+ import { tweetInfo, tweetDownload } from '@soyaxell09/zenbot-scraper'
115
+
116
+ // Info completa del tweet
117
+ const info = await tweetInfo('https://x.com/user/status/123')
118
+ // → { id, text, createdAt, likes, replies, author: { name, username, avatar }, hashtags, medias }
119
+
120
+ // Solo media descargable
121
+ const media = await tweetDownload('https://x.com/user/status/123')
122
+ // → { id, text, author, videos: [{ type, url, thumbnail }], photos: [{ type, url }] }
123
+ ```
124
+
92
125
  ### MediaFire
93
126
 
94
127
  ```js
95
- import { mediafireInfo } from '@axeldev09/zenbot-scraper'
128
+ import { mediafireInfo } from '@soyaxell09/zenbot-scraper'
96
129
 
97
130
  const result = await mediafireInfo('https://www.mediafire.com/file/abc123/archivo.apk/file')
98
131
  // → { key, name, size, download, url }
@@ -101,7 +134,7 @@ const result = await mediafireInfo('https://www.mediafire.com/file/abc123/archiv
101
134
  ### GitHub
102
135
 
103
136
  ```js
104
- import { githubInfo, githubRelease, githubContents, githubSearch } from '@axeldev09/zenbot-scraper'
137
+ import { githubInfo, githubRelease, githubContents, githubSearch } from '@soyaxell09/zenbot-scraper'
105
138
 
106
139
  // Info del repositorio
107
140
  const info = await githubInfo('facebook/react')
@@ -123,7 +156,7 @@ const repos = await githubSearch('whatsapp bot', 'repositories', 5)
123
156
  ### APK (APKPure)
124
157
 
125
158
  ```js
126
- import { apkSearch, apkInfo } from '@axeldev09/zenbot-scraper'
159
+ import { apkSearch, apkInfo } from '@soyaxell09/zenbot-scraper'
127
160
 
128
161
  // Buscar por nombre
129
162
  const results = await apkSearch('whatsapp', 3)
@@ -134,6 +167,21 @@ const info = await apkInfo('com.whatsapp')
134
167
  // → { name, developer, pkg, date, icon, download, dlLinks, url }
135
168
  ```
136
169
 
170
+ ### APK (APKPure)
171
+
172
+ ```js
173
+ import { apkSearch, apkInfo } from '@soyaxell09/zenbot-scraper'
174
+
175
+ // Buscar por nombre
176
+ const results = await apkSearch('whatsapp', 3)
177
+ // → [{ name, developer, pkg, date, icon, appUrl, dlUrl }]
178
+
179
+ // Info por package name
180
+ const info = await apkInfo('com.whatsapp')
181
+ // → { name, developer, pkg, date, icon, download, dlLinks, url }
182
+ ```
183
+
184
+
137
185
  ---
138
186
 
139
187
  ## 🔍 Search
@@ -141,7 +189,7 @@ const info = await apkInfo('com.whatsapp')
141
189
  ### Google (DuckDuckGo)
142
190
 
143
191
  ```js
144
- import { googleSearch } from '@axeldev09/zenbot-scraper'
192
+ import { googleSearch } from '@soyaxell09/zenbot-scraper'
145
193
 
146
194
  const results = await googleSearch('node.js tutorial', 5)
147
195
  // → [{ title, url, snippet }]
@@ -150,7 +198,7 @@ const results = await googleSearch('node.js tutorial', 5)
150
198
  ### Spotify / Deezer
151
199
 
152
200
  ```js
153
- import { spotify } from '@axeldev09/zenbot-scraper'
201
+ import { spotify } from '@soyaxell09/zenbot-scraper'
154
202
 
155
203
  // Buscar tracks
156
204
  const tracks = await spotify('bad bunny', 'tracks', 5)
@@ -163,7 +211,7 @@ const albums = await spotify('bad bunny', 'albums', 3)
163
211
  ### Tenor (GIFs)
164
212
 
165
213
  ```js
166
- import { giphy } from '@axeldev09/zenbot-scraper'
214
+ import { giphy } from '@soyaxell09/zenbot-scraper'
167
215
 
168
216
  const gifs = await giphy('funny cat', 5)
169
217
  // → [{ id, title, url, gif, preview, mp4, width, height }]
@@ -172,7 +220,7 @@ const gifs = await giphy('funny cat', 5)
172
220
  ### Pinterest
173
221
 
174
222
  ```js
175
- import { pinsearch, pinimg, pinvid } from '@axeldev09/zenbot-scraper'
223
+ import { pinsearch, pinimg, pinvid } from '@soyaxell09/zenbot-scraper'
176
224
 
177
225
  // Buscar imágenes por texto
178
226
  const imgs = await pinsearch('anime wallpaper', 5)
@@ -193,10 +241,29 @@ const pinVid = await pinvid('https://www.pinterest.com/pin/123/')
193
241
 
194
242
  ## 🛠️ Tools
195
243
 
244
+ ### YouTube v2 (via ytdown.to — más calidades)
245
+
246
+ ```js
247
+ import { ytDownloadV2, ytInfoV2, getFileSizeV2 } from '@soyaxell09/zenbot-scraper'
248
+
249
+ // Ver calidades disponibles
250
+ const info = await ytInfoV2('https://youtu.be/dQw4w9WgXcQ')
251
+ // → { title, uploader, views, thumb, qualities: [{ id, type, quality, size, sizeB, duration }] }
252
+
253
+ // Descargar con calidad específica
254
+ const video = await ytDownloadV2('https://youtu.be/dQw4w9WgXcQ', 'video', '1080p')
255
+ const audio = await ytDownloadV2('https://youtu.be/dQw4w9WgXcQ', 'mp3', '128k')
256
+ // → { title, uploader, views, thumb, type, quality, size, sizeB, duration, url }
257
+
258
+ // Obtener tamaño de un archivo por URL
259
+ const size = await getFileSizeV2('https://example.com/file.mp4')
260
+ // → '14.5 MB'
261
+ ```
262
+
196
263
  ### TikTok Stalk
197
264
 
198
265
  ```js
199
- import { tiktokStalk } from '@axeldev09/zenbot-scraper'
266
+ import { tiktokStalk } from '@soyaxell09/zenbot-scraper'
200
267
 
201
268
  const profile = await tiktokStalk('charlidamelio')
202
269
  // → { id, username, nickname, bio, avatar, verified, private, bioLink, stats: { followers, following, likes, videos, followersStr, ... }, url }
@@ -205,7 +272,7 @@ const profile = await tiktokStalk('charlidamelio')
205
272
  ### Letras de canciones
206
273
 
207
274
  ```js
208
- import { lyricsSearch, lyricsGet } from '@axeldev09/zenbot-scraper'
275
+ import { lyricsSearch, lyricsGet } from '@soyaxell09/zenbot-scraper'
209
276
 
210
277
  // Buscar por texto libre
211
278
  const results = await lyricsSearch('bad bunny tití me preguntó', 3)
@@ -220,7 +287,7 @@ const song = await lyricsGet('Bad Bunny', 'Tití Me Preguntó')
220
287
  ### Traductor
221
288
 
222
289
  ```js
223
- import { translate, getLangs } from '@axeldev09/zenbot-scraper'
290
+ import { translate, getLangs } from '@soyaxell09/zenbot-scraper'
224
291
 
225
292
  // Traducir (auto-detecta idioma origen)
226
293
  const result = await translate('Hello, how are you?', 'es')
@@ -239,7 +306,7 @@ const langs = getLangs()
239
306
  ### Clima
240
307
 
241
308
  ```js
242
- import { weather } from '@axeldev09/zenbot-scraper'
309
+ import { weather } from '@soyaxell09/zenbot-scraper'
243
310
 
244
311
  const w = await weather('Buenos Aires')
245
312
  // → { location, temp, feelsLike, humidity, wind, windDir, visibility, pressure, uvIndex, description, forecast: [{ date, maxTemp, minTemp, desc, sunrise, sunset }] }
@@ -248,7 +315,7 @@ const w = await weather('Buenos Aires')
248
315
  ### QR
249
316
 
250
317
  ```js
251
- import { qrGenerate, qrRead } from '@axeldev09/zenbot-scraper'
318
+ import { qrGenerate, qrRead } from '@soyaxell09/zenbot-scraper'
252
319
 
253
320
  // Generar QR
254
321
  const qr = await qrGenerate('https://github.com/axeldev09', 300)
@@ -262,7 +329,7 @@ const result = await qrRead('https://example.com/qr.png')
262
329
  ### Acortador de URLs
263
330
 
264
331
  ```js
265
- import { shortenUrl, expandUrl } from '@axeldev09/zenbot-scraper'
332
+ import { shortenUrl, expandUrl } from '@soyaxell09/zenbot-scraper'
266
333
 
267
334
  // Acortar
268
335
  const short = await shortenUrl('https://github.com/axeldev09/zenbot-scraper')
@@ -276,7 +343,7 @@ const expanded = await expandUrl('https://is.gd/xxxxx')
276
343
  ### Noticias
277
344
 
278
345
  ```js
279
- import { news, newsCategories } from '@axeldev09/zenbot-scraper'
346
+ import { news, newsCategories } from '@soyaxell09/zenbot-scraper'
280
347
 
281
348
  // Obtener noticias
282
349
  const n = await news('es', 5)
@@ -290,10 +357,27 @@ const cats = newsCategories()
290
357
  ---
291
358
 
292
359
 
360
+ ### Stickers (StickersCloud)
361
+
362
+ ```js
363
+ import { stickerSearch, stickerPack } from '@soyaxell09/zenbot-scraper'
364
+
365
+ // Buscar packs por texto
366
+ const packs = await stickerSearch('anime', 5)
367
+ // → [{ packId, name, url, preview }]
368
+
369
+ // Obtener stickers de un pack
370
+ const pack = await stickerPack('mochi-mochi-peach-cat-christmas', 10)
371
+ // → { packId, name, url, total, stickers: ['https://img-xx.stickers.cloud/...webp'] }
372
+
373
+ // También acepta URL completa
374
+ const pack2 = await stickerPack('https://stickerscloud.com/en/pack/anime-pack')
375
+ ```
376
+
293
377
  ### Upload (Catbox.moe)
294
378
 
295
379
  ```js
296
- import { upload } from '@axeldev09/zenbot-scraper'
380
+ import { upload } from '@soyaxell09/zenbot-scraper'
297
381
 
298
382
  // Por ruta de archivo local
299
383
  const r1 = await upload('/sdcard/foto.jpg')
@@ -314,16 +398,16 @@ const r3 = await upload(buffer, 'video.mp4')
314
398
 
315
399
  ```js
316
400
  // Todo desde el índice principal
317
- import { ytDownload, tiktokDownload, translate, weather } from '@axeldev09/zenbot-scraper'
401
+ import { ytDownload, tiktokDownload, translate, weather } from '@soyaxell09/zenbot-scraper'
318
402
 
319
403
  // Solo scrapers
320
- import { ytDownload, fbDownload } from '@axeldev09/zenbot-scraper/scrapers'
404
+ import { ytDownload, fbDownload } from '@soyaxell09/zenbot-scraper/scrapers'
321
405
 
322
406
  // Solo search
323
- import { googleSearch, spotify } from '@axeldev09/zenbot-scraper/search'
407
+ import { googleSearch, spotify } from '@soyaxell09/zenbot-scraper/search'
324
408
 
325
409
  // Solo tools
326
- import { translate, weather, news } from '@axeldev09/zenbot-scraper/tools'
410
+ import { translate, weather, news } from '@soyaxell09/zenbot-scraper/tools'
327
411
  ```
328
412
 
329
413
  ---
@@ -339,6 +423,20 @@ import { translate, weather, news } from '@axeldev09/zenbot-scraper/tools'
339
423
 
340
424
  **AxelDev09** — [GitHub](https://github.com/axeldev09)
341
425
 
426
+ ---
427
+
428
+ ## ⭐ Apoyá el proyecto
429
+
430
+ Si este módulo te fue útil, dejá una ⭐ en el repositorio. Le pusimos mucho esfuerzo y tiempo para que funcione bien.
431
+
432
+ **Dejá los créditos** si usás este módulo en tu bot — es lo único que se pide 🙏
433
+
434
+ 📸 Seguime en Instagram: [@axeldev09](https://instagram.com/axeldev09)
435
+
436
+ 📢 Canal oficial de ZenBot en WhatsApp: [Unirse al canal](https://whatsapp.com/channel/0029Vb6OR9O2v1IvoXO5oT2c)
437
+
438
+ ---
439
+
342
440
  ## 📄 Licencia
343
441
 
344
442
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soyaxell09/zenbot-scraper",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Scrapers de descarga y búsqueda para bots de WhatsApp — YouTube, TikTok, Facebook, Twitter, Pinterest, MediaFire, GitHub, APK y más.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -34,7 +34,8 @@
34
34
  "translate",
35
35
  "qr",
36
36
  "news",
37
- "upload"
37
+ "upload",
38
+ "stickers"
38
39
  ],
39
40
  "author": "AxelDev09",
40
41
  "license": "MIT",
package/src/index.js CHANGED
@@ -13,11 +13,11 @@ export { tweetInfo, tweetDownload } from './scrap
13
13
  export { mediafireInfo } from './scrapers/mediafire.js'
14
14
  export { githubInfo, githubRelease, githubContents, githubSearch } from './scrapers/github.js'
15
15
  export { apkSearch, apkInfo } from './scrapers/apk.js'
16
- export { stickerSearch, stickerPack } from './scrapers/stickers.js'
17
16
  export { googleSearch } from './search/google.js'
18
17
  export { spotify } from './search/spotify.js'
19
18
  export { giphy } from './search/giphy.js'
20
19
  export { pinsearch, pinimg, pinvid } from './search/pinterest.js'
20
+ export { stickerSearch } from './search/stickersearch.js'
21
21
  export { tiktokStalk } from './tools/tiktokstalk.js'
22
22
  export { lyricsSearch, lyricsGet } from './tools/lyrics.js'
23
23
  export { translate, getLangs } from './tools/translator.js'
@@ -5,5 +5,4 @@ export { fbDownload } from './faceboo
5
5
  export { tweetInfo, tweetDownload } from './twitter.js'
6
6
  export { mediafireInfo } from './mediafire.js'
7
7
  export { githubInfo, githubRelease, githubContents, githubSearch } from './github.js'
8
- export { apkSearch, apkInfo } from './apk.js'
9
- export { stickerSearch, stickerPack } from './stickers.js'
8
+ export { apkSearch, apkInfo } from './apk.js'
@@ -10,3 +10,4 @@ export { googleSearch } from './google.js'
10
10
  export { spotify } from './spotify.js'
11
11
  export { giphy } from './giphy.js'
12
12
  export { pinsearch, pinimg, pinvid } from './pinterest.js'
13
+ export { stickerSearch } from './stickersearch.js'
@@ -0,0 +1,49 @@
1
+ /*
2
+ * © Created by AxelDev09 🔥
3
+ * GitHub: https://github.com/AxelDev09
4
+ * Instagram: @axeldev09
5
+ * Deja los créditos we 🗣️
6
+ */
7
+
8
+ import axios from 'axios'
9
+ import * as cheerio from 'cheerio'
10
+
11
+ export async function stickerSearch(text, limit = 10) {
12
+ try {
13
+ const response = await axios.get(
14
+ `https://getstickerpack.com/stickers?query=${encodeURIComponent(text)}`
15
+ )
16
+ const $ = cheerio.load(response.data)
17
+ const packs = $('.sticker-pack-block')
18
+
19
+ if (packs.length === 0)
20
+ return { status: false, text: 'ningún resultado encontrado' }
21
+
22
+ const randomIndex = Math.floor(Math.random() * packs.length)
23
+ const selectedPack = $(packs[randomIndex])
24
+ const title = selectedPack.find('.title').text().trim()
25
+ const creator = selectedPack.find('.username').text().trim()
26
+ const packLink = selectedPack.closest('a').attr('href')
27
+
28
+ const packResponse = await axios.get(packLink)
29
+ const packHtml = cheerio.load(packResponse.data)
30
+ const images = packHtml('.sticker-pack-cols img')
31
+ const totalImages = images.length
32
+
33
+ const imageArray = []
34
+ images.each((i, img) => {
35
+ if (i < limit) imageArray.push(packHtml(img).attr('src'))
36
+ })
37
+
38
+ return {
39
+ status: true,
40
+ nombre: title,
41
+ creador: creator,
42
+ total: totalImages,
43
+ fotos: imageArray,
44
+ url: packLink,
45
+ }
46
+ } catch (error) {
47
+ return { status: false, text: 'Error al acceder al sitio' }
48
+ }
49
+ }
package/test.js ADDED
@@ -0,0 +1,4 @@
1
+ import { stickerSearch } from './src/index.js'
2
+
3
+ const result = await stickerSearch('anime')
4
+ console.log(result)
package/test.js.bak ADDED
@@ -0,0 +1,5 @@
1
+ import { stickerSearch } from './src/index.js'
2
+
3
+ const result = await stickerSearch('anime')
4
+ console.log(result.name, result.creator, result.total)
5
+ console.log(result.stickers[0])
@@ -1,101 +0,0 @@
1
- /*
2
- * © Created by AxelDev09 🔥
3
- * GitHub: https://github.com/AxelDev09
4
- * Instagram: @axeldev09
5
- * Deja los créditos we 🗣️
6
- */
7
-
8
- import axios from 'axios'
9
- import * as cheerio from 'cheerio'
10
-
11
- const HEADERS = {
12
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
13
- }
14
- const BASE = 'https://stickerscloud.com'
15
-
16
- function extractPackId(url) {
17
- const m = url.match(/\/pack\/([^/?#]+)/)
18
- return m ? m[1] : null
19
- }
20
-
21
- export async function stickerSearch(query, limit = 10) {
22
- if (!query?.trim()) throw new Error('Query vacío')
23
-
24
- const res = await axios.get(
25
- `${BASE}/search?q=${encodeURIComponent(query)}`,
26
- { headers: HEADERS, timeout: 15000 }
27
- )
28
-
29
- const $ = cheerio.load(res.data)
30
- const results = []
31
- const seen = new Set()
32
-
33
- $('a[href*="/pack/"]').each((_, el) => {
34
- if (results.length >= limit) return false
35
- const href = $(el).attr('href') || ''
36
- const packId = extractPackId(href)
37
- if (!packId || seen.has(packId)) return
38
- seen.add(packId)
39
-
40
- const name = $(el).text().trim() || packId
41
- const preview = $(el).find('img').first().attr('src')
42
- || $(el).closest('[class]').find('img[src*="stickers.cloud"]').first().attr('src')
43
- || ''
44
-
45
- if (!name || name.startsWith('#') === false && name.length < 2) return
46
-
47
- const cleanName = decodeURIComponent(
48
- (name.replace(/^#\d+\s*/, '').trim() || packId)
49
- .replace(/-/g, ' ')
50
- .replace(/\b\w/g, l => l.toUpperCase())
51
- )
52
- results.push({
53
- packId,
54
- name: cleanName,
55
- url: `${BASE}/en/pack/${packId}`,
56
- preview: preview || '',
57
- })
58
- })
59
-
60
- if (!results.length) throw new Error('Sin resultados para: ' + query)
61
- return results
62
- }
63
-
64
- export async function stickerPack(packIdOrUrl, limit = 30) {
65
- const packId = packIdOrUrl.includes('stickerscloud.com')
66
- ? extractPackId(packIdOrUrl)
67
- : packIdOrUrl
68
-
69
- if (!packId) throw new Error('Pack ID o URL inválida')
70
-
71
- const res = await axios.get(
72
- `${BASE}/en/pack/${packId}`,
73
- { headers: HEADERS, timeout: 15000 }
74
- )
75
-
76
- const $ = cheerio.load(res.data)
77
- const stickers = []
78
- const seen = new Set()
79
-
80
- $('img[src*="stickers.cloud"]').each((_, el) => {
81
- if (stickers.length >= limit) return false
82
- const src = $(el).attr('src') || ''
83
- if (!src || seen.has(src)) return
84
- seen.add(src)
85
- stickers.push(src)
86
- })
87
-
88
- const name = decodeURIComponent(packId)
89
- .replace(/-/g, ' ')
90
- .replace(/\b\w/g, l => l.toUpperCase())
91
-
92
- if (!stickers.length) throw new Error('No se encontraron stickers en ese pack')
93
-
94
- return {
95
- packId,
96
- name,
97
- url: `${BASE}/en/pack/${packId}`,
98
- total: stickers.length,
99
- stickers,
100
- }
101
- }