new logs, removing sharp as dependency, stickers are resized

This commit is contained in:
synt-xerror
2026-03-15 03:31:35 -03:00
parent 2d5268bb44
commit 7256d5678c
9 changed files with 1091 additions and 190 deletions

0
deploy.sh Normal file → Executable file
View File

560
package-lock.json generated
View File

@@ -12,6 +12,7 @@
"node-gyp": "^12.2.0",
"node-webpmux": "^3.2.1",
"qrcode-terminal": "^0.12.0",
"wa-sticker-formatter": "^4.4.4",
"whatsapp-web.js": "^1.24.0"
}
},
@@ -126,6 +127,12 @@
"node": ">=18"
}
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
"license": "MIT"
},
"node_modules/@tootallnate/quickjs-emscripten": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
@@ -161,6 +168,18 @@
"node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/agent-base": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
@@ -293,6 +312,15 @@
"license": "MIT",
"optional": true
},
"node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/b4a": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz",
@@ -419,8 +447,7 @@
"url": "https://feross.org/support"
}
],
"license": "MIT",
"optional": true
"license": "MIT"
},
"node_modules/basic-ftp": {
"version": "5.2.0",
@@ -460,7 +487,6 @@
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"license": "MIT",
"optional": true,
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@@ -504,7 +530,6 @@
}
],
"license": "MIT",
"optional": true,
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
@@ -680,6 +705,19 @@
"node": ">=12"
}
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
},
"engines": {
"node": ">=12.5.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -698,6 +736,16 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
"license": "MIT",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"node_modules/compress-commons": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
@@ -807,6 +855,30 @@
}
}
},
"node_modules/decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"license": "MIT",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/degenerator": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
@@ -821,6 +893,15 @@
"node": ">= 14"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/devtools-protocol": {
"version": "0.0.1581282",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz",
@@ -964,6 +1045,24 @@
"node": ">=0.10.0"
}
},
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"license": "MIT",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/events-universal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
@@ -973,6 +1072,15 @@
"bare-events": "^2.7.0"
}
},
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"license": "(MIT OR WTFPL)",
"engines": {
"node": ">=6"
}
},
"node_modules/exponential-backoff": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
@@ -1031,6 +1139,23 @@
}
}
},
"node_modules/file-type": {
"version": "16.5.4",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
"license": "MIT",
"dependencies": {
"readable-web-to-node-stream": "^3.0.0",
"strtok3": "^6.2.4",
"token-types": "^4.1.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
}
},
"node_modules/fluent-ffmpeg": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
@@ -1050,19 +1175,37 @@
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"license": "MIT",
"optional": true
"license": "MIT"
},
"node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -1146,6 +1289,12 @@
"node": ">= 14"
}
},
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"license": "MIT"
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -1241,8 +1390,22 @@
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause",
"optional": true
"license": "BSD-3-Clause"
},
"node_modules/image-size": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
"integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
"license": "MIT",
"dependencies": {
"queue": "6.0.2"
},
"bin": {
"image-size": "bin/image-size.js"
},
"engines": {
"node": ">=16.x"
}
},
"node_modules/import-fresh": {
"version": "3.3.1",
@@ -1285,8 +1448,13 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC",
"optional": true
"license": "ISC"
},
"node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"license": "ISC"
},
"node_modules/ip-address": {
"version": "10.1.0",
@@ -1354,7 +1522,6 @@
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
"license": "MIT",
"optional": true,
"dependencies": {
"universalify": "^2.0.0"
},
@@ -1499,6 +1666,18 @@
"node": ">=10.0.0"
}
},
"node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimatch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
@@ -1517,7 +1696,6 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"optional": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -1663,12 +1841,24 @@
"mkdirp": "bin/cmd.js"
}
},
"node_modules/mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"license": "MIT"
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/napi-build-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
"license": "MIT"
},
"node_modules/negotiator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
@@ -1687,6 +1877,18 @@
"node": ">= 0.4.0"
}
},
"node_modules/node-abi": {
"version": "3.88.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.88.0.tgz",
"integrity": "sha512-At6b4UqIEVudaqPsXjmUO1r/N5BUr4yhDGs5PkBE8/oG5+TfLPhFechiskFsnT6Ql0VfUXbalUUCbfXxtj7K+w==",
"license": "MIT",
"dependencies": {
"semver": "^7.3.5"
},
"engines": {
"node": ">=10"
}
},
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
@@ -1910,6 +2112,19 @@
"node": "20 || >=22"
}
},
"node_modules/peek-readable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -1934,6 +2149,51 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/prebuild-install": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.",
"license": "MIT",
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp-classic": "^0.5.3",
"napi-build-utils": "^2.0.0",
"node-abi": "^3.3.0",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^4.0.0",
"tar-fs": "^2.0.0",
"tunnel-agent": "^0.6.0"
},
"bin": {
"prebuild-install": "bin.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/prebuild-install/node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"license": "ISC"
},
"node_modules/prebuild-install/node_modules/tar-fs": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
}
},
"node_modules/proc-log": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz",
@@ -1943,6 +2203,15 @@
"node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -2041,12 +2310,35 @@
"qrcode-terminal": "bin/qrcode-terminal.js"
}
},
"node_modules/queue": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.3"
}
},
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
},
"bin": {
"rc": "cli.js"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"optional": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -2056,6 +2348,62 @@
"node": ">= 6"
}
},
"node_modules/readable-web-to-node-stream": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz",
"integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==",
"license": "MIT",
"dependencies": {
"readable-stream": "^4.7.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/readable-web-to-node-stream/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/readable-web-to-node-stream/node_modules/readable-stream": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
"license": "MIT",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/readdir-glob": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
@@ -2148,8 +2496,7 @@
"url": "https://feross.org/support"
}
],
"license": "MIT",
"optional": true
"license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
@@ -2177,6 +2524,113 @@
"license": "MIT",
"optional": true
},
"node_modules/sharp": {
"version": "0.30.7",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.7.tgz",
"integrity": "sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.1",
"node-addon-api": "^5.0.0",
"prebuild-install": "^7.1.1",
"semver": "^7.3.7",
"simple-get": "^4.0.1",
"tar-fs": "^2.1.1",
"tunnel-agent": "^0.6.0"
},
"engines": {
"node": ">=12.13.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/sharp/node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"license": "ISC"
},
"node_modules/sharp/node_modules/node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
"license": "MIT"
},
"node_modules/sharp/node_modules/tar-fs": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
}
},
"node_modules/simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/simple-get": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"node_modules/simple-swizzle": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
"integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
},
"node_modules/simple-swizzle/node_modules/is-arrayish": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
"license": "MIT"
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
@@ -2253,7 +2707,6 @@
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"license": "MIT",
"optional": true,
"dependencies": {
"safe-buffer": "~5.2.0"
}
@@ -2284,6 +2737,32 @@
"node": ">=8"
}
},
"node_modules/strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/strtok3": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
"license": "MIT",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"peek-readable": "^4.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/tar": {
"version": "7.5.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz",
@@ -2331,7 +2810,6 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
@@ -2377,6 +2855,23 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/token-types": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
"license": "MIT",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"ieee754": "^1.2.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -2399,6 +2894,18 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
},
"engines": {
"node": "*"
}
},
"node_modules/typed-query-selector": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz",
@@ -2441,7 +2948,6 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 10.0.0"
}
@@ -2502,8 +3008,22 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
"node_modules/wa-sticker-formatter": {
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/wa-sticker-formatter/-/wa-sticker-formatter-4.4.4.tgz",
"integrity": "sha512-tl2tXlu7HEs630+1LcJsdavNGEysyQV7EIe/tFsPJCEd2jteG0nGouWNUglUEjW+bDCZGXw9VpJgUtwVGIKr8w==",
"license": "MIT",
"optional": true
"dependencies": {
"axios": "^0.21.1",
"file-type": "^16.5.3",
"fluent-ffmpeg": "^2.1.2",
"fs-extra": "^10.0.0",
"image-size": "^1.0.0",
"node-webpmux": "^3.1.0",
"sharp": "^0.30.0"
}
},
"node_modules/webdriver-bidi-protocol": {
"version": "0.4.1",

View File

@@ -7,6 +7,7 @@
"node-gyp": "^12.2.0",
"node-webpmux": "^3.2.1",
"qrcode-terminal": "^0.12.0",
"wa-sticker-formatter": "^4.4.4",
"whatsapp-web.js": "^1.24.0"
}
}

