@mbermeo/wa-blaster 0.1.0

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 (82) hide show
  1. package/README.md +1060 -0
  2. package/bin/wa-blast.js +124 -0
  3. package/dist/node20/cli/index.js +2 -0
  4. package/dist/node20/cli/index.jsc +0 -0
  5. package/dist/node20/cli/lib.js +2 -0
  6. package/dist/node20/cli/lib.jsc +0 -0
  7. package/dist/node20/mcp/index.js +2 -0
  8. package/dist/node20/mcp/index.jsc +0 -0
  9. package/dist/node20/src/accountManager.js +2 -0
  10. package/dist/node20/src/accountManager.jsc +0 -0
  11. package/dist/node20/src/campaignRunner.js +2 -0
  12. package/dist/node20/src/campaignRunner.jsc +0 -0
  13. package/dist/node20/src/db.js +2 -0
  14. package/dist/node20/src/db.jsc +0 -0
  15. package/dist/node20/src/paths.js +2 -0
  16. package/dist/node20/src/paths.jsc +0 -0
  17. package/dist/node20/src/routes/accounts.js +2 -0
  18. package/dist/node20/src/routes/accounts.jsc +0 -0
  19. package/dist/node20/src/routes/campaigns.js +2 -0
  20. package/dist/node20/src/routes/campaigns.jsc +0 -0
  21. package/dist/node20/src/routes/inbound.js +2 -0
  22. package/dist/node20/src/routes/inbound.jsc +0 -0
  23. package/dist/node20/src/server.js +2 -0
  24. package/dist/node20/src/server.jsc +0 -0
  25. package/dist/node20/src/utils/csvParser.js +2 -0
  26. package/dist/node20/src/utils/csvParser.jsc +0 -0
  27. package/dist/node20/src/utils/templateEngine.js +2 -0
  28. package/dist/node20/src/utils/templateEngine.jsc +0 -0
  29. package/dist/node22/cli/index.js +2 -0
  30. package/dist/node22/cli/index.jsc +0 -0
  31. package/dist/node22/cli/lib.js +2 -0
  32. package/dist/node22/cli/lib.jsc +0 -0
  33. package/dist/node22/mcp/index.js +2 -0
  34. package/dist/node22/mcp/index.jsc +0 -0
  35. package/dist/node22/src/accountManager.js +2 -0
  36. package/dist/node22/src/accountManager.jsc +0 -0
  37. package/dist/node22/src/campaignRunner.js +2 -0
  38. package/dist/node22/src/campaignRunner.jsc +0 -0
  39. package/dist/node22/src/db.js +2 -0
  40. package/dist/node22/src/db.jsc +0 -0
  41. package/dist/node22/src/paths.js +2 -0
  42. package/dist/node22/src/paths.jsc +0 -0
  43. package/dist/node22/src/routes/accounts.js +2 -0
  44. package/dist/node22/src/routes/accounts.jsc +0 -0
  45. package/dist/node22/src/routes/campaigns.js +2 -0
  46. package/dist/node22/src/routes/campaigns.jsc +0 -0
  47. package/dist/node22/src/routes/inbound.js +2 -0
  48. package/dist/node22/src/routes/inbound.jsc +0 -0
  49. package/dist/node22/src/server.js +2 -0
  50. package/dist/node22/src/server.jsc +0 -0
  51. package/dist/node22/src/utils/csvParser.js +2 -0
  52. package/dist/node22/src/utils/csvParser.jsc +0 -0
  53. package/dist/node22/src/utils/templateEngine.js +2 -0
  54. package/dist/node22/src/utils/templateEngine.jsc +0 -0
  55. package/dist/node24/cli/index.js +2 -0
  56. package/dist/node24/cli/index.jsc +0 -0
  57. package/dist/node24/cli/lib.js +2 -0
  58. package/dist/node24/cli/lib.jsc +0 -0
  59. package/dist/node24/mcp/index.js +2 -0
  60. package/dist/node24/mcp/index.jsc +0 -0
  61. package/dist/node24/src/accountManager.js +2 -0
  62. package/dist/node24/src/accountManager.jsc +0 -0
  63. package/dist/node24/src/campaignRunner.js +2 -0
  64. package/dist/node24/src/campaignRunner.jsc +0 -0
  65. package/dist/node24/src/db.js +2 -0
  66. package/dist/node24/src/db.jsc +0 -0
  67. package/dist/node24/src/paths.js +2 -0
  68. package/dist/node24/src/paths.jsc +0 -0
  69. package/dist/node24/src/routes/accounts.js +2 -0
  70. package/dist/node24/src/routes/accounts.jsc +0 -0
  71. package/dist/node24/src/routes/campaigns.js +2 -0
  72. package/dist/node24/src/routes/campaigns.jsc +0 -0
  73. package/dist/node24/src/routes/inbound.js +2 -0
  74. package/dist/node24/src/routes/inbound.jsc +0 -0
  75. package/dist/node24/src/server.js +2 -0
  76. package/dist/node24/src/server.jsc +0 -0
  77. package/dist/node24/src/utils/csvParser.js +2 -0
  78. package/dist/node24/src/utils/csvParser.jsc +0 -0
  79. package/dist/node24/src/utils/templateEngine.js +2 -0
  80. package/dist/node24/src/utils/templateEngine.jsc +0 -0
  81. package/package.json +44 -0
  82. package/public/index.html +2459 -0
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Entry point único para `npx @scope/wa-blast`.
6
+ *
7
+ * Despacha a los tres subcomandos principales:
8
+ * serve → arranca Express + dashboard
9
+ * mcp → arranca el MCP stdio server
10
+ * <otro> → cae al CLI (accounts/campaigns/inbound)
11
+ *
12
+ * Auto-detección dev vs compilado:
13
+ * - Si existe ../dist/src/server.js (stub de bytenode) → usamos dist/
14
+ * (caso del paquete publicado en npm)
15
+ * - Si no existe → usamos src/ y cli/ directos (caso del checkout de desarrollo)
16
+ *
17
+ * IMPORTANTE: los flags globales --data-dir y --url deben parsearse ANTES
18
+ * de requerir cualquier módulo que toque paths.js / better-sqlite3, porque
19
+ * WA_BLAST_HOME se lee una sola vez al cargar el módulo.
20
+ */
21
+
22
+ const fs = require('fs');
23
+ const path = require('path');
24
+
25
+ // ─── Pre-parseo de --data-dir y --url ────────────────────────────────────────
26
+ // Minimal, antes de cargar nada más. El CLI/lib reparsea normalmente después.
27
+ (function preApplyGlobalFlags() {
28
+ const argv = process.argv.slice(2);
29
+ for (let i = 0; i < argv.length - 1; i++) {
30
+ if (argv[i] === '--data-dir') {
31
+ process.env.WA_BLAST_HOME = path.resolve(argv[i + 1]);
32
+ } else if (argv[i] === '--url') {
33
+ process.env.WA_BLAST_URL = argv[i + 1];
34
+ }
35
+ }
36
+ })();
37
+
38
+ // ─── Resolución dev vs compilado + target por versión de Node ───────────────
39
+
40
+ const DIST_DIR = path.join(__dirname, '..', 'dist');
41
+ const NODE_MAJOR = parseInt(process.versions.node.split('.')[0], 10);
42
+
43
+ // Si existe src/server.js al lado del paquete, estamos en checkout de dev
44
+ const DEV_SRC = path.join(__dirname, '..', 'src', 'server.js');
45
+ const IS_DEV_CHECKOUT = fs.existsSync(DEV_SRC);
46
+
47
+ function resolveDistTarget() {
48
+ if (!fs.existsSync(DIST_DIR)) return null;
49
+ // Primero: dist/node<MAJOR>/ para la versión actual
50
+ const preferred = path.join(DIST_DIR, `node${NODE_MAJOR}`);
51
+ if (fs.existsSync(path.join(preferred, 'src', 'server.js'))) {
52
+ return preferred;
53
+ }
54
+ // No hay bytecode para esta versión. Si estamos en dev, silenciosamente
55
+ // volvemos al source. Si es un paquete publicado (sin src/), fallamos
56
+ // con un mensaje claro listando las versiones disponibles.
57
+ if (IS_DEV_CHECKOUT) return null;
58
+
59
+ const available = fs.readdirSync(DIST_DIR)
60
+ .filter(d => d.startsWith('node') && fs.existsSync(path.join(DIST_DIR, d, 'src', 'server.js')));
61
+ process.stderr.write(
62
+ `[wa-blast] Este paquete no incluye bytecode para Node ${NODE_MAJOR}.x.\n` +
63
+ `[wa-blast] Versiones soportadas: ${available.map(v => v.replace('node', '')).join(', ') || '(ninguna)'}\n` +
64
+ `[wa-blast] Instalá una versión compatible de Node (p. ej. con nvm) y reintentá.\n`
65
+ );
66
+ process.exit(1);
67
+ }
68
+
69
+ const DIST_TARGET = resolveDistTarget();
70
+ const USE_DIST = DIST_TARGET !== null;
71
+
72
+ if (USE_DIST) {
73
+ // En modo compilado, los stubs .js requieren bytenode para cargar .jsc
74
+ require('bytenode');
75
+ }
76
+
77
+ function loadModule(distPath, devPath) {
78
+ const target = USE_DIST
79
+ ? path.join(DIST_TARGET, distPath)
80
+ : path.join(__dirname, '..', devPath);
81
+ require(target);
82
+ }
83
+
84
+ // ─── Despacho de subcomando ──────────────────────────────────────────────────
85
+
86
+ // Encontrar el primer positional que no sea un flag ni su valor
87
+ function firstPositional(argv) {
88
+ for (let i = 0; i < argv.length; i++) {
89
+ const a = argv[i];
90
+ if (a.startsWith('--')) {
91
+ // si el siguiente no es otro flag, es el valor de este
92
+ if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) i++;
93
+ continue;
94
+ }
95
+ return a;
96
+ }
97
+ return undefined;
98
+ }
99
+
100
+ const argvSlice = process.argv.slice(2);
101
+
102
+ // --version / -v antes del despacho normal
103
+ if (argvSlice.includes('--version') || argvSlice.includes('-v')) {
104
+ const pkg = require(path.join(__dirname, '..', 'package.json'));
105
+ process.stdout.write(`${pkg.name} ${pkg.version}\n`);
106
+ process.exit(0);
107
+ }
108
+
109
+ const cmd = firstPositional(argvSlice);
110
+
111
+ switch (cmd) {
112
+ case 'serve':
113
+ loadModule('src/server.js', 'src/server.js');
114
+ break;
115
+
116
+ case 'mcp':
117
+ loadModule('mcp/index.js', 'mcp/index.js');
118
+ break;
119
+
120
+ default:
121
+ // Todo lo demás lo maneja el CLI (incluido --help, accounts, campaigns, inbound)
122
+ loadModule('cli/index.js', 'cli/index.js');
123
+ break;
124
+ }
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./index.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./lib.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./index.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./accountManager.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./campaignRunner.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./db.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./paths.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./accounts.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./campaigns.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./inbound.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./server.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./csvParser.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./templateEngine.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./index.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./lib.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./index.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./accountManager.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./campaignRunner.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./db.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./paths.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./accounts.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./campaigns.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./inbound.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./server.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./csvParser.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./templateEngine.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./index.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./lib.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./index.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./accountManager.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./campaignRunner.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./db.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./paths.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./accounts.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./campaigns.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./inbound.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./server.jsc');
Binary file
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./csvParser.jsc');
@@ -0,0 +1,2 @@
1
+ require('bytenode');
2
+ module.exports = require('./templateEngine.jsc');
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@mbermeo/wa-blaster",
3
+ "version": "0.1.0",
4
+ "description": "Sistema de mensajes masivos por WhatsApp con CLI y MCP server para agentes",
5
+ "main": "bin/wa-blast.js",
6
+ "bin": {
7
+ "wa-blast": "./bin/wa-blast.js"
8
+ },
9
+ "engines": {
10
+ "node": ">=20.0.0"
11
+ },
12
+ "files": [
13
+ "bin/",
14
+ "dist/",
15
+ "public/",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "start": "node bin/wa-blast.js serve",
21
+ "dev": "node --watch src/server.js",
22
+ "cli": "node bin/wa-blast.js",
23
+ "build": "node scripts/build.js",
24
+ "build:all": "bash scripts/build-all.sh",
25
+ "prepublishOnly": "node scripts/prepublish-check.js",
26
+ "test": "node --test test/**/*.test.js"
27
+ },
28
+ "dependencies": {
29
+ "@modelcontextprotocol/sdk": "^1.29.0",
30
+ "better-sqlite3": "^12.6.2",
31
+ "bytenode": "^1.5.7",
32
+ "csv-parse": "^5.6.0",
33
+ "dotenv": "^16.6.1",
34
+ "express": "^4.22.1",
35
+ "math-intrinsics": "^1.1.0",
36
+ "multer": "^1.4.5-lts.1",
37
+ "qrcode": "^1.5.4",
38
+ "whatsapp-web.js": "^1.34.6",
39
+ "xlsx": "^0.18.5"
40
+ },
41
+ "devDependencies": {
42
+ "supertest": "^7.2.2"
43
+ }
44
+ }