@manybot/manybot 4.0.3 β†’ 4.1.1

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
@@ -4,15 +4,56 @@
4
4
 
5
5
  **Just a cool open source WhatsApp bot**
6
6
 
7
- [πŸ‡§πŸ‡· PortuguΓͺs](README.md) Β· [πŸ‡ΊπŸ‡Έ English](README_EN.md)
8
-
9
7
  ![Node.js 18+](https://img.shields.io/badge/Node.js-18+-339933?logo=node.js&logoColor=white)
10
8
  ![npm 9+](https://img.shields.io/badge/npm-9+-CB3837?logo=npm&logoColor=white)
11
9
  ![GPL v3](https://img.shields.io/badge/License-GPL--v3-blue.svg)
12
10
  ![Linux](https://img.shields.io/badge/Linux%20%7C%20Windows-lightgrey)
11
+ ![whatsapp-web.js](https://img.shields.io/badge/WhatsApp-25D366?logo=whatsapp&logoColor=white)
12
+
13
+ </div>
13
14
 
14
15
  ---
15
16
 
16
- This repository is dedicated to contributions related to the project.
17
+ ManyBot is a free, open source WhatsApp bot built around a modular plugin system. Instead of a monolithic bot with features baked in, ManyBot gives you a lightweight core and lets you pick exactly what you want through plugins - no cloud dependency, no subscription, no black box.
18
+
19
+ ## Requirements
20
+
21
+ - Node.js >= 18
22
+ - npm
23
+
24
+ ## Getting started
25
+
26
+ ```bash
27
+ npm install -g @manybot/manybot
28
+ npm install -g @manybot/manyplug
29
+ manybot
30
+ ```
31
+
32
+ On first run, a configuration file is created at `~/.manybot/manybot.conf`. Edit it to set up your preferences and list the plugins you want to load.
33
+
34
+ For detailed setup instructions, see the **[documentation](https://manybot.stxerr.dev/docs/)**.
35
+
36
+ ## Plugins
37
+
38
+ ManyBot's functionality comes from plugins. Install them with ManyPlug:
39
+
40
+ ```bash
41
+ manyplug install <plugin-name>
42
+ ```
43
+
44
+ Browse available plugins at **[manybot.stxerr.dev/plugins](https://manybot.stxerr.dev/plugins/)**.
45
+
46
+ Want to build your own? The plugin API lets you add commands and features without touching the bot's core - *documentation coming soon*.
47
+
48
+ ## Contributing
49
+
50
+ All kinds of contributions are welcome:
51
+
52
+ - **Bug reports and feature requests**: open an issue on GitHub or Codeberg
53
+ - **Code**: pull requests are welcome on [GitHub](https://github.com/many-bot/manybot) or [Codeberg](https://codeberg.org/many-bot/manybot); patches by email (`devel+manybot@stxerr.dev`) are also accepted - subscribe to the mailing list [here](https://list.stxerr.dev).
54
+ - **Plugins**: submit your plugin to [manyplug-repo](https://github.com/many-bot/manyplug-repo), which has instructions on how to do it
55
+ - **Anything else**: suggestions, translations, documentation fixes - reach out by email or open an issue
56
+
57
+ ## License
17
58
 
18
- website: https://manybot.stxerr.dev
59
+ ManyBot is distributed under the [GNU General Public License v3.0](LICENSE).
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "SyntaxError!",
6
6
  "email": "me@stxerr.dev"
7
7
  },
8
- "version": "4.0.3",
8
+ "version": "4.1.1",
9
9
  "license": "GPL-3.0-only",
10
10
  "private": false,
11
11
  "engines": {
@@ -16,7 +16,6 @@ import { enqueue } from "#download";
16
16
  import { emptyFolder } from "#utils/file";
17
17
  import { getChatId } from "#utils/getChatId";
18
18
  import pkg from "whatsapp-web.js";
19
- import { client } from "#client/whatsappClient";
20
19
 
21
20
  const { MessageMedia } = pkg;
22
21
 
@@ -112,7 +111,7 @@ function buildPluginsApi(pluginRegistry) {
112
111
  require(name) {
113
112
  const plugin = pluginRegistry.get(name);
114
113
  if (!plugin || plugin.status !== "active") {
115
- throw new Error(`Plugin dependency "${name}" is not active.`);
114
+ throw new Error(`Plugin dependency "${name}" does not exist or is not active.`);
116
115
  }
117
116
  return plugin.exports;
118
117
  },
@@ -181,24 +180,35 @@ function chatIdTarget(client, chatId) {
181
180
  };
182
181
  }
183
182
 
184
- // ── Setup API ────────────────────────────────────────────────────────────────
183
+ // ── Send APIs ────────────────────────────────────────────────────────────────
185
184
 
186
- /**
187
- * Setup API β€” without message context.
188
- * Passed to plugin.setup(ctx) during initialization.
189
- *
190
- * @param {import("whatsapp-web.js").Client} client
191
- * @param {Map<string, any>} pluginRegistry
192
- * @returns {object}
193
- */
194
- export function buildSetupApi(client, pluginRegistry) {
185
+ /** Send to a specific chat by ID. Available in both setup and runtime. */
186
+ function buildSendToApi(client) {
195
187
  return {
196
188
  sendTo: (chatId, text) => client.sendMessage(chatId, text),
197
189
  sendImageTo: (chatId, filePath, caption) => makeSender(chatIdTarget(client, chatId)).image(filePath, caption),
198
190
  sendVideoTo: (chatId, filePath, caption) => makeSender(chatIdTarget(client, chatId)).video(filePath, caption),
199
191
  sendAudioTo: (chatId, filePath) => makeSender(chatIdTarget(client, chatId)).audio(filePath),
200
192
  sendStickerTo: (chatId, source) => makeSender(chatIdTarget(client, chatId)).sticker(source),
193
+ };
194
+ }
195
+
196
+ /** Send to the current chat. Only available in runtime. */
197
+ function buildSendApi(chat) {
198
+ const sender = makeSender(chat);
199
+ return {
200
+ send: (text) => sender.text(text),
201
+ sendImage: (filePath, caption) => sender.image(filePath, caption),
202
+ sendVideo: (filePath, caption) => sender.video(filePath, caption),
203
+ sendAudio: (filePath) => sender.audio(filePath),
204
+ sendSticker: (source) => sender.sticker(source),
205
+ };
206
+ }
201
207
 
208
+ // ── Base API (shared between setup and runtime) ───────────────────────────────
209
+
210
+ function buildBaseApi(client, pluginRegistry) {
211
+ return {
202
212
  log,
203
213
  t,
204
214
  config: buildConfigApi(),
@@ -207,6 +217,23 @@ export function buildSetupApi(client, pluginRegistry) {
207
217
  download: buildDownloadApi(),
208
218
  plugins: buildPluginsApi(pluginRegistry),
209
219
  botId: client.info?.wid?._serialized ?? null,
220
+ ...buildSendToApi(client),
221
+ };
222
+ }
223
+
224
+ // ── Setup API ────────────────────────────────────────────────────────────────
225
+
226
+ /**
227
+ * Setup API β€” without message context.
228
+ * Passed to plugin.setup(ctx) during initialization.
229
+ *
230
+ * @param {import("whatsapp-web.js").Client} client
231
+ * @param {Map<string, any>} pluginRegistry
232
+ * @returns {object}
233
+ */
234
+ export function buildSetupApi(client, pluginRegistry) {
235
+ return {
236
+ ...buildBaseApi(client, pluginRegistry),
210
237
  };
211
238
  }
212
239
 
@@ -224,10 +251,9 @@ export function buildSetupApi(client, pluginRegistry) {
224
251
  * @returns {object} ctx
225
252
  */
226
253
  export function buildApi({ msg, chat, client, pluginRegistry }) {
227
-
228
- const currentSender = makeSender(chat);
229
-
230
254
  return {
255
+ ...buildBaseApi(client, pluginRegistry),
256
+ ...buildSendApi(chat),
231
257
 
232
258
  // ── msg ──────────────────────────────────────────────────
233
259
 
@@ -263,6 +289,10 @@ export function buildApi({ msg, chat, client, pluginRegistry }) {
263
289
  async reply(text) {
264
290
  return msg.reply(text);
265
291
  },
292
+
293
+ async react(emoji) {
294
+ return msg.react(emoji);
295
+ },
266
296
  },
267
297
 
268
298
  // ── chat ─────────────────────────────────────────────────
@@ -272,32 +302,5 @@ export function buildApi({ msg, chat, client, pluginRegistry }) {
272
302
  name: chat.name || chat.id.user,
273
303
  isGroup: /@g\.us$/.test(chat.id._serialized),
274
304
  },
275
-
276
- // ── send (current chat) ──────────────────────────────────
277
-
278
- send: (text) => currentSender.text(text),
279
- sendImage: (filePath, caption) => currentSender.image(filePath, caption),
280
- sendVideo: (filePath, caption) => currentSender.video(filePath, caption),
281
- sendAudio: (filePath) => currentSender.audio(filePath),
282
- sendSticker: (source) => currentSender.sticker(source),
283
-
284
- // ── sendTo (specific chat) ───────────────────────────────
285
-
286
- sendTo: (chatId, text) => client.sendMessage(chatId, text),
287
- sendImageTo: (chatId, filePath, caption) => makeSender(chatIdTarget(client, chatId)).image(filePath, caption),
288
- sendVideoTo: (chatId, filePath, caption) => makeSender(chatIdTarget(client, chatId)).video(filePath, caption),
289
- sendAudioTo: (chatId, filePath) => makeSender(chatIdTarget(client, chatId)).audio(filePath),
290
- sendStickerTo: (chatId, source) => makeSender(chatIdTarget(client, chatId)).sticker(source),
291
-
292
- // ── system ───────────────────────────────────────────────
293
-
294
- log,
295
- t,
296
- config: buildConfigApi(),
297
- i18n: buildI18nApi(),
298
- utils: buildUtilsApi(),
299
- download: buildDownloadApi(),
300
- plugins: buildPluginsApi(pluginRegistry),
301
- botId: client.info?.wid?._serialized ?? null,
302
305
  };
303
306
  }