@manybot/manybot 4.1.2 → 4.2.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.
- package/README.md +2 -2
- package/package.json +3 -2
- package/src/client/whatsappClient.js +63 -0
- package/src/config.js +3 -3
- package/src/kernel/pluginApi.js +6 -5
- package/src/locales/en.json +3 -1
- package/src/locales/es.json +3 -1
- package/src/locales/pt.json +3 -1
package/README.md
CHANGED
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
ManyBot is free and open-source
|
|
15
|
+
ManyBot is a free and open-source messaging automation ecosystem for online businesses and communities.
|
|
16
16
|
|
|
17
17
|
## Requirements
|
|
18
18
|
|
|
19
|
-
- Node.js >=
|
|
19
|
+
- Node.js >= 20
|
|
20
20
|
- npm
|
|
21
21
|
|
|
22
22
|
## Getting started
|
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"name": "SyntaxError!",
|
|
6
6
|
"email": "me@stxerr.dev"
|
|
7
7
|
},
|
|
8
|
-
"version": "4.
|
|
8
|
+
"version": "4.2.0",
|
|
9
9
|
"license": "GPL-3.0-only",
|
|
10
10
|
"private": false,
|
|
11
11
|
"engines": {
|
|
12
|
-
"node": ">=
|
|
12
|
+
"node": ">=20"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"node-webpmux": "^3.2.1",
|
|
39
39
|
"qrcode-terminal": "^0.12.0",
|
|
40
|
+
"tar": "^7.5.16",
|
|
40
41
|
"whatsapp-web.js": "^1.24.0"
|
|
41
42
|
},
|
|
42
43
|
"imports": {
|
|
@@ -15,16 +15,79 @@ import { PHONE_NUMBER, CLIENT_ID } from "#config";
|
|
|
15
15
|
import { logger } from "#logger";
|
|
16
16
|
import qrcode from "qrcode-terminal";
|
|
17
17
|
import { t } from "#i18n"
|
|
18
|
+
import { CONFIG_DIR } from "#config";
|
|
19
|
+
import { extract } from "tar";
|
|
20
|
+
import { pipeline } from "node:stream/promises";
|
|
21
|
+
import { Readable } from "node:stream";
|
|
22
|
+
import { Transform } from "node:stream";
|
|
18
23
|
|
|
19
24
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
25
|
const __dirname = path.dirname(__filename);
|
|
21
26
|
|
|
27
|
+
const chrome = path.join(CONFIG_DIR, "chrome/chrome")
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(chrome)) {
|
|
30
|
+
try {
|
|
31
|
+
logger.warn(t("errors.chromeNotFound"));
|
|
32
|
+
const tmpDir = "/tmp/manybot-chrome";
|
|
33
|
+
const tmpPath = path.join(tmpDir, "chrome.tar.gz");
|
|
34
|
+
const url = "https://api.manybot.stxerr.dev/download-chrome";
|
|
35
|
+
|
|
36
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
37
|
+
|
|
38
|
+
const res = await fetch(url);
|
|
39
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
40
|
+
|
|
41
|
+
const expected = Number(res.headers.get("content-length"));
|
|
42
|
+
let received = 0;
|
|
43
|
+
const frames = ["|","/","-","\\"];
|
|
44
|
+
let frame = 0;
|
|
45
|
+
let spinner;
|
|
46
|
+
|
|
47
|
+
const file = fs.createWriteStream(tmpPath);
|
|
48
|
+
|
|
49
|
+
spinner = setInterval(() => {
|
|
50
|
+
const pct = expected
|
|
51
|
+
? ` ${Math.floor((received / expected) * 100)}%`
|
|
52
|
+
: ` ${(received / 1024 / 1024).toFixed(1)}MB`;
|
|
53
|
+
process.stderr.write(`\r${frames[frame++ % frames.length]} Baixando Chrome...${pct}`);
|
|
54
|
+
}, 80);
|
|
55
|
+
|
|
56
|
+
const counter = new Transform({
|
|
57
|
+
transform(chunk, _enc, cb) {
|
|
58
|
+
received += chunk.length;
|
|
59
|
+
cb(null, chunk);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
await pipeline(
|
|
65
|
+
Readable.fromWeb(res.body),
|
|
66
|
+
counter,
|
|
67
|
+
file
|
|
68
|
+
);
|
|
69
|
+
} finally {
|
|
70
|
+
clearInterval(spinner);
|
|
71
|
+
process.stderr.write("\r\x1b[2K"); // limpa a linha
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (expected && received !== expected) {
|
|
75
|
+
throw new Error("Download incompleto");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await extract({ file: tmpPath, cwd: CONFIG_DIR, gzip: true });
|
|
79
|
+
} catch (err) {
|
|
80
|
+
throw new Error(t("errors.couldNotDownloadChrome") + err.message);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
}
|
|
22
84
|
export const { Client, LocalAuth, MessageMedia } = pkg;
|
|
23
85
|
|
|
24
86
|
// -- Instance --------------------------------------------------
|
|
25
87
|
const clientOptions = {
|
|
26
88
|
authStrategy: new LocalAuth({ clientId: CLIENT_ID }),
|
|
27
89
|
puppeteer: {
|
|
90
|
+
executablePath: chrome,
|
|
28
91
|
headless: true,
|
|
29
92
|
args: [
|
|
30
93
|
'--no-sandbox',
|
package/src/config.js
CHANGED
|
@@ -14,9 +14,9 @@ import path from "path";
|
|
|
14
14
|
|
|
15
15
|
import { logger } from "#logger";
|
|
16
16
|
|
|
17
|
-
const CONFIG_DIR = path.join(os.homedir(), ".manybot");
|
|
18
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, "manybot.conf");
|
|
19
|
-
const PLUGIN_FILE = path.join(CONFIG_DIR, "manyplug.conf");
|
|
17
|
+
export const CONFIG_DIR = path.join(os.homedir(), ".manybot");
|
|
18
|
+
export const CONFIG_FILE = path.join(CONFIG_DIR, "manybot.conf");
|
|
19
|
+
export const PLUGIN_FILE = path.join(CONFIG_DIR, "manyplug.conf");
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Converts strings to native JS values.
|
package/src/kernel/pluginApi.js
CHANGED
|
@@ -151,8 +151,8 @@ function mediaFromSource(source, mimetype = "image/webp") {
|
|
|
151
151
|
*/
|
|
152
152
|
function makeSender(target) {
|
|
153
153
|
return {
|
|
154
|
-
async text(content) {
|
|
155
|
-
return target.sendMessage(content);
|
|
154
|
+
async text(content, opts = {}) {
|
|
155
|
+
return target.sendMessage(content, opts);
|
|
156
156
|
},
|
|
157
157
|
async image(filePath, caption = "") {
|
|
158
158
|
const media = MessageMedia.fromFilePath(filePath);
|
|
@@ -185,7 +185,7 @@ function chatIdTarget(client, chatId) {
|
|
|
185
185
|
/** Send to a specific chat by ID. Available in both setup and runtime. */
|
|
186
186
|
function buildSendToApi(client) {
|
|
187
187
|
return {
|
|
188
|
-
sendTo: (chatId, text)
|
|
188
|
+
sendTo: (chatId, text, opts) => client.sendMessage(chatId, text, opts),
|
|
189
189
|
sendImageTo: (chatId, filePath, caption) => makeSender(chatIdTarget(client, chatId)).image(filePath, caption),
|
|
190
190
|
sendVideoTo: (chatId, filePath, caption) => makeSender(chatIdTarget(client, chatId)).video(filePath, caption),
|
|
191
191
|
sendAudioTo: (chatId, filePath) => makeSender(chatIdTarget(client, chatId)).audio(filePath),
|
|
@@ -197,7 +197,7 @@ function buildSendToApi(client) {
|
|
|
197
197
|
function buildSendApi(chat) {
|
|
198
198
|
const sender = makeSender(chat);
|
|
199
199
|
return {
|
|
200
|
-
send: (text)
|
|
200
|
+
send: (text, opts) => sender.text(text, opts),
|
|
201
201
|
sendImage: (filePath, caption) => sender.image(filePath, caption),
|
|
202
202
|
sendVideo: (filePath, caption) => sender.video(filePath, caption),
|
|
203
203
|
sendAudio: (filePath) => sender.audio(filePath),
|
|
@@ -267,7 +267,8 @@ export function buildApi({ msg, chat, client, pluginRegistry }) {
|
|
|
267
267
|
|
|
268
268
|
/** Check if message starts with a command. */
|
|
269
269
|
is(cmd) {
|
|
270
|
-
|
|
270
|
+
const command = msg.body?.trim().split(/\s+/)[0].toLowerCase();
|
|
271
|
+
return command === cmd.toLowerCase();
|
|
271
272
|
},
|
|
272
273
|
|
|
273
274
|
hasMedia: msg.hasMedia,
|
package/src/locales/en.json
CHANGED
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
"errors": {
|
|
60
60
|
"pluginLoad": "Failed to load plugin",
|
|
61
61
|
"messageProcess": "Failed to process message",
|
|
62
|
-
"stack": "Stack"
|
|
62
|
+
"stack": "Stack",
|
|
63
|
+
"chromeNotFound": "Chrome not found. Downloading...",
|
|
64
|
+
"couldNotDownloadChrome": "Could not download Chrome: "
|
|
63
65
|
}
|
|
64
66
|
}
|
package/src/locales/es.json
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"errors": {
|
|
55
55
|
"pluginLoad": "Error al cargar el plugin",
|
|
56
56
|
"messageProcess": "Error al procesar el mensaje",
|
|
57
|
-
"stack": "Stack"
|
|
57
|
+
"stack": "Stack",
|
|
58
|
+
"chromeNotFound": "No se ha encontrado Chrome. Descargando...",
|
|
59
|
+
"couldNotDownloadChrome": "No se ha podido descargar Chrome: "
|
|
58
60
|
}
|
|
59
61
|
}
|
package/src/locales/pt.json
CHANGED
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
"errors": {
|
|
60
60
|
"pluginLoad": "Falha ao carregar plugin",
|
|
61
61
|
"messageProcess": "Falha ao processar mensagem",
|
|
62
|
-
"stack": "Stack"
|
|
62
|
+
"stack": "Stack",
|
|
63
|
+
"chromeNotFound": "Chrome não encontrado. Baixando...",
|
|
64
|
+
"couldNotDownloadChrome": "Não foi possível baixar o Chrome: "
|
|
63
65
|
}
|
|
64
66
|
}
|