View File

@@ -6,49 +6,97 @@ import os from "os";
export const { Client, LocalAuth, MessageMedia } = pkg;
// detecta termux, e usa o executável do chromium do sistema em vez do puppeteer
// ── Logger ──────────────────────────────────────────────────
const c = {
reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
green: "\x1b[32m", yellow: "\x1b[33m", cyan: "\x1b[36m",
red: "\x1b[31m", gray: "\x1b[90m", white: "\x1b[37m",
blue: "\x1b[34m", magenta: "\x1b[35m",
};
const now = () =>
new Date().toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "short" });
export const logger = {
info: (...a) => console.log(`${c.gray}${now()}${c.reset} `, ...a),
success: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.green}${c.reset}`, ...a),
warn: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.yellow}⚠️ ${c.reset}`, ...a),
error: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.red}${c.reset}`, ...a),
bot: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.magenta}🤖${c.reset}`, ...a),
};
// ── Banner ───────────────────────────────────────────────────
function printBanner() {
console.log(`${c.blue}${c.bold}`);
console.log(` _____ _____ _ `);
console.log(`| |___ ___ _ _| __ |___| |_ `);
console.log(`| | | | .'| | | | __ -| . | _|`);
console.log(`|_|_|_|__,|_|_|_ |_____|___|_| `);
console.log(` |___| `);
console.log();
console.log(` website : ${c.reset}${c.cyan}www.mlplovers.com.br/manybot${c.reset}`);
console.log(` repo : ${c.reset}${c.cyan}github.com/synt-xerror/manybot${c.reset}`);
console.log();
console.log(` ${c.bold}✨ A Amizade é Mágica!${c.reset}`);
console.log();
}
// ── Ambiente ─────────────────────────────────────────────────
const isTermux =
(os.platform() === "linux" || os.platform() === "android") &&
process.env.PREFIX?.startsWith("/data/data/com.termux");
logger.info(isTermux
? `Ambiente: ${c.yellow}${c.bold}Termux${c.reset} — usando Chromium do sistema`
: `Ambiente: ${c.blue}${c.bold}${os.platform()}${c.reset} — usando Puppeteer padrão`
);
const puppeteerConfig = isTermux
? {
executablePath: "/data/data/com.termux/files/usr/bin/chromium-browser",
args: [
"--headless=new",
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage",
"--disable-gpu",
"--single-process",
"--no-zygote",
"--disable-software-rasterizer"
]
"--headless=new", "--no-sandbox", "--disable-setuid-sandbox",
"--disable-dev-shm-usage", "--disable-gpu", "--single-process",
"--no-zygote", "--disable-software-rasterizer",
],
}
: {};
// ── Cliente ──────────────────────────────────────────────────
export const client = new Client({
authStrategy: new LocalAuth({ clientId: CLIENT_ID }),
puppeteer: {
headless: true,
...puppeteerConfig
}
puppeteer: { headless: true, ...puppeteerConfig },
});
client.on("qr", qr => {
console.log("[BOT] Escaneie o QR Code");
console.log(qr);
client.on("qr", async qr => {
if (isTermux) {
try {
await QRCode.toFile(QR_PATH, qr, { width: 400 });
logger.bot(`QR Code salvo em: ${c.cyan}${c.bold}${QR_PATH}${c.reset}`);
logger.bot(`Abra com: ${c.yellow}termux-open qr.png${c.reset}`);
} catch (err) {
logger.error("Falha ao salvar QR Code:", err.message);
}
} else {
logger.bot(`Escaneie o ${c.yellow}${c.bold}QR Code${c.reset} abaixo:`);
qrcode.generate(qr, { small: true });
}
});
client.on("ready", () => {
exec("clear");
console.log("[BOT] WhatsApp conectado.");
printBanner();
logger.success(`${c.green}${c.bold}WhatsApp conectado e pronto!${c.reset}`);
logger.info(`Client ID: ${c.cyan}${CLIENT_ID}${c.reset}`);
});
client.on("disconnected", reason => {
console.warn("[BOT] Reconectando:", reason);
setTimeout(() => client.initialize(), 5000);
logger.warn(`Desconectado — motivo: ${c.yellow}${reason}${c.reset}`);
logger.info(`Reconectando em ${c.cyan}5s${c.reset}...`);
setTimeout(() => {
logger.bot("Reinicializando cliente...");
client.initialize();
}, 5000);
});
export default client;

View File

@@ -1,97 +1,256 @@
import pkg from "whatsapp-web.js";
const { MessageMedia } = pkg;
import fs from "fs";
import path from "path";
import os from "os";
import { execFile } from "child_process";
import { promisify } from "util";
import webpmux from "node-webpmux";
import { botMsg } from "../utils/botMsg.js";
import pkg from "whatsapp-web.js";
import { createSticker } from "wa-sticker-formatter";
import { client } from "../client/whatsappClient.js";
import { botMsg } from "../utils/botMsg.js";
import { emptyFolder } from "../utils/file.js";
import { stickerSessions } from "./index.js";
const exec = promisify(execFile);
const { MessageMedia } = pkg;
const execFileAsync = promisify(execFile);
export async function gerarSticker(msg) {
const DOWNLOADS_DIR = path.resolve("downloads");
const FFMPEG = os.platform() === "win32"
? ".\\bin\\ffmpeg.exe"
: "./bin/ffmpeg";
if (!msg.hasMedia) {
await msg.reply(botMsg("Envie uma imagem junto com o comando: `!figurinha`."));
const MAX_STICKER_SIZE = 900 * 1024;
const SESSION_TIMEOUT = 2 * 60 * 1000;
const MAX_MEDIA = 10;
// ───────────────── Helpers ─────────────────
function ensureDownloadsDir() {
if (!fs.existsSync(DOWNLOADS_DIR)) {
fs.mkdirSync(DOWNLOADS_DIR, { recursive: true });
}
}
function cleanupFiles(...files) {
for (const f of files) {
if (f && fs.existsSync(f)) fs.unlinkSync(f);
}
}
// Converte vídeo/gif → GIF 512x512 com paleta preservada
async function convertVideoToGif(inputPath, outputPath, fps = 12) {
const clampedFps = Math.min(fps, 12);
const filter = [
`fps=${clampedFps},scale=512:512:flags=lanczos,split[s0][s1]`,
`[s0]palettegen=max_colors=256:reserve_transparent=1[p]`,
`[s1][p]paletteuse=dither=bayer`
].join(";");
await execFileAsync(FFMPEG, [
"-i", inputPath,
"-filter_complex", filter, // <-- era -vf, tem que ser -filter_complex pro split funcionar
"-loop", "0",
"-y",
outputPath
]);
}
// Força imagem estática para 512x512
async function resizeToSticker(inputPath, outputPath) {
await execFileAsync(FFMPEG, [
"-i", inputPath,
"-vf", "scale=512:512:flags=lanczos", // lanczos = melhor qualidade no resize
"-y",
outputPath
]);
}
async function createStickerWithFallback(stickerInputPath, isAnimated) {
const qualities = [80, 60, 40, 20];
for (const quality of qualities) {
const buffer = await createSticker(
fs.readFileSync(stickerInputPath),
{
pack: "Criada por ManyBot\n",
author: "\ngithub.com/synt-xerror/manybot",
type: isAnimated ? "FULL" : "STATIC",
categories: ["🤖"],
quality,
}
);
if (buffer.length <= MAX_STICKER_SIZE) {
return buffer;
}
}
throw new Error("Não foi possível reduzir o sticker para menos de 900 KB.");
}
// ───────────────── Sessão ─────────────────
export function iniciarSessao(chatId, author) {
if (stickerSessions.has(chatId)) return false;
const timeout = setTimeout(() => {
stickerSessions.delete(chatId);
client.sendMessage(chatId, botMsg("Sessão de figurinha expirou."));
}, SESSION_TIMEOUT);
stickerSessions.set(chatId, {
author,
medias: [],
timeout
});
return true;
}
// ───────────────── Coleta de mídia ─────────────────
export async function coletarMidia(msg) {
const chat = await msg.getChat();
const chatId = chat.id._serialized;
const session = stickerSessions.get(chatId);
if (!session) return;
const sender = msg.author || msg.from;
if (sender !== session.author) return;
if (!msg.hasMedia) return;
const media = await msg.downloadMedia();
if (!media) return;
const isGif =
media.mimetype === "image/gif" ||
(media.mimetype === "video/mp4" && msg._data?.isGif);
if (
!media.mimetype ||
(!media.mimetype.startsWith("image/") &&
!media.mimetype.startsWith("video/") &&
!isGif)
) {
return;
}
const media = await msg.downloadMedia();
const ext = media.mimetype.split("/")[1];
if (session.medias.length < MAX_MEDIA) {
session.medias.push(media);
}
}
// ───────────────── Criar stickers ─────────────────
export async function gerarSticker(msg, chatId) {
const sender = msg.author || msg.from;
const session = stickerSessions.get(chatId);
if (!session) {
return msg.reply(botMsg("Nenhuma sessão de figurinha ativa."));
}
if (session.author !== sender) {
return msg.reply(botMsg("Apenas quem iniciou a sessão pode criar as figurinhas."));
}
const medias = session.medias;
if (!medias.length) {
return msg.reply(botMsg("Nenhuma imagem recebida."));
}
clearTimeout(session.timeout);
console.log("midias:", medias.length);
await msg.reply(botMsg("Aguarde! Estou criando as suas figurinhas..."));
ensureDownloadsDir();
for (const media of medias) {
try {
const ext = media.mimetype.split("/")[1];
const isVideo = media.mimetype.startsWith("video/");
const isGif = media.mimetype === "image/gif";
const isAnimated = isVideo || isGif;
const id = Date.now() + "-" + Math.random().toString(36).slice(2);
const inputPath = path.join(DOWNLOADS_DIR, `${id}.${ext}`);
const gifPath = path.join(DOWNLOADS_DIR, `${id}.gif`);
const resizedPath = path.join(DOWNLOADS_DIR, `${id}-scaled.${ext}`);
fs.writeFileSync(inputPath, Buffer.from(media.data, "base64"));
// LOG 1 — arquivo de entrada
const inputSize = fs.statSync(inputPath).size;
console.log(`[1] mimetype: ${media.mimetype} | isAnimated: ${isAnimated} | inputPath: ${inputPath} | size: ${inputSize} bytes`);
let stickerInputPath = inputPath;
if (isAnimated) {
console.log("[2] Convertendo para GIF...");
await convertVideoToGif(inputPath, gifPath, isVideo ? 12 : 24);
// LOG 2 — gif gerado
if (fs.existsSync(gifPath)) {
console.log(`[2] GIF gerado: ${fs.statSync(gifPath).size} bytes`);
} else {
console.error("[2] ERRO: gifPath não foi criado pelo ffmpeg!");
}
stickerInputPath = gifPath;
} else {
console.log("[2] Redimensionando imagem estática...");
await resizeToSticker(inputPath, resizedPath);
if (fs.existsSync(resizedPath)) {
console.log(`[2] Resized gerado: ${fs.statSync(resizedPath).size} bytes`);
} else {
console.error("[2] ERRO: resizedPath não foi criado!");
}
stickerInputPath = resizedPath;
}
// LOG 3 — antes de criar o sticker
console.log(`[3] stickerInputPath: ${stickerInputPath} | exists: ${fs.existsSync(stickerInputPath)} | size: ${fs.existsSync(stickerInputPath) ? fs.statSync(stickerInputPath).size : "N/A"} bytes`);
const stickerBuffer = await createStickerWithFallback(stickerInputPath, isAnimated);
// LOG 4 — sticker gerado
console.log(`[4] Sticker buffer: ${stickerBuffer.length} bytes`);
const stickerMedia = new MessageMedia("image/webp", stickerBuffer.toString("base64"));
await client.sendMessage(chatId, stickerMedia, { sendMediaAsSticker: true });
cleanupFiles(inputPath, gifPath, resizedPath);
} catch (err) {
console.error("Erro ao gerar sticker:", err);
await msg.reply(botMsg("Erro ao gerar uma das figurinhas."));
}
}
await msg.reply(botMsg("Figurinhas geradas com sucesso!"));
stickerSessions.delete(chatId);
emptyFolder("downloads");
const input = `downloads/${msg.id._serialized}.${ext}`;
const output = `downloads/${msg.id._serialized}.webp`;
fs.writeFileSync(input, Buffer.from(media.data, "base64"));
const so = os.platform();
const cmd = so === "win32" ? ".\\bin\\ffmpeg.exe" : "./bin/ffmpeg";
await exec(cmd, [
"-y",
"-i", input,
"-vf",
"scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=0x00000000",
"-vcodec", "libwebp",
"-lossless", "1",
"-qscale", "75",
"-preset", "default",
"-an",
"-vsync", "0",
output
]);
const img = new webpmux.Image();
await img.load(output);
const metadata = {
"sticker-pack-id": "manybot",
"sticker-pack-name": "Feito por ManyBot",
"sticker-pack-publisher": "My Little Pony Lovers",
"emojis": ["🤖"]
};
const json = Buffer.from(JSON.stringify(metadata));
const exif = Buffer.concat([
Buffer.from([
0x49,0x49,0x2A,0x00,
0x08,0x00,0x00,0x00,
0x01,0x00,
0x41,0x57,
0x07,0x00
]),
Buffer.from([
json.length & 0xff,
(json.length >> 8) & 0xff,
(json.length >> 16) & 0xff,
(json.length >> 24) & 0xff
]),
json
]);
img.exif = exif;
await img.save(output);
const data = fs.readFileSync(output);
const sticker = new MessageMedia(
"image/webp",
data.toString("base64"),
"sticker.webp"
);
const chat = await msg.getChat();
await client.sendMessage(
chat.id._serialized,
sticker,
{ sendMediaAsSticker: true }
);
fs.unlinkSync(input);
fs.unlinkSync(output);
}

View File

@@ -1,45 +1,90 @@
import { enqueueDownload } from "../download/queue.js";
import { gerarSticker } from "./figurinha.js";
import { iniciarSessao, gerarSticker } from "./figurinha.js";
import { botMsg } from "../utils/botMsg.js";
import { iniciarJogo, pararJogo, processarJogo } from "../games/adivinhacao.js";
import { iniciarJogo, pararJogo } from "../games/adivinhacao.js";
import { processarInfo } from "./info.js";
export const stickerSessions = new Map();
const c = {
reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
green: "\x1b[32m", yellow: "\x1b[33m", cyan: "\x1b[36m",
red: "\x1b[31m", gray: "\x1b[90m",
};
const now = () =>
new Date().toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "medium" });
const log = {
cmd: (cmd, ...a) => console.log(`${c.gray}${now()}${c.reset} ${c.cyan}⚙️ ${c.bold}${cmd}${c.reset}`, ...a),
ok: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.green}${c.reset}`, ...a),
warn: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.yellow}⚠️ ${c.reset}`, ...a),
error: (...a) => console.log(`${c.gray}${now()}${c.reset} ${c.red}${c.reset}`, ...a),
};
export async function processarComando(msg, chat, chatId) {
const tokens = msg.body.trim().split(/\s+/);
const cmd = tokens[0]?.toLowerCase();
if (!cmd?.startsWith("!") && cmd !== "a") return;
log.cmd(cmd);
try {
switch(tokens[0]) {
switch (cmd) {
case "!many":
await chat.sendMessage(botMsg(
"Comandos:\n\n"+
"- `!ping`\n"+
"- `!video <link>`\n"+
"- `!audio <link>`\n"+
"- `!figurinha`\n"+
"- `!adivinhação começar|parar`\n"+
"Comandos:\n\n" +
"- `!ping`\n" +
"- `!video <link>`\n" +
"- `!audio <link>`\n" +
"- `!figurinha`\n" +
"- `!adivinhação começar|parar`\n" +
"- `!info <comando>`"
));
break;
case "!ping":
await msg.reply(botMsg("pong 🏓"));
log.ok("pong enviado");
break;
case "!video":
if (!tokens[1]) return;
if (!tokens[1]) { log.warn("!video sem link"); return; }
await msg.reply(botMsg("⏳ Baixando vídeo..."));
enqueueDownload("video", tokens[1], msg, chatId);
log.ok("vídeo enfileirado →", tokens[1]);
break;
case "!audio":
if (!tokens[1]) return;
if (!tokens[1]) { log.warn("!audio sem link"); return; }
await msg.reply(botMsg("⏳ Baixando áudio..."));
enqueueDownload("audio", tokens[1], msg, chatId);
log.ok("áudio enfileirado →", tokens[1]);
break;
case "!figurinha":
await gerarSticker(msg);
const author = msg.author || msg.from;
if (tokens[1] === "criar") {
await gerarSticker(msg, chatId);
} else {
if (stickerSessions.has(chatId)) {
return msg.reply("Já existe uma sessão ativa.");
}
iniciarSessao(chatId, author);
await msg.reply(
`Sessão de figurinha iniciada por @${author.split("@")[0]}. Envie no máximo 10 imagens, quando estiver pronto mande \`!figurinha criar\``,
null,
{ mentions: [author] }
);
}
break;
case "!adivinhação":
if (!tokens[1]) {
await chat.sendMessage(botMsg("`!adivinhação começar`\n`!adivinhação parar`"));
@@ -48,10 +93,13 @@ export async function processarComando(msg, chat, chatId) {
if (tokens[1] === "começar") {
iniciarJogo();
await chat.sendMessage(botMsg("Jogo iniciado! Tente adivinhar o número de 1 a 100."));
}
if (tokens[1] === "parar") {
log.ok("jogo iniciado");
} else if (tokens[1] === "parar") {
pararJogo();
await chat.sendMessage(botMsg("Jogo parado."));
log.ok("jogo parado");
} else {
log.warn("!adivinhação — subcomando desconhecido:", tokens[1]);
}
break;
@@ -59,13 +107,23 @@ export async function processarComando(msg, chat, chatId) {
if (!tokens[1]) {
await chat.sendMessage(botMsg("Use:\n`!info <comando>`"));
return;
} else {
processarInfo(tokens[1], chat);
}
processarInfo(tokens[1], chat);
log.ok("info →", tokens[1]);
break;
case "!obrigado":
case "!valeu":
case "!brigado":
await msg.reply(botMsg("Por nada!"));
break;
case "a":
if (!tokens[1]) await msg.reply(botMsg("B"));
break;
}
} catch(err) {
console.error(err);
await chat.sendMessage(botMsg("Erro:\n`"+err.message+"`"));
} catch (err) {
log.error("Falha em", cmd, "—", err.message);
await chat.sendMessage(botMsg("Erro:\n`" + err.message + "`"));
}
}

View File

@@ -23,6 +23,7 @@ export async function get_video(url, id) {
'--fragment-retries', '5',
'--socket-timeout', '15',
'--sleep-interval', '1', '--max-sleep-interval', '4',
'--no-playlist',
url
];

View File

@@ -1,29 +1,134 @@
console.log("Iniciando...");
import client from "./client/whatsappClient.js";
import { CHATS } from "./config.js";
import { CHATS, BOT_PREFIX } from "./config.js"; // <- importar PREFIX
import { processarComando } from "./commands/index.js";
import { coletarMidia } from "./commands/figurinha.js";
import { processarJogo } from "./games/adivinhacao.js";
import { getChatId } from "./utils/getChatId.js";
// ── Cores ────────────────────────────────────────────────────
const c = {
reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
green: "\x1b[32m", yellow: "\x1b[33m", cyan: "\x1b[36m",
red: "\x1b[31m", gray: "\x1b[90m", white: "\x1b[37m",
blue: "\x1b[34m", magenta: "\x1b[35m",
};
const now = () =>
new Date().toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "medium" });
const SEP = `${c.gray}${"─".repeat(52)}${c.reset}`;
// ── Logger ───────────────────────────────────────────────────
const logger = {
info: (...a) => console.log(`${SEP}\n${c.gray}[${now()}]${c.reset} ${c.cyan}INFO ${c.reset}`, ...a),
success: (...a) => console.log(`${c.gray}[${now()}]${c.reset} ${c.green}OK ${c.reset}`, ...a),
warn: (...a) => console.log(`${c.gray}[${now()}]${c.reset} ${c.yellow}WARN ${c.reset}`, ...a),
error: (...a) => console.log(`${c.gray}[${now()}]${c.reset} ${c.red}ERROR ${c.reset}`, ...a),
msg: async (chatName, chatId, from, body, msg = {}) => {
const number = String(from).split("@")[0];
const isGroup = /@g\.us$/.test(chatId);
let name = msg?.notifyName || number;
try {
if (typeof client?.getContactById === "function") {
const contact = await client.getContactById(from);
name = contact?.pushname || contact?.formattedName || name;
}
} catch {}
const type = msg?.type || "text";
const typeLabel =
type === "sticker" ? `${c.magenta}sticker${c.reset}` :
type === "image" ? `${c.cyan}imagem${c.reset}` :
type === "video" ? `${c.cyan}vídeo${c.reset}` :
type === "audio" ? `${c.cyan}áudio${c.reset}` :
type === "ptt" ? `${c.cyan}áudio${c.reset}` :
type === "document" ? `${c.cyan}arquivo${c.reset}` :
type === "chat" ? `${c.white}texto${c.reset}` :
`${c.gray}${type}${c.reset}`;
const isCommand = body?.trimStart().startsWith(BOT_PREFIX);
const context = isGroup
? `${c.bold}${chatName}${c.reset} ${c.dim}(grupo)${c.reset}`
: `${c.bold}${chatName}${c.reset} ${c.dim}(privado)${c.reset}`;
const bodyPreview = body?.trim()
? `${isCommand ? c.yellow : c.green}"${body.length > 80 ? body.slice(0, 80) + "…" : body}"${c.reset}`
: `${c.dim}<${typeLabel}>${c.reset}`;
// Resolve reply
let replyLine = "";
if (msg?.hasQuotedMsg) {
try {
const quoted = await msg.getQuotedMessage();
const quotedNumber = String(quoted.from).split("@")[0];
let quotedName = quotedNumber;
try {
const quotedContact = await client.getContactById(quoted.from);
quotedName = quotedContact?.pushname || quotedContact?.formattedName || quotedNumber;
} catch {}
const quotedPreview = quoted.body?.trim()
? `"${quoted.body.length > 60 ? quoted.body.slice(0, 60) + "…" : quoted.body}"`
: `<${quoted.type}>`;
replyLine =
`\n${c.gray} ↩ Para: ${c.reset}${c.white}${quotedName}${c.reset} ${c.dim}+${quotedNumber}${c.reset}` +
`\n${c.gray} ↩ Msg: ${c.reset}${c.dim}${quotedPreview}${c.reset}`;
} catch {}
}
console.log(
`${SEP}\n` +
`${c.gray}[${now()}]${c.reset} ${c.cyan}MSG ${c.reset}${context}\n` +
`${c.gray} De: ${c.reset}${c.white}${name}${c.reset} ${c.dim}+${number}${c.reset}\n` +
`${c.gray} Tipo: ${c.reset}${typeLabel}${isCommand ? ` ${c.yellow}(bot)${c.reset}` : ""}\n` +
`${c.gray} Text: ${c.reset}${bodyPreview}` +
replyLine
);
},
cmd: (cmd, extra = "") =>
console.log(
`${c.gray}[${now()}]${c.reset} ${c.yellow}CMD ${c.reset}` +
`${c.bold}${cmd}${c.reset}` +
(extra ? ` ${c.dim}${extra}${c.reset}` : "")
),
done: (cmd, detail = "") =>
console.log(
`${c.gray}[${now()}]${c.reset} ${c.green}DONE ${c.reset}` +
`${c.dim}${cmd}${c.reset}` +
(detail ? `${detail}` : "")
),
};
export { logger };
// ── Boot ─────────────────────────────────────────────────────
logger.info("Iniciando ManyBot...");
client.on("message_create", async msg => {
try {
const chat = await msg.getChat();
const chatId = getChatId(chat);
if (!CHATS.includes(chatId)) return;
console.log("==================================");
console.log(`CHAT NAME : ${chat.name || chat.id.user}`);
console.log(`CHAT ID : ${chatId}`);
console.log(`FROM : ${msg.from}`);
console.log(`BODY : ${msg.body}`);
console.log("==================================\n");
await logger.msg(chat.name || chat.id.user, chatId, msg.from, msg.body, msg);
await coletarMidia(msg);
await processarComando(msg, chat, chatId);
await processarJogo(msg, chat);
} catch(err) {
console.error("[ERRO]", err);
logger.done("message_create", `de +${String(msg.from).split("@")[0]}`);
} catch (err) {
logger.error(
`Falha ao processar — ${err.message}`,
`\n Stack: ${err.stack?.split("\n")[1]?.trim() ?? ""}`
);
}
});
client.initialize();
logger.info("Cliente inicializado. Aguardando conexão com WhatsApp...");

9
todo.txt Normal file
View File

@@ -0,0 +1,9 @@
Deixar o log mais claro, permanecendo limpo e simples
Possibilidade de tirar fundo de figurinhas
Salvar mensagens num banco de dados
Mudar a licença para GPLv3
Possibilidade de baixar playlists do youtube