update documentation and remove systemd support

This commit is contained in:
synt-xerror
2026-04-21 11:18:19 -03:00
parent f683496318
commit c12374f86c
18 changed files with 3441 additions and 248 deletions

370
README.md
View File

@@ -1,308 +1,188 @@
<div align="center">
![ManyBot Logo](logo.png)
ManyBot é um bot para WhatsApp que roda 100% localmente, sem depender da API oficial do WhatsApp. Ele utiliza a biblioteca `whatsapp-web.js`, que automatiza o WhatsApp Web sem depender de gráficos (headless).
<p>
<strong>Bot para WhatsApp 100% local, sem API oficial</strong>
</p>
Algumas funcionalidades desse bot incluem:
- Suporte a múltiplos chats em uma única sessão
- Sistema de plugins — adicione, remova ou crie funcionalidades sem mexer no núcleo do bot
<p>
<a href="#-recursos">Recursos</a> .
<a href="#-instalação-rápida">Instalação</a> .
<a href="#-uso">Uso</a> .
<a href="#-plugins">Plugins</a> .
<a href="#-documentação">Documentação</a>
</p>
# Exemplos
<p>
🇧🇷 Português · <a href="README_EN.md">🇺🇸 English</a>
</p>
<center>
<p>
<img src="https://img.shields.io/badge/Node.js-18+-339933?logo=node.js&logoColor=white" alt="Node.js 18+">
<img src="https://img.shields.io/badge/npm-9+-CB3837?logo=npm&logoColor=white" alt="npm 9+">
<img src="https://img.shields.io/badge/License-GPL--v3-blue.svg" alt="License: GPL v3">
<img src="https://img.shields.io/badge/Platform-Linux%20%7C%20Windows-lightgrey" alt="Platform">
</p>
<p>
<img src="https://img.shields.io/badge/whatsapp--web.js-%2325D366?logo=whatsapp&logoColor=white" alt="whatsapp-web.js">
<img src="https://img.shields.io/badge/headless-Automated-green" alt="Headless">
</p>
<br>
> **Versão Oficial Online**
> Quer usar o ManyBot sem instalar? Adicione o bot oficial:
>
> **+55 (16) 99459-1903**
>
> Online 24h (quando possível) - Disponibilidade não garantida
>
> Ao adicionar, você concorda com os [Termos de Uso](TERMOS_pt-br.md)
![Exemplo do gerador de figurinhas](examples/figurinha.gif)
</center>
</div>
---
# Requisitos
- Node.js
- NPM
- Sistema Linux ou Windows
## Recursos
obs: Sistemas Android e iOS ainda não são 100% compatíveis. O suporte para Termux está em fases de testes e sem garantia de funcionamento correto.
- **100% Local** - Sem depender da API oficial do WhatsApp
- **Multi-chat** - Suporte a múltiplos chats em uma única sessão
- **Sistema de Plugins** - Adicione, remova ou crie funcionalidades sem mexer no núcleo
- **Headless** - Funciona em segundo plano sem interface gráfica
- **Fácil Configuração** - Arquivo de config simples e intuitivo
# Instalação (Linux)
---
## Instalação Rápida
### Opção 1: Usar o Bot Oficial (Sem instalar)
Adicione o número **+55 (16) 99459-1903** aos seus contatos e envie `!many` para ver os comandos disponíveis.
**Status:** 🟢 Online (24h quando possível, mas sem garantia)
> ⚠️ **Importante:** Ao usar o bot oficial, você concorda com os [Termos de Uso](TERMOS_pt-br.md). Leia antes de adicionar!
---
### Opção 2: Instalar sua Própria Versão
1. Clone o repositório e entre:
```bash
# 1. Clone o repositório
git clone https://github.com/synt-xerror/manybot
cd manybot
```
2. Crie e abra o arquivo de configuração (use o editor de sua preferência):
```bash
touch manybot.conf
# 2. Crie o arquivo de configuração
cp manybot.conf.example manybot.conf
# 3. Configure conforme sua necessidade (veja a documentação)
nano manybot.conf
```
3. Nele você pode configurar algumas coisas do ManyBot. Esse é o arquivo base para que possa modificar:
```bash
# Comentários com '#'
CLIENT_ID=bot_permanente
CMD_PREFIX=!
CHATS=[
123456789@c.us,
123456789@g.us
]
PLUGINS=[
video,
audio,
figurinha,
adivinhacao
]
```
- **CLIENT_ID:** ID do cliente, serve para identificar sua sessão.
- Valor padrão: `bot_permanente`
- **CMD_PREFIX:** Prefixo do comando, o caractere que você usa para executar um comando (!many, !figurinha).
- Valor padrão: `!`
- **CHATS:** ID dos chats no qual você quer que o bot assista. Use o utilitário: `src/utils/get_id.js` para descobrir os IDs. Deixe vazio caso queira que funcione com qualquer chat.
- Valor padrão: (nenhum)
- **PLUGINS:** Lista de plugins ativos. Cada nome corresponde a uma pasta dentro de `src/plugins/`. Remova ou comente uma linha para desativar o plugin sem apagá-lo.
- Valor padrão: (nenhum)
obs: o utilitário `src/utils/get_id.js` usa um CLIENT_ID separado para que não entre em conflito com a sessão principal do ManyBot. Você terá que escanear o QR Code novamente para executá-lo.
4. Execute o script de instalação:
```bash
# 4. Execute o script de instalação
bash ./setup
```
5. Rode o bot pela primeira vez (você deve rodar da raiz, não dentro de `src`):
```bash
node ./src/main.js
```
Ele vai pedir para que escaneie o QR Code com seu celular.
No WhatsApp:
Menu (três pontos) > Dispositivos conectados > Conectar um dispositivo
# Instalação (Windows)
O uso desse bot foi pensado para rodar em um terminal Linux. No entanto, você pode usar o Git Bash, que simula um terminal Linux com Bash real:
1. Para baixar o Git Bash: https://git-scm.com/install/windows
Selecione a versão que deseja (portátil ou instalador)
2. Para baixar o Node.js: https://nodejs.org/pt-br/download
Role a tela e selecione "Instalador Windows (.msi)"
Ou se preferir, use um gerenciador de pacotes como mostra no conteúdo inicial
Depois de instalar ambos, abra o Git Bash e execute exatamente os mesmos comandos mostrados na seção Linux.
# Uso
Feito a instalação, você pode executar o bot apenas rodando:
```bash
# 5. Rode o bot
node ./src/main.js
```
## Atualizações
📱 **Escaneie o QR Code** no WhatsApp: Menu → Dispositivos conectados → Conectar um dispositivo
> **⚡ Pronto!** Veja a [documentação completa](docs/INSTALACAO.md) para mais detalhes.
---
## 💻 Uso
É recomendável sempre ter a versão mais recente do ManyBot. Para isso, temos um utilitário logo na raíz. Para executar:
```bash
# Iniciar o bot
node ./src/main.js
# Atualizar para a versão mais recente
bash ./update
# Descobrir IDs de chats
node src/utils/get_id.js
```
## Criando um serviço (opcional)
---
Se estiver rodando numa VPS ou apenas quer mais controle, é recomendável criar um serviço systemd. Siga os passos abaixo para saber como criar, habilitar e gerenciar um.
## 🔌 Plugins
1. Configurando o diretório
O ManyBot é construído em torno de um sistema de plugins. O kernel apenas conecta ao WhatsApp e distribui as mensagens — os plugins decidem o que fazer.
Primeiro passo é garantir que o diretório do ManyBot esteja no local adequado, é recomendável guardar em `/root/manybot` (os passos a seguir supõem que esteja essa localização)
### Plugins Incluídos
2. Criando o serviço
| Plugin | Comando | Descrição |
|--------|---------|-----------|
| **figurinha** | `!figurinha` | Converte imagens, GIFs e vídeos em figurinhas |
| **video** | `!video <link>` | Baixa vídeos da internet |
| **audio** | `!audio <link>` | Baixa áudio de vídeos como mensagem de voz |
| **adivinhacao** | `!adivinhacao comecar` | Jogo de adivinhação (1-100) |
| **forca** | `!forca comecar` | Jogo da forca clássico |
| **many** | `!many` | Lista todos os comandos disponíveis |
| **obrigado** | `!obrigado` | Responde agradecimentos |
Abra o arquivo:
```bash
/etc/systemd/system/manybot.service
```
### Criar um Plugin
E cole o seguinte conteúdo:
```conf
[Unit]
Description=ManyBot
After=network.target
[Service]
ExecStart=/usr/bin/env node /root/manybot/src/main.js
WorkingDirectory=/root/manybot
Restart=always
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
```
3. Iniciando e habilitando o serviço:
Primeiro reinicie o daemon do systemd:
```bash
systemctl daemon-reload
```
Inicie o serviço:
```bash
systemctl start manybot
```
Habilite para que ele seja iniciado junto com o seu sistema (opcional):
```bash
systemctl enable manybot
```
4. Gerenciando o serviço:
Ver logs:
```bash
journalctl -u manybot
```
Em tempo real:
```bash
journalctl -u manybot -f
```
Parar o serviço:
```bash
systemctl stop manybot
```
Reiniciar o serviço:
```bash
systemctl restart manybot
```
Saiba mais sobre como gerenciar serviços em: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units-pt
Sobre o journalctl: https://www.digitalocean.com/community/tutorials/how-to-use-journalctl-to-view-and-manipulate-systemd-logs-pt
# Plugins
O ManyBot é construído em torno de um sistema de plugins. O núcleo do bot (kernel) apenas conecta ao WhatsApp e distribui as mensagens — quem decide o que fazer com elas são os plugins.
Isso significa que você pode adicionar, remover ou criar funcionalidades sem tocar no código principal do bot.
## Plugins incluídos
O ManyBot vem com alguns plugins prontos para uso, como:
- **video** — baixa um vídeo da internet e envia no chat (`!video <link>`)
- **audio** — baixa o áudio de um vídeo e envia como mensagem de voz (`!audio <link>`)
- **figurinha** — converte imagens, GIFs e vídeos em figurinhas (`!figurinha`)
- **adivinhacao** — jogo de adivinhação de um número entre 1 e 100 (`!adivinhação começar`)
- **forca** — clássico jogo da forca (`!forca começar`)
- **many** — exibe a lista de comandos disponíveis (`!many`)
- **obrigado** — responde agradecimentos (`!obrigado`, `!valeu`, `!brigado`)
Para ativar ou desativar qualquer um deles, basta editar a lista `PLUGINS` no `manybot.conf`.
## Criando um plugin
Cada plugin é uma pasta dentro de `plugins/` com um arquivo `index.js`. O bot carrega automaticamente todos os plugins listados no `manybot.conf`.
A estrutura mínima de um plugin:
```
plugins/
└── meu-plugin/
└── index.js
```
O `index.js` deve exportar uma função `default` que o kernel chama a cada mensagem recebida. A função recebe `{ msg, api }` e decide por conta própria se age ou ignora:
```js
```javascript
// plugins/meu-plugin/index.js
import { CMD_PREFIX } from "../../config.js"
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "oi")) return;
await msg.reply("Olá! 👋");
}
```
### O objeto `msg`
Veja mais na [documentação de plugins](docs/PLUGINS.md).
Contém as informações da mensagem recebida:
---
| Propriedade | Descrição |
|---|---|
| `msg.body` | Texto da mensagem |
| `msg.args` | Tokens da mensagem — `["!video", "https://..."]` |
| `msg.type` | Tipo — `"chat"`, `"image"`, `"video"`, `"audio"`, `"sticker"` |
| `msg.sender` | ID de quem enviou |
| `msg.senderName` | Nome de quem enviou |
| `msg.fromMe` | `true` se foi o próprio bot que enviou |
| `msg.hasMedia` | `true` se a mensagem tem mídia |
| `msg.hasReply` | `true` se é uma resposta a outra mensagem |
| `msg.isGif` | `true` se a mídia é um GIF |
| `msg.is(cmd)` | Retorna `true` se a mensagem começa com `cmd` |
| `msg.reply(text)` | Responde à mensagem com quote |
| `msg.downloadMedia()` | Baixa a mídia — retorna `{ mimetype, data }` |
| `msg.getReply()` | Retorna a mensagem citada, ou `null` |
## 📚 Documentação
### O objeto `api`
- [📥 Instalação Completa](docs/INSTALACAO.md) — Linux, Windows, Termux
- [⚙️ Configuração](docs/CONFIGURACAO.md) — Todas as opções do `manybot.conf`
- [🔌 Criando Plugins](docs/PLUGINS.md) — Guia completo de desenvolvimento
- [🖥️ Serviço Systemd](docs/SYSTEMD.md) — Rodar como serviço Linux
- [🛠️ API de Plugins](docs/API.md) — Referência de objetos `msg` e `api`
Contém tudo que o plugin pode fazer — enviar mensagens, acessar outros plugins, registrar logs:
## 🌍 Internacionalização
| Método | Descrição |
|---|---|
| `api.send(text)` | Envia texto no chat |
| `api.sendVideo(filePath)` | Envia um vídeo a partir de um arquivo local |
| `api.sendAudio(filePath)` | Envia um áudio a partir de um arquivo local |
| `api.sendImage(filePath, caption?)` | Envia uma imagem a partir de um arquivo local |
| `api.sendSticker(bufferOuPath)` | Envia uma figurinha — aceita `Buffer` ou caminho |
| `api.getPlugin(name)` | Retorna a API pública de outro plugin |
| `api.chat.id` | ID do chat atual |
| `api.chat.name` | Nome do chat atual |
| `api.chat.isGroup` | `true` se é um grupo |
| `api.log.info(...)` | Loga uma mensagem informativa |
| `api.log.warn(...)` | Loga um aviso |
| `api.log.error(...)` | Loga um erro |
O ManyBot suporta múltiplos idiomas. Configure no `manybot.conf`:
### Lendo o manybot.conf no plugin
Se o seu plugin precisar de configurações próprias, você pode adicioná-las diretamente no `manybot.conf` e importá-las no código:
```js
import { MEU_PREFIXO } from "../../src/config.js";
const prefixo = MEU_PREFIXO ?? "padrão";
```bash
LANGUAGE=pt # Português
LANGUAGE=en # English
LANGUAGE=es # Español
```
### Expondo uma API para outros plugins
- **Padrão:** Inglês (`en`)
- **Fallback:** Se o idioma selecionado não existir, o bot usa inglês
Um plugin pode expor funções para que outros plugins as utilizem. Para isso, basta exportar um objeto `api`:
---
```js
// plugins/utilidades/index.js
## 📋 Requisitos
export const api = {
formatarData: (date) => date.toLocaleDateString("pt-BR"),
};
- **Node.js** 18+
- **NPM** 9+
- **Linux** ou **Windows** (via Git Bash)
export default async function ({ msg }) {
// lógica normal do plugin
}
```
> ⚠️ Android/iOS e Termux têm suporte experimental sem garantias.
Outro plugin pode chamar:
---
```js
const utils = api.getPlugin("utilidades");
utils.formatarData(new Date());
```
## 📝 Licença
### Erros no plugin
Distribuído sob a licença **GPLv3**. Veja [LICENSE](LICENSE) para mais detalhes.
Se um plugin lançar um erro, o kernel o desativa automaticamente e loga o problema — o restante dos plugins continua funcionando normalmente. Isso garante que um plugin com bug não derruba o bot inteiro.
---
# Considerações
<div align="center">
ManyBot é distribuído sob a licença GPLv3. Você pode usar, modificar e redistribuir o software conforme os termos da licença.
**[⬆ Voltar ao topo](#)**
Saiba mais sobre as permissões lendo o arquivo [LICENSE](LICENSE) ou em: https://www.gnu.org/licenses/quick-guide-gplv3.pt-br.html
</div>

188
README_EN.md Normal file
View File

@@ -0,0 +1,188 @@
<div align="center">
![ManyBot Logo](logo.png)
<p>
<strong>100% Local WhatsApp Bot, no official API</strong>
</p>
<p>
<a href="#-features">Features</a> •
<a href="#-quick-install">Install</a> •
<a href="#-usage">Usage</a> •
<a href="#-plugins">Plugins</a> •
<a href="#-documentation">Documentation</a>
</p>
<p>
<a href="README.md">🇧🇷 Português</a> · <a href="README_EN.md">🇺🇸 English</a>
</p>
<p>
<img src="https://img.shields.io/badge/Node.js-18+-339933?logo=node.js&logoColor=white" alt="Node.js 18+">
<img src="https://img.shields.io/badge/npm-9+-CB3837?logo=npm&logoColor=white" alt="npm 9+">
<img src="https://img.shields.io/badge/License-GPL--v3-blue.svg" alt="License: GPL v3">
<img src="https://img.shields.io/badge/Platform-Linux%20%7C%20Windows-lightgrey" alt="Platform">
</p>
<p>
<img src="https://img.shields.io/badge/whatsapp--web.js-%2325D366?logo=whatsapp&logoColor=white" alt="whatsapp-web.js">
<img src="https://img.shields.io/badge/headless-Automated-green" alt="Headless">
</p>
<br>
> 🟢 **Official Instance Online**
> Want to use ManyBot without installing? Add the official bot:
>
> **+55 (16) 99459-1903**
>
> Online 24h (when possible) · Availability not guaranteed
>
> By adding, you agree to the [Terms of Use](TERMS_en-us.md)
![Sticker generator example](examples/figurinha.gif)
</div>
---
## ✨ Features
- **100% Local** — No dependency on the official WhatsApp API
- **Multi-chat** — Support for multiple chats in a single session
- **Plugin System** — Add, remove, or create features without touching the core
- **Headless** — Runs in the background without a GUI
- **Easy Configuration** — Simple and intuitive config file
---
## 🚀 Quick Install
### Option 1: Use the Official Bot (No install)
Add the number **+55 (16) 99459-1903** to your contacts and send `!many` to see available commands.
**Status:** 🟢 Online (24h when possible, but no guarantee)
> ⚠️ **Important:** By using the official bot, you agree to the [Terms of Use](TERMS_en-us.md). Read before adding!
---
### Option 2: Install Your Own Version
```bash
# 1. Clone the repository
git clone https://github.com/synt-xerror/manybot
cd manybot
# 2. Create the config file
cp manybot.conf.example manybot.conf
# 3. Configure as needed (see documentation)
nano manybot.conf
# 4. Run the install script
bash ./setup
# 5. Run the bot
node ./src/main.js
```
📱 **Scan the QR Code** on WhatsApp: Menu → Linked Devices → Link a Device
> **⚡ Done!** See the [full documentation](docs/INSTALLATION.md) for more details.
---
## 💻 Usage
```bash
# Start the bot
node ./src/main.js
# Update to the latest version
bash ./update
# Discover chat IDs
node src/utils/get_id.js
```
---
## 🔌 Plugins
ManyBot is built around a plugin system. The kernel only connects to WhatsApp and distributes messages — plugins decide what to do.
### Included Plugins
| Plugin | Command | Description |
|--------|---------|-------------|
| **sticker** | `!sticker` | Converts images, GIFs, and videos into stickers |
| **video** | `!video <link>` | Downloads videos from the internet |
| **audio** | `!audio <link>` | Downloads audio from videos as voice messages |
| **guess** | `!guess start` | Guessing game (1-100) |
| **hangman** | `!hangman start` | Classic hangman game |
| **many** | `!many` | Lists all available commands |
| **thanks** | `!thanks` | Responds to thanks |
### Create a Plugin
```javascript
// plugins/my-plugin/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "hello")) return;
await msg.reply("Hello! 👋");
}
```
See more in the [plugin documentation](docs/PLUGINS_EN.md).
---
## 📚 Documentation
- [📥 Full Installation](docs/INSTALLATION.md) — Linux, Windows, Termux
- [⚙️ Configuration](docs/CONFIGURATION.md) — All `manybot.conf` options
- [🔌 Creating Plugins](docs/PLUGINS.md) — Complete development guide
- [🖥️ Systemd Service](docs/SYSTEMD.md) — Run as a Linux service
- [🛠️ Plugin API](docs/API.md) — Reference for `msg` and `api` objects
## 🌍 Internationalization
ManyBot supports multiple languages. Configure in `manybot.conf`:
```bash
LANGUAGE=pt # Português
LANGUAGE=en # English
LANGUAGE=es # Español
```
- **Default:** English (`en`)
- **Fallback:** If selected language doesn't exist, bot falls back to English
---
## 📋 Requirements
- **Node.js** 18+
- **NPM** 9+
- **Linux** or **Windows** (via Git Bash)
> ⚠️ Android/iOS and Termux have experimental support with no guarantees.
---
## 📝 License
Distributed under the **GPLv3** license. See [LICENSE](LICENSE) for details.
---
<div align="center">
**[⬆ Back to top](#)**
</div>

View File

@@ -1,6 +1,6 @@
## Termos de Uso
> Este arquivo poderá ser excluído no futuro, assim que o site oficial for lançado.
> Este arquivo poderá ser movido no futuro, assim que o site oficial for lançado.
### 1. Natureza do Software

View File

@@ -1,6 +1,6 @@
## Terms of Use
. This is file may be deleted in the future as the official webpage is launched.
> This is file may be moved in the future as the official webpage is launched.
### 1. Nature of the Software

277
docs/API (en).md Normal file
View File

@@ -0,0 +1,277 @@
# 🛠️ API Reference
Complete documentation of objects available in plugins.
---
## The `msg` Object
Contains information about the received message.
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `msg.body` | `string` | Full text of the message |
| `msg.args` | `string[]` | Message tokens. E.g.: `"!video url"``["!video", "url"]` |
| `msg.type` | `string` | Message type: `chat`, `image`, `video`, `audio`, `sticker`, `ptt` (voice), `document`, `location` |
| `msg.sender` | `string` | Sender ID (format: `NUMBER@c.us` or `NUMBER@g.us`) |
| `msg.senderName` | `string` | Display name of the sender |
| `msg.fromMe` | `boolean` | `true` if the bot itself sent the message |
| `msg.hasMedia` | `boolean` | `true` if the message contains media |
| `msg.hasReply` | `boolean` | `true` if the message is a reply to another |
| `msg.isGif` | `boolean` | `true` if the media is a GIF |
| `msg.timestamp` | `number` | Unix timestamp of the message |
### Methods
#### `msg.is(cmd)`
Checks whether the message starts with the specified command.
```javascript
if (msg.is(CMD_PREFIX + "video")) {
// Execute command
}
```
**Returns:** `boolean`
---
#### `msg.reply(text)`
Replies to the current message with a quote (citation).
```javascript
await msg.reply("Reply with citation!");
```
**Parameters:**
- `text` (string): Text of the reply
**Returns:** `Promise<void>`
---
#### `msg.downloadMedia()`
Downloads the media from the message.
```javascript
const media = await msg.downloadMedia();
// Returns: { mimetype: "image/jpeg", data: "base64string..." }
```
**Returns:** `Promise<{ mimetype: string, data: string } | null>`
---
#### `msg.getReply()`
Returns the message that was quoted.
```javascript
const quotedMsg = msg.getReply();
if (quotedMsg) {
console.log(quotedMsg.body);
}
```
**Returns:** `msg object | null`
---
## The `api` Object
Contains methods for interacting with WhatsApp and other plugins.
### Properties
#### `api.chat`
Information about the current chat.
| Property | Type | Description |
|----------|------|-------------|
| `api.chat.id` | `string` | Chat ID |
| `api.chat.name` | `string` | Chat name |
| `api.chat.isGroup` | `boolean` | `true` if it is a group |
---
### Send Methods
#### `api.send(text)`
Sends a text message.
```javascript
await api.send("Message sent!");
```
**Parameters:**
- `text` (string): Text to send
**Returns:** `Promise<void>`
---
#### `api.sendVideo(filePath)`
Sends a video from the file system.
```javascript
await api.sendVideo("/path/to/video.mp4");
```
**Parameters:**
- `filePath` (string): Path to the file
**Returns:** `Promise<void>`
---
#### `api.sendAudio(filePath)`
Sends audio as a voice message (PTT).
```javascript
await api.sendAudio("/path/to/audio.mp3");
```
**Parameters:**
- `filePath` (string): Path to the file
**Returns:** `Promise<void>`
---
#### `api.sendImage(filePath, caption?)`
Sends an image.
```javascript
await api.sendImage("/path/to/image.jpg", "Optional caption");
```
**Parameters:**
- `filePath` (string): Path to the file
- `caption` (string, optional): Image caption
**Returns:** `Promise<void>`
---
#### `api.sendSticker(bufferOrPath)`
Sends a sticker. Accepts a `Buffer` or a file path.
```javascript
// With Buffer
const buffer = fs.readFileSync("image.png");
await api.sendSticker(buffer);
// With path
await api.sendSticker("/path/to/image.png");
```
**Parameters:**
- `bufferOrPath` (`Buffer` | `string`): Image data or file path
**Returns:** `Promise<void>`
---
### Plugin Methods
#### `api.getPlugin(name)`
Accesses the public API of another plugin.
```javascript
const utils = api.getPlugin("utilities");
const data = utils.formatDate(new Date());
```
**Parameters:**
- `name` (string): Plugin name
**Returns:** `object | undefined`
---
### Log Methods
#### `api.log.info(...args)`
Informational log.
```javascript
api.log.info("Message received:", msg.body);
```
#### `api.log.warn(...args)`
Warning log.
```javascript
api.log.warn("Missing config, using default");
```
#### `api.log.error(...args)`
Error log.
```javascript
api.log.error("Failed to process:", error);
```
---
## Configuration Object
Import settings from `manybot.conf`:
```javascript
import { CMD_PREFIX, CLIENT_ID, CHATS, PLUGINS } from "../../config.js";
// Custom configurations also work
import { MY_PREFIX } from "../../config.js";
```
---
## Full Example
```javascript
import { CMD_PREFIX } from "../../config.js";
import fs from "fs";
export default async function ({ msg, api }) {
// Ignore messages from the bot itself
if (msg.fromMe) return;
// Command: !echo
if (!msg.is(CMD_PREFIX + "echo")) return;
api.log.info("Echo command received from:", msg.senderName);
// If it has media, download and resend
if (msg.hasMedia) {
const media = await msg.downloadMedia();
await api.sendSticker(media.data);
return;
}
// If it's a reply, echo the quoted message
if (msg.hasReply) {
const quoted = msg.getReply();
await msg.reply(`You quoted: "${quoted.body}"`);
return;
}
// Default response
await msg.reply("Send media or reply to a message!");
}
```

277
docs/API.md Normal file
View File

@@ -0,0 +1,277 @@
# 🛠️ Referência da API
Documentação completa dos objetos disponíveis nos plugins.
---
## Objeto `msg`
Contém informações da mensagem recebida.
### Propriedades
| Propriedade | Tipo | Descrição |
|-------------|------|-----------|
| `msg.body` | `string` | Texto completo da mensagem |
| `msg.args` | `string[]` | Tokens da mensagem. Ex: `"!video url"``["!video", "url"]` |
| `msg.type` | `string` | Tipo da mensagem: `chat`, `image`, `video`, `audio`, `sticker`, `ptt` (voz), `document`, `location` |
| `msg.sender` | `string` | ID do remetente (formato: `NUMERO@c.us` ou `NUMERO@g.us`) |
| `msg.senderName` | `string` | Nome de exibição do remetente |
| `msg.fromMe` | `boolean` | `true` se o próprio bot enviou a mensagem |
| `msg.hasMedia` | `boolean` | `true` se a mensagem contém mídia |
| `msg.hasReply` | `boolean` | `true` se é uma resposta a outra mensagem |
| `msg.isGif` | `boolean` | `true` se a mídia é um GIF |
| `msg.timestamp` | `number` | Timestamp Unix da mensagem |
### Métodos
#### `msg.is(cmd)`
Verifica se a mensagem começa com o comando especificado.
```javascript
if (msg.is(CMD_PREFIX + "video")) {
// Executa comando
}
```
**Retorno:** `boolean`
---
#### `msg.reply(text)`
Responde à mensagem atual com quote (citação).
```javascript
await msg.reply("Resposta com citação!");
```
**Parâmetros:**
- `text` (string): Texto da resposta
**Retorno:** `Promise<void>`
---
#### `msg.downloadMedia()`
Baixa a mídia da mensagem.
```javascript
const media = await msg.downloadMedia();
// Retorna: { mimetype: "image/jpeg", data: "base64string..." }
```
**Retorno:** `Promise<{ mimetype: string, data: string } | null>`
---
#### `msg.getReply()`
Retorna a mensagem que foi citada.
```javascript
const mensagemCitada = msg.getReply();
if (mensagemCitada) {
console.log(mensagemCitada.body);
}
```
**Retorno:** `msg object | null`
---
## Objeto `api`
Contém métodos para interagir com o WhatsApp e outros plugins.
### Propriedades
#### `api.chat`
Informações do chat atual.
| Propriedade | Tipo | Descrição |
|-------------|------|-----------|
| `api.chat.id` | `string` | ID do chat |
| `api.chat.name` | `string` | Nome do chat |
| `api.chat.isGroup` | `boolean` | `true` se é grupo |
---
### Métodos de Envio
#### `api.send(text)`
Envia uma mensagem de texto.
```javascript
await api.send("Mensagem enviada!");
```
**Parâmetros:**
- `text` (string): Texto a enviar
**Retorno:** `Promise<void>`
---
#### `api.sendVideo(filePath)`
Envia um vídeo do sistema de arquivos.
```javascript
await api.sendVideo("/caminho/para/video.mp4");
```
**Parâmetros:**
- `filePath` (string): Caminho para o arquivo
**Retorno:** `Promise<void>`
---
#### `api.sendAudio(filePath)`
Envia um áudio como mensagem de voz (PTT).
```javascript
await api.sendAudio("/caminho/para/audio.mp3");
```
**Parâmetros:**
- `filePath` (string): Caminho para o arquivo
**Retorno:** `Promise<void>`
---
#### `api.sendImage(filePath, caption?)`
Envia uma imagem.
```javascript
await api.sendImage("/caminho/para/imagem.jpg", "Legenda opcional");
```
**Parâmetros:**
- `filePath` (string): Caminho para o arquivo
- `caption` (string, opcional): Legenda da imagem
**Retorno:** `Promise<void>`
---
#### `api.sendSticker(bufferOuPath)`
Envia uma figurinha. Aceita `Buffer` ou caminho para arquivo.
```javascript
// Com Buffer
const buffer = fs.readFileSync("imagem.png");
await api.sendSticker(buffer);
// Com caminho
await api.sendSticker("/caminho/para/imagem.png");
```
**Parâmetros:**
- `bufferOuPath` (`Buffer` | `string`): Dados da imagem ou caminho
**Retorno:** `Promise<void>`
---
### Métodos de Plugin
#### `api.getPlugin(name)`
Acessa a API pública de outro plugin.
```javascript
const utils = api.getPlugin("utilidades");
const data = utils.formatarData(new Date());
```
**Parâmetros:**
- `name` (string): Nome do plugin
**Retorno:** `object | undefined`
---
### Métodos de Log
#### `api.log.info(...args)`
Log informativo.
```javascript
api.log.info("Mensagem recebida:", msg.body);
```
#### `api.log.warn(...args)`
Log de aviso.
```javascript
api.log.warn("Configuração ausente, usando padrão");
```
#### `api.log.error(...args)`
Log de erro.
```javascript
api.log.error("Falha ao processar:", erro);
```
---
## Objeto de Configuração
Importe configurações do `manybot.conf`:
```javascript
import { CMD_PREFIX, CLIENT_ID, CHATS, PLUGINS } from "../../config.js";
// Configurações personalizadas também funcionam
import { MEU_PREFIXO } from "../../config.js";
```
---
## Exemplo Completo
```javascript
import { CMD_PREFIX } from "../../config.js";
import fs from "fs";
export default async function ({ msg, api }) {
// Ignora mensagens do próprio bot
if (msg.fromMe) return;
// Comando: !eco
if (!msg.is(CMD_PREFIX + "eco")) return;
api.log.info("Comando eco recebido de:", msg.senderName);
// Se tem mídia, baixa e reenvia
if (msg.hasMedia) {
const media = await msg.downloadMedia();
await api.sendSticker(media.data);
return;
}
// Se é resposta, ecoa a mensagem citada
if (msg.hasReply) {
const citada = msg.getReply();
await msg.reply(`Você citou: "${citada.body}"`);
return;
}
// Resposta padrão
await msg.reply("Envie uma mídia ou responda uma mensagem!");
}
```

146
docs/CONFIGURACAO.md Normal file
View File

@@ -0,0 +1,146 @@
# ⚙️ Configuração
Guia completo do arquivo `manybot.conf`.
---
## Estrutura Básica
```bash
# Comentários começam com '#'
CLIENT_ID=bot_permanente
CMD_PREFIX=!
LANGUAGE=pt
CHATS=[]
PLUGINS=[]
```
---
## Opções
### CLIENT_ID
Identificador único da sessão do bot.
```bash
CLIENT_ID=bot_permanente
```
- **Padrão:** `bot_permanente`
- **Uso:** Cria uma pasta `session/` com esse nome para armazenar dados de autenticação
### CMD_PREFIX
Caractere que indica o início de um comando.
```bash
CMD_PREFIX=!
```
- **Padrão:** `!`
- **Exemplo:** Com prefixo `!`, o comando é `!figurinha`. Com `.`, seria `.figurinha`.
### LANGUAGE
Idioma das mensagens do bot.
```bash
LANGUAGE=pt
```
- **Padrão:** `en` (inglês)
- **Opções:** `en` (inglês), `pt` (português), `es` (espanhol)
- **Nota:** Se o idioma selecionado não existir, o bot usará inglês como fallback
### CHATS
Lista de IDs de chats onde o bot responderá.
```bash
CHATS=[
123456789@c.us, # Chat privado
123456789@g.us # Grupo
]
```
- **Padrão:** `[]` (vazio = responde em todos)
- **Formato:**
- Privado: `NUMERO@c.us`
- Grupo: `NUMERO@g.us`
#### Como descobrir o ID
```bash
node src/utils/get_id.js
```
Escaneie o QR Code e mande uma mensagem no chat. O ID aparecerá no terminal.
> Nota: O utilitário usa um `CLIENT_ID` separado para não conflitar com a sessão principal.
### PLUGINS
Lista de plugins a serem carregados.
```bash
PLUGINS=[
video,
audio,
figurinha,
adivinhacao,
forca,
many,
obrigado
]
```
- **Padrão:** `[]` (nenhum)
- Cada nome corresponde a uma pasta em `src/plugins/`
- Remova ou comente para desativar sem apagar
---
## Configurações Personalizadas
Você pode adicionar suas próprias variáveis para plugins:
```bash
# manybot.conf
MEU_PREFIXO=>
API_KEY=minha_chave
```
E acessar no código do plugin:
```javascript
import { MEU_PREFIXO, API_KEY } from "../../config.js";
```
---
## Exemplo Completo
```bash
# ManyBot Configuration
CLIENT_ID=meu_bot_prod
CMD_PREFIX=/
LANGUAGE=pt
CHATS=[
5511999999999@c.us,
5511888888888-123456789@g.us
]
PLUGINS=[
figurinha,
video,
audio,
many
]
# Configurações extras
ADMIN_NUMBER=5511999999999@c.us
```

146
docs/CONFIGURATION.md Normal file
View File

@@ -0,0 +1,146 @@
# Configuration
Complete guide for the `manybot.conf` file.
---
## Basic Structure
```bash
# Comments start with '#'
CLIENT_ID=bot_permanente
CMD_PREFIX=!
LANGUAGE=en
CHATS=[]
PLUGINS=[]
```
---
## Options
### CLIENT_ID
Unique identifier for the bot session.
```bash
CLIENT_ID=my_bot
```
- **Default:** `bot_permanente`
- **Usage:** Creates a `session/` folder with this name to store authentication data
### CMD_PREFIX
Character that indicates the start of a command.
```bash
CMD_PREFIX=!
```
- **Default:** `!`
- **Example:** With prefix `!`, the command is `!sticker`. With `.`, it would be `.sticker`.
### LANGUAGE
Bot message language.
```bash
LANGUAGE=en
```
- **Default:** `en` (English)
- **Options:** `en` (English), `pt` (Portuguese), `es` (Spanish)
- **Note:** If the selected language doesn't exist, the bot will fall back to English
### CHATS
List of chat IDs where the bot will respond.
```bash
CHATS=[
123456789@c.us, # Private chat
123456789@g.us # Group
]
```
- **Default:** `[]` (empty = responds to all)
- **Format:**
- Private: `NUMBER@c.us`
- Group: `NUMBER@g.us`
#### How to discover the ID
```bash
node src/utils/get_id.js
```
Scan the QR Code and send a message in the chat. The ID will appear in the terminal.
> Note: The utility uses a separate `CLIENT_ID` to avoid conflicting with the main session.
### PLUGINS
List of plugins to be loaded.
```bash
PLUGINS=[
video,
audio,
sticker,
guess,
hangman,
many,
thanks
]
```
- **Default:** `[]` (none)
- Each name corresponds to a folder in `src/plugins/`
- Remove or comment to disable without deleting
---
## Custom Settings
You can add your own variables for plugins:
```bash
# manybot.conf
MY_PREFIX=>
API_KEY=my_key
```
And access in the plugin code:
```javascript
import { MY_PREFIX, API_KEY } from "../../config.js";
```
---
## Complete Example
```bash
# ManyBot Configuration
CLIENT_ID=my_bot_prod
CMD_PREFIX=/
LANGUAGE=en
CHATS=[
5511999999999@c.us,
5511888888888-123456789@g.us
]
PLUGINS=[
sticker,
video,
audio,
many
]
# Extra settings
ADMIN_NUMBER=5511999999999@c.us
```

144
docs/INSTALACAO.md Normal file
View File

@@ -0,0 +1,144 @@
# 📥 Instalação
Guia completo de instalação do ManyBot em diferentes plataformas.
---
## 📑 Índice
- [Linux](#linux)
- [Windows](#windows)
- [Termux (Android)](#termux-android)
---
## Linux
### 1. Clone o repositório
```bash
git clone https://github.com/synt-xerror/manybot
cd manybot
```
### 2. Configure o bot
Crie o arquivo de configuração:
```bash
touch manybot.conf
nano manybot.conf
```
Exemplo de configuração:
```bash
# Comentários com '#'
CLIENT_ID=bot_permanente
CMD_PREFIX=!
LANGUAGE=pt
CHATS=[
123456789@c.us,
123456789@g.us
]
PLUGINS=[
video,
audio,
figurinha,
adivinhacao
]
```
**Detalhes:**
- `CLIENT_ID`: ID da sessão (padrão: `bot_permanente`)
- `CMD_PREFIX`: Prefixo dos comandos (padrão: `!`)
- `LANGUAGE`: Idioma do bot - `pt`, `en` ou `es` (padrão: `en`)
- `CHATS`: IDs dos chats permitidos (deixe vazio para todos)
- `PLUGINS`: Lista de plugins ativos
### 3. Execute a instalação
```bash
bash ./setup
```
### 4. Primeira execução
```bash
node ./src/main.js
```
Escaneie o QR Code no WhatsApp:
**Menu → Dispositivos conectados → Conectar um dispositivo**
---
## Windows
O ManyBot foi pensado para Linux, mas funciona no Windows via **Git Bash**.
### Pré-requisitos
1. **Git Bash**: https://git-scm.com/download/win
2. **Node.js**: https://nodejs.org (escolha "Instalador Windows (.msi)")
### Instalação
Após instalar ambos, abra o **Git Bash** e siga os mesmos passos da [instalação Linux](#linux).
---
## Termux (Android)
> ⚠️ **Aviso:** Suporte experimental. Não há garantia de funcionamento.
```bash
# Instale o Termux pela F-Droid (não use Play Store)
# https://f-droid.org/packages/com.termux/
# Atualize pacotes
pkg update && pkg upgrade
# Instale dependências
pkg install nodejs git
# Clone e instale
git clone https://github.com/synt-xerror/manybot
cd manybot
```
Siga os passos de configuração Linux a partir do passo 2.
---
## 🔧 Resolução de Problemas
### Erro ao escanear QR Code
- Limpe os dados do Chrome/Chromium do Termux
- Delete a pasta `session/` e tente novamente
### Bot não responde comandos
- Verifique o `CMD_PREFIX` no `manybot.conf`
- Confira se o plugin está na lista `PLUGINS`
### Erros de instalação
```bash
# Limpe a cache do npm
npm cache clean --force
# Reinstale dependências
rm -rf node_modules package-lock.json
npm install
```
---
## 📚 Próximos Passos
- [Configuração avançada](./CONFIGURACAO.md)
- [Criando plugins](./PLUGINS.md)

144
docs/INSTALLATION.md Normal file
View File

@@ -0,0 +1,144 @@
# Installation
Complete installation guide for ManyBot on different platforms.
---
## Index
- [Linux](#linux)
- [Windows](#windows)
- [Termux (Android)](#termux-android)
---
## Linux
### 1. Clone the repository
```bash
git clone https://github.com/synt-xerror/manybot
cd manybot
```
### 2. Configure the bot
Create the configuration file:
```bash
touch manybot.conf
nano manybot.conf
```
Example configuration:
```bash
# Comments with '#'
CLIENT_ID=bot_permanente
CMD_PREFIX=!
LANGUAGE=en
CHATS=[
123456789@c.us,
123456789@g.us
]
PLUGINS=[
video,
audio,
sticker,
guess
]
```
**Details:**
- `CLIENT_ID`: Session ID (default: `bot_permanente`)
- `CMD_PREFIX`: Command prefix (default: `!`)
- `LANGUAGE`: Bot language - `pt`, `en`, or `es` (default: `en`)
- `CHATS`: Allowed chat IDs (leave empty for all)
- `PLUGINS`: List of active plugins
### 3. Run installation
```bash
bash ./setup
```
### 4. First run
```bash
node ./src/main.js
```
Scan the QR Code in WhatsApp:
**Menu → Linked Devices → Link a Device**
---
## Windows
ManyBot was designed for Linux, but works on Windows via **Git Bash**.
### Prerequisites
1. **Git Bash**: https://git-scm.com/download/win
2. **Node.js**: https://nodejs.org (choose "Windows Installer (.msi)")
### Installation
After installing both, open **Git Bash** and follow the same steps as the [Linux installation](#linux).
---
## Termux (Android)
> ⚠️ **Warning:** Experimental support. No guarantee of functionality.
```bash
# Install Termux from F-Droid (don't use Play Store)
# https://f-droid.org/packages/com.termux/
# Update packages
pkg update && pkg upgrade
# Install dependencies
pkg install nodejs git
# Clone and install
git clone https://github.com/synt-xerror/manybot
cd manybot
```
Follow the Linux configuration steps from step 2.
---
## Troubleshooting
### QR Code scanning error
- Clear Chrome/Chromium data from Termux
- Delete the `session/` folder and try again
### Bot not responding to commands
- Check `CMD_PREFIX` in `manybot.conf`
- Make sure the plugin is in the `PLUGINS` list
### Installation errors
```bash
# Clean npm cache
npm cache clean --force
# Reinstall dependencies
rm -rf node_modules package-lock.json
npm install
```
---
## Next Steps
- [Advanced configuration](./CONFIGURATION.md)
- [Creating plugins](./PLUGINS_EN.md)

317
docs/PLUGINS (en).md Normal file
View File

@@ -0,0 +1,317 @@
# 🔌 Creating Plugins
Complete guide to creating plugins in ManyBot.
---
## 📑 Index
- [Basic Structure](#basic-structure)
- [Plugin Manifest](#plugin-manifest-manyplug-json)
- [Creating Your First Plugin](#creating-your-first-plugin)
- [Object API](#object-api)
- [Exposing API](#exposing-api-to-other-plugins)
- [Translating Your Plugin](#translating-your-plugin)
- [Error Handling](#error-handling)
---
## Basic Structure
```
src/plugins/
└── my-plugin/
├── index.js
├── manyplug.json
└── locale/ (optional)
├── en.json
├── pt.json
└── es.json
```
`index.js` must export a `default` function that receives `{ msg, api }`:
```javascript
export default async function ({ msg, api }) {
// Your logic here
}
```
---
## Plugin Manifest (manyplug.json)
Every plugin should have a `manyplug.json` at its root. It describes the plugin and declares any extra npm dependencies it needs.
```json
{
"name": "my-plugin",
"version": "1.0.0",
"category": "utility",
"service": false,
"dependencies": {}
}
```
### Fields
| Field | Type | Description |
|-------|------|-------------|
| `name` | `string` | Plugin identifier, must match the folder name |
| `version` | `string` | Semantic version (e.g., `"1.0.0"`) |
| `category` | `string` | Plugin category: `utility`, `media`, `game`, `humor`, `info` |
| `service` | `boolean` | `true` if the plugin runs in the background (scheduler, listener). `false` if triggered by a command or event |
| `dependencies` | `object` | Extra npm packages required by the plugin, same format as `package.json` |
### Example with dependencies
```json
{
"name": "weather",
"version": "1.0.0",
"category": "utility",
"service": false,
"dependencies": {
"axios": "^1.6.0"
}
}
```
After adding dependencies, run `npm install` at the project root to install them.
---
## Creating Your First Plugin
### Example 1: Simple command
```javascript
// plugins/greeting/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
// Only responds if the message starts with "!hi"
if (!msg.is(CMD_PREFIX + "hi")) return;
await msg.reply("Hello! 👋");
}
```
### Example 2: Command with arguments
```javascript
// plugins/calculate/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "calculate")) return;
// msg.args = ["!calculate", "5", "+", "3"]
const [, a, operator, b] = msg.args;
let result;
switch (operator) {
case "+": result = Number(a) + Number(b); break;
case "-": result = Number(a) - Number(b); break;
case "*": result = Number(a) * Number(b); break;
case "/": result = Number(a) / Number(b); break;
default: return msg.reply("Invalid operator!");
}
await msg.reply(`Result: ${result}`);
}
```
### Example 3: Processing media
```javascript
// plugins/echo-media/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "echo")) return;
// Checks if the message has media
if (!msg.hasMedia) {
return msg.reply("Send a media file with the command!");
}
// Downloads the media
const media = await msg.downloadMedia();
// Resends in the chat
await api.sendSticker(media.data);
}
```
---
## Object API
### `msg` Object
| Property | Type | Description |
|----------|------|-------------|
| `msg.body` | `string` | Message text |
| `msg.args` | `string[]` | Message tokens |
| `msg.type` | `string` | Type: `chat`, `image`, `video`, `audio`, `sticker` |
| `msg.sender` | `string` | Sender ID |
| `msg.senderName` | `string` | Sender name |
| `msg.fromMe` | `boolean` | Whether the bot sent it |
| `msg.hasMedia` | `boolean` | Whether it has media |
| `msg.hasReply` | `boolean` | Whether it is a reply |
| `msg.isGif` | `boolean` | Whether it is a GIF |
| `msg.is(cmd)` | `function` | Checks if starts with command |
| `msg.reply(text)` | `function` | Replies with quote |
| `msg.downloadMedia()` | `function` | Returns `{ mimetype, data }` |
| `msg.getReply()` | `function` | Returns quoted message |
### `api` Object
| Method | Description |
|--------|-------------|
| `api.send(text)` | Sends text |
| `api.sendVideo(path)` | Sends video |
| `api.sendAudio(path)` | Sends audio (voice) |
| `api.sendImage(path, caption?)` | Sends image |
| `api.sendSticker(bufferOrPath)` | Sends sticker |
| `api.getPlugin(name)` | Accesses another plugin |
| `api.chat.id` | Chat ID |
| `api.chat.name` | Chat name |
| `api.chat.isGroup` | Whether it is a group |
| `api.log.info(...)` | Info log |
| `api.log.warn(...)` | Warning log |
| `api.log.error(...)` | Error log |
---
## Exposing API to Other Plugins
A plugin can export functions for others to use:
```javascript
// plugins/utilities/index.js
// Public API
export const api = {
formatDate: (date) => date.toLocaleDateString("en-US"),
formatCurrency: (value) => `$${value.toFixed(2)}`,
wait: (ms) => new Promise(resolve => setTimeout(resolve, ms))
};
// Normal plugin logic
export default async function ({ msg }) {
if (msg.is("!ping")) {
await msg.reply("pong!");
}
}
```
Another plugin using it:
```javascript
// plugins/other/index.js
export default async function ({ msg, api }) {
const utils = api.getPlugin("utilities");
const date = utils.formatDate(new Date());
await msg.reply(`Today is ${date}`);
}
```
---
## Translating Your Plugin
Each plugin can have its own translations, completely independent from the bot core. The bot locale (set in `manybot.conf`) is used automatically.
### Structure
```
src/plugins/
└── my-plugin/
├── index.js
└── locale/
├── en.json
├── pt.json
└── es.json
```
### locale/en.json
```json
{
"hello": "Hello, {{name}}! 👋",
"error": {
"notFound": "Item not found."
}
}
```
### index.js
```javascript
import { CMD_PREFIX } from "../../config.js";
import { createPluginI18n } from "../../utils/pluginI18n.js";
const { t } = createPluginI18n(import.meta.url);
export default async function ({ msg }) {
if (!msg.is(CMD_PREFIX + "hi")) return;
// Simple key
await msg.reply(t("hello", { name: msg.senderName }));
// Nested key
await msg.reply(t("error.notFound"));
}
```
### Notes
- If the configured locale has no translation file, falls back to `en.json`.
- If the key doesn't exist in any file, the key itself is returned as-is.
- Use `{{variable}}` syntax for interpolation.
- Each plugin manages its own translations — never import `t` from the bot core.
---
## Error Handling
If a plugin throws an error, the kernel automatically disables it:
```javascript
export default async function ({ msg, api }) {
try {
// Code that might fail
const result = await somethingRisky();
await msg.reply(result);
} catch (error) {
// Logs the error and notifies
api.log.error("Plugin error:", error);
await msg.reply("Oops! Something went wrong.");
}
}
```
---
## Enabling the Plugin
After creating it, add to `manybot.conf`:
```bash
PLUGINS=[
# ... other plugins
my-plugin
]
```
Restart the bot to load it.
---
## See Also
- [API Reference](./API.md)
- [Plugin examples](../src/plugins/)

317
docs/PLUGINS.md Normal file
View File

@@ -0,0 +1,317 @@
# 🔌 Criando Plugins
Guia completo para criar plugins no ManyBot.
---
## 📑 Índice
- [Estrutura Básica](#estrutura-básica)
- [Manifesto do Plugin](#manifesto-do-plugin-manyplugjson)
- [Criando Seu Primeiro Plugin](#criando-seu-primeiro-plugin)
- [API de Objetos](#api-de-objetos)
- [Expondo API](#expondo-api-para-outros-plugins)
- [Traduzindo Seu Plugin](#traduzindo-seu-plugin)
- [Tratamento de Erros](#tratamento-de-erros)
---
## Estrutura Básica
```
src/plugins/
└── meu-plugin/
├── index.js
├── manyplug.json
└── locale/ (opcional)
├── en.json
├── pt.json
└── es.json
```
O `index.js` deve exportar uma função `default` que recebe `{ msg, api }`:
```javascript
export default async function ({ msg, api }) {
// Sua lógica aqui
}
```
---
## Manifesto do Plugin (manyplug.json)
Todo plugin deve ter um `manyplug.json` na raiz. Ele descreve o plugin e declara dependências npm extras que ele precisar.
```json
{
"name": "meu-plugin",
"version": "1.0.0",
"category": "utility",
"service": false,
"dependencies": {}
}
```
### Campos
| Campo | Tipo | Descrição |
|-------|------|-----------|
| `name` | `string` | Identificador do plugin, deve ser igual ao nome da pasta |
| `version` | `string` | Versão semântica (ex: `"1.0.0"`) |
| `category` | `string` | Categoria do plugin: `utility`, `media`, `game`, `humor`, `info` |
| `service` | `boolean` | `true` se o plugin roda em segundo plano (agendador, listener). `false` se acionado por comando ou evento |
| `dependencies` | `object` | Pacotes npm extras necessários, mesmo formato do `package.json` |
### Exemplo com dependências
```json
{
"name": "clima",
"version": "1.0.0",
"category": "utility",
"service": false,
"dependencies": {
"axios": "^1.6.0"
}
}
```
Após adicionar dependências, rode `npm install` na raiz do projeto para instalá-las.
---
## Criando Seu Primeiro Plugin
### Exemplo 1: Comando simples
```javascript
// plugins/saudacao/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
// Só responde se a mensagem começar com "!oi"
if (!msg.is(CMD_PREFIX + "oi")) return;
await msg.reply("Olá! 👋");
}
```
### Exemplo 2: Comando com argumentos
```javascript
// plugins/calcular/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "calcular")) return;
// msg.args = ["!calcular", "5", "+", "3"]
const [, a, operador, b] = msg.args;
let resultado;
switch (operador) {
case "+": resultado = Number(a) + Number(b); break;
case "-": resultado = Number(a) - Number(b); break;
case "*": resultado = Number(a) * Number(b); break;
case "/": resultado = Number(a) / Number(b); break;
default: return msg.reply("Operador inválido!");
}
await msg.reply(`Resultado: ${resultado}`);
}
```
### Exemplo 3: Processando mídia
```javascript
// plugins/echo-media/index.js
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "echo")) return;
// Verifica se a mensagem tem mídia
if (!msg.hasMedia) {
return msg.reply("Envie uma mídia com o comando!");
}
// Baixa a mídia
const media = await msg.downloadMedia();
// Reenvia no chat
await api.sendSticker(media.data);
}
```
---
## API de Objetos
### Objeto `msg`
| Propriedade | Tipo | Descrição |
|-------------|------|-----------|
| `msg.body` | `string` | Texto da mensagem |
| `msg.args` | `string[]` | Tokens da mensagem |
| `msg.type` | `string` | Tipo: `chat`, `image`, `video`, `audio`, `sticker` |
| `msg.sender` | `string` | ID do remetente |
| `msg.senderName` | `string` | Nome do remetente |
| `msg.fromMe` | `boolean` | Se o bot enviou |
| `msg.hasMedia` | `boolean` | Se tem mídia |
| `msg.hasReply` | `boolean` | Se é resposta |
| `msg.isGif` | `boolean` | Se é GIF |
| `msg.is(cmd)` | `function` | Verifica se começa com comando |
| `msg.reply(text)` | `function` | Responde com quote |
| `msg.downloadMedia()` | `function` | Retorna `{ mimetype, data }` |
| `msg.getReply()` | `function` | Retorna mensagem citada |
### Objeto `api`
| Método | Descrição |
|--------|-----------|
| `api.send(text)` | Envia texto |
| `api.sendVideo(path)` | Envia vídeo |
| `api.sendAudio(path)` | Envia áudio (voz) |
| `api.sendImage(path, caption?)` | Envia imagem |
| `api.sendSticker(bufferOrPath)` | Envia figurinha |
| `api.getPlugin(name)` | Acessa outro plugin |
| `api.chat.id` | ID do chat |
| `api.chat.name` | Nome do chat |
| `api.chat.isGroup` | Se é grupo |
| `api.log.info(...)` | Log informativo |
| `api.log.warn(...)` | Log de aviso |
| `api.log.error(...)` | Log de erro |
---
## Expondo API para Outros Plugins
Um plugin pode exportar funções para outros usarem:
```javascript
// plugins/utilidades/index.js
// API pública
export const api = {
formatarData: (date) => date.toLocaleDateString("pt-BR"),
formatarMoeda: (valor) => `R$ ${valor.toFixed(2).replace(".", ",")}`,
esperar: (ms) => new Promise(resolve => setTimeout(resolve, ms))
};
// Lógica normal do plugin
export default async function ({ msg }) {
if (msg.is("!ping")) {
await msg.reply("pong!");
}
}
```
Outro plugin usando:
```javascript
// plugins/outro/index.js
export default async function ({ msg, api }) {
const utils = api.getPlugin("utilidades");
const data = utils.formatarData(new Date());
await msg.reply(`Hoje é ${data}`);
}
```
---
## Traduzindo Seu Plugin
Cada plugin pode ter suas próprias traduções, completamente independentes do core do bot. O locale do bot (definido no `manybot.conf`) é usado automaticamente.
### Estrutura
```
src/plugins/
└── meu-plugin/
├── index.js
└── locale/
├── en.json
├── pt.json
└── es.json
```
### locale/pt.json
```json
{
"ola": "Olá, {{nome}}! 👋",
"erro": {
"naoEncontrado": "Item não encontrado."
}
}
```
### index.js
```javascript
import { CMD_PREFIX } from "../../config.js";
import { createPluginI18n } from "../../utils/pluginI18n.js";
const { t } = createPluginI18n(import.meta.url);
export default async function ({ msg }) {
if (!msg.is(CMD_PREFIX + "oi")) return;
// Chave simples
await msg.reply(t("ola", { nome: msg.senderName }));
// Chave aninhada
await msg.reply(t("erro.naoEncontrado"));
}
```
### Observações
- Se o locale configurado não tiver arquivo de tradução, cai automaticamente para `en.json`.
- Se a chave não existir em nenhum arquivo, a própria chave é retornada.
- Use a sintaxe `{{variavel}}` para interpolação.
- Cada plugin gerencia suas próprias traduções — nunca importe `t` do core do bot.
---
## Tratamento de Erros
Se um plugin lançar erro, o kernel o desativa automaticamente:
```javascript
export default async function ({ msg, api }) {
try {
// Código que pode falhar
const resultado = await algoPerigoso();
await msg.reply(resultado);
} catch (erro) {
// Loga o erro e notifica
api.log.error("Erro no plugin:", erro);
await msg.reply("Ops! Algo deu errado.");
}
}
```
---
## Ativando o Plugin
Depois de criar, adicione ao `manybot.conf`:
```bash
PLUGINS=[
# ... outros plugins
meu-plugin
]
```
Reinicie o bot para carregar.
---
## Veja Também
- [Referência da API](./API.md)
- [Exemplos de plugins](../src/plugins/)

267
man/man1/manybot-plugin.1 Normal file
View File

@@ -0,0 +1,267 @@
.TH MANYBOT-PLUGIN 1 "April 2026" "ManyBot 2.4.3" "User Commands"
.SH NAME
manybot-plugin \- ManyBot plugin development guide
.SH SYNOPSIS
.B manyplug.json
.I manifest file
.br
.I src/plugins/
.B plugin directory
.SH DESCRIPTION
ManyBot plugins extend the bot's functionality without modifying the core
kernel. The kernel connects to WhatsApp and distributes messages to plugins,
which decide how to respond.
.PP
Each plugin lives in its own folder under
.I src/plugins/
with a
.B manyplug.json
manifest file and an
.B index.js
entry point.
.SH PLUGIN STRUCTURE
.nf
src/plugins/
\(do__ my-plugin/
\(bu__ manyplug.json # Plugin manifest
\(bu__ index.js # Main entry point
\(bu__ locale/ # Translations (optional)
\(bu__ en.json
\(bu__ pt.json
\(bu__ es.json
.fi
.SH MANIFEST (manyplug.json)
Every plugin must include a manifest describing its metadata:
.PP
.nf
{
"name": "my-plugin",
"version": "1.0.0",
"category": "utility",
"service": false,
"dependencies": {
"axios": "^1.6.0"
}
}
.fi
.TP
.B name
Plugin identifier. Must match the folder name.
.TP
.B version
Semantic version (e.g., "1.0.0").
.TP
.B category
Plugin type: \fButility\fR, \fBmedia\fR, \fBgame\fR, \fBhumor\fR, or \fBinfo\fR.
.TP
.B service
\fBtrue\fR for background plugins (schedulers, listeners).
\fBfalse\fR for command/event-triggered plugins.
.TP
.B dependencies
Extra npm packages required. Install with \fBnpm install\fR from project root.
.SH PLUGIN ENTRY POINT
The
.I index.js
file must export a default async function:
.PP
.nf
.B "export default async function ({ msg, api }) {"
// Plugin logic here
.B "}"
.fi
.SS Parameters
.TP
.B msg
Message object containing:
.RS
.IP \(bu 2
\fBbody\fR - Full message text
.IP \(bu 2
\fBargs\fR - Array of message tokens
.IP \(bu 2
\fBtype\fR - Message type: chat, image, video, audio, sticker, ptt, document, location
.IP \(bu 2
\fBsender\fR - Sender ID (NUMBER@c.us or NUMBER@g.us)
.IP \(bu 2
\fBsenderName\fR - Display name
.IP \(bu 2
\fBfromMe\fR - True if bot sent the message
.IP \(bu 2
\fBhasMedia\fR - True if contains media
.IP \(bu 2
\fBhasReply\fR - True if it's a reply
.IP \(bu 2
\fBisGif\fR - True if media is GIF
.IP \(bu 2
\fBtimestamp\fR - Unix timestamp
.IP \(bu 2
\fBis(cmd)\fR - Check if message starts with command
.IP \(bu 2
\fBreply(text)\fR - Reply with quote
.IP \(bu 2
\fBdownloadMedia()\fR - Download media (returns {mimetype, data})
.IP \(bu 2
\fBgetReply()\fR - Get quoted message object
.RE
.TP
.B api
API object containing:
.RS
.IP \(bu 2
\fBsend(text)\fR - Send text message
.IP \(bu 2
\fBsendVideo(path)\fR - Send video file
.IP \(bu 2
\fBsendAudio(path)\fR - Send audio as voice message
.IP \(bu 2
\fBsendImage(path, caption?)\fR - Send image with optional caption
.IP \(bu 2
\fBsendSticker(bufferOrPath)\fR - Send sticker from buffer or file
.IP \(bu 2
\fBgetPlugin(name)\fR - Access another plugin's public API
.IP \(bu 2
\fBchat\fR - Chat info: \fBid\fR, \fBname\fR, \fBisGroup\fR
.IP \(bu 2
\fBlog.info(...), log.warn(...), log.error(...)\fR - Logging methods
.RE
.SH EXAMPLES
.SS Simple Command
.nf
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "hi")) return;
await msg.reply("Hello! 👋");
}
.fi
.SS Command with Arguments
.nf
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "calc")) return;
const [, a, op, b] = msg.args;
let result;
switch (op) {
case "+": result = Number(a) + Number(b); break;
case "-": result = Number(a) - Number(b); break;
default: return msg.reply("Invalid operator!");
}
await msg.reply(`Result: ${result}`);
}
.fi
.SS Processing Media
.nf
import { CMD_PREFIX } from "../../config.js";
export default async function ({ msg, api }) {
if (!msg.is(CMD_PREFIX + "echo")) return;
if (!msg.hasMedia) {
return msg.reply("Send media with the command!");
}
const media = await msg.downloadMedia();
await api.sendSticker(media.data);
}
.fi
.SS Exposing API to Other Plugins
.nf
// Public API for other plugins
export const api = {
formatDate: (d) => d.toLocaleDateString("en-US"),
wait: (ms) => new Promise(r => setTimeout(r, ms))
};
// Normal plugin logic
export default async function ({ msg }) {
if (msg.is("!ping")) await msg.reply("pong!");
}
.fi
.PP
Used by another plugin:
.nf
export default async function ({ msg, api }) {
const utils = api.getPlugin("utilities");
const date = utils.formatDate(new Date());
await msg.reply(`Today is ${date}`);
}
.fi
.SH TRANSLATIONS
Plugins can include their own translations:
.PP
.nf
import { createPluginI18n } from "../../utils/pluginI18n.js";
const { t } = createPluginI18n(import.meta.url);
export default async function ({ msg }) {
if (!msg.is(CMD_PREFIX + "hello")) return;
await msg.reply(t("greeting", { name: msg.senderName }));
}
.fi
.PP
Locale file (\fIlocale/en.json\fR):
.nf
{
"greeting": "Hello, {{name}}! 👋"
}
.fi
.PP
If the configured locale has no translation file, falls back to \fBen.json\fR.
Use \fB{{variable}}\fR syntax for interpolation.
.SH ENABLING A PLUGIN
Add the plugin folder name to
.I manybot.conf R:
.PP
.nf
PLUGINS=[
many,
figurinha,
my-plugin
]
.fi
.PP
Restart ManyBot to load the plugin.
.SH ERROR HANDLING
If a plugin throws an error, the kernel automatically disables it.
Use try/catch for graceful error handling:
.PP
.nf
export default async function ({ msg, api }) {
try {
const result = await riskyOperation();
await msg.reply(result);
} catch (error) {
api.log.error("Plugin error:", error);
await msg.reply("Oops! Something went wrong.");
}
}
.fi
.SH CONFIGURATION ACCESS
Import settings from the main config:
.PP
.nf
import { CMD_PREFIX, CLIENT_ID, CHATS, PLUGINS } from "../../config.js";
// Custom config values also work
import { MY_API_KEY } from "../../config.js";
.fi
.PP
Add custom values to
.I manybot.conf R:
.nf
MY_API_KEY=secret_key_here
.fi
.SH SEE ALSO
.BR manybot (1),
.BR manyplug (1),
.BR manybot.conf (5)
.SH AUTHOR
Written by synt-xerror.
.SH REPORTING BUGS
Report bugs at: https://github.com/synt-xerror/manybot/issues

171
man/man1/manybot.1 Normal file
View File

@@ -0,0 +1,171 @@
.TH MANYBOT 1 "April 2026" "ManyBot 2.4.3" "User Commands"
.SH NAME
manybot \- local WhatsApp bot with plugin system
.SH SYNOPSIS
.B node
.I ./src/main.js
.br
.B node
.I src/utils/get_id.js
.br
.B bash
.I ./setup
.br
.B bash
.I ./update
.SH DESCRIPTION
ManyBot is a 100%% local WhatsApp bot that operates without relying on the
official WhatsApp API. It uses whatsapp-web.js to connect as a regular
WhatsApp client and provides a modular plugin system for extending functionality.
.PP
The bot supports multiple chats in a single session, runs headless (without
a GUI), and can be configured through a simple configuration file.
.SH COMMANDS
.TP
.B !many
List all available commands from loaded plugins.
.TP
.B !figurinha
Convert images, GIFs, and videos to stickers.
.TP
.B !video \fIURL\fR
Download videos from supported platforms.
.TP
.B !audio \fIURL\fR
Download audio from videos and send as voice message.
.TP
.B !adivinhacao comecar
Start a guessing game (1-100).
.TP
.B !forca comecar
Start a hangman game.
.TP
.B !obrigado
Bot responds with a thank-you message.
.PP
Command prefix can be configured via
.B CMD_PREFIX
in
.IR manybot.conf .
Default is
.BR ! .
.SH CONFIGURATION
ManyBot uses a configuration file
.I manybot.conf
in the project root. Key options:
.TP
.B CLIENT_ID=\fIname\fR
Unique identifier for the bot session. Creates a session/\fIname\fR folder
for authentication data. Default: \fIbot_permanente\fR.
.TP
.B CMD_PREFIX=\fIchar\fR
Character prefixing all commands. Default: \fI!\fR.
.TP
.B LANGUAGE=\fIcode\fR
Bot interface language: \fBen\fR (English), \fBpt\fR (Portuguese), or \fBes\fR (Spanish).
Default: \fBen\fR.
.TP
.B CHATS=[\fIid1\fR, \fIid2\fR, ...]
List of allowed chat IDs. Empty array allows all chats.
Format: \fBnumber@c.us\fR for private chats, \fBnumber@g.us\fR for groups.
.TP
.B PLUGINS=[\fIname1\fR, \fIname2\fR, ...]
List of plugins to load at startup. Each name corresponds to a folder in
.IR src/plugins/ .
.PP
See
.BR manybot.conf (5)
for complete configuration reference.
.SH PLUGINS
Plugins extend ManyBot functionality without modifying the kernel. Each plugin
is a folder under
.I src/plugins/
containing:
.TP
.I index.js
Main plugin file exporting a default async function receiving \fB{ msg, api }\fR.
.TP
.I manyplug.json
Plugin manifest describing name, version, category, service status, and dependencies.
.TP
.I locale/
Optional translation files (\fBen.json\fR, \fBpt.json\fR, \fBes.json\fR).
.PP
Plugins receive two objects:
.TP
.B msg
Message information including \fBbody\fR, \fBargs\fR, \fBtype\fR, \fBsender\fR,
\fBhasMedia\fR, methods \fBis()\fR, \fBreply()\fR, \fBdownloadMedia()\fR.
.TP
.B api
Interaction methods including \fBsend()\fR, \fBsendVideo()\fR, \fBsendAudio()\fR,
\fBsendImage()\fR, \fBsendSticker()\fR, \fBgetPlugin()\fR, and \fBlog\fR methods.
.SH FILES
.TP
.I manybot.conf
Main configuration file. See \fBmanybot.conf(5)\fR.
.TP
.I session/
Authentication data and WhatsApp session storage.
.TP
.I src/plugins/
Plugin directory containing all installed plugins.
.TP
.I src/main.js
Bot entry point.
.TP
.I logs/
Log files directory.
.TP
.I update.log
Update script log output.
.SH ENVIRONMENT
.TP
.B NODE_ENV
Set to \fBproduction\fR to disable development features.
.SH EXIT STATUS
.TP
.B 0
Success
.TP
.B 1
General error
.TP
.B 130
Interrupted by user (Ctrl+C)
.SH EXAMPLES
.SS First run
.nf
$ node ./src/main.js
# Scan QR code with WhatsApp:
# Menu \-> Linked Devices \-> Link a Device
.fi
.SS Get chat IDs
.nf
$ node src/utils/get_id.js
# Send a message in the target chat to see the ID
.fi
.SS Update to latest version
.nf
$ bash ./update
.fi
.SH SECURITY
\(bu Bot runs with same privileges as the user running it
.br
\(bu Session data stored in \fIsession/\fR should be protected (chmod 700)
.br
\(bu CHATS whitelist recommended to limit bot exposure
.br
\(bu No official WhatsApp API keys required or used
.SH SEE ALSO
.BR manybot.conf (5),
.BR manybot-plugin (1),
.BR manyplug (1)
.SH AUTHOR
Written by synt-xerror.
.SH COPYRIGHT
Licensed under GPLv3. See LICENSE file for details.
.br
https://github.com/synt-xerror/manybot
.SH BUGS
Report bugs at: https://github.com/synt-xerror/manybot/issues

225
man/man5/manybot.conf.5 Normal file
View File

@@ -0,0 +1,225 @@
.TH MANYBOT.CONF 5 "April 2026" "ManyBot 2.4.3" "File Formats"
.SH NAME
manybot.conf \- ManyBot configuration file
.SH SYNOPSIS
.I manybot.conf
.SH DESCRIPTION
The
.I manybot.conf
file configures the ManyBot WhatsApp bot. It uses a simple key-value format
with support for multiline lists. Comments start with \fB#\fR.
.PP
The file must be located in the project root directory, alongside
.IR package.json .
.SH FORMAT
.nf
# Comments start with '#'
KEY=value
KEY=[item1, item2, item3]
.fi
.SS Key-Value Pairs
Simple configuration values:
.PP
.nf
CLIENT_ID=my_bot
CMD_PREFIX=!
LANGUAGE=en
.fi
.SS Multiline Lists
Arrays spanning multiple lines:
.PP
.nf
CHATS=[
123456789@c.us,
123456789@g.us
]
PLUGINS=[
many,
figurinha,
audio,
video
]
.fi
.SH OPTIONS
.SS Core Settings
.TP
.B CLIENT_ID=\fIstring\fR
Unique identifier for the bot session.
.RS
.IP \(bu 2
Default: \fBbot_permanente\fR
.IP \(bu 2
Creates a \fIsession/CLIENT_ID/\fR folder for authentication data
.IP \(bu 2
Changing this starts a new session (requires QR code rescan)
.RE
.TP
.B CMD_PREFIX=\fIcharacter\fR
Character that prefixes all bot commands.
.RS
.IP \(bu 2
Default: \fB!\fR
.IP \(bu 2
Example: \fB!\fR makes commands like \fB!video\fR, \fB!audio\fR
.IP \(bu 2
Changing to \fB.\fR would make commands \fB.video\fR, \fB.audio\fR
.RE
.TP
.B LANGUAGE=\fIcode\fR
Bot interface language.
.RS
.IP \(bu 2
Default: \fBen\fR (English)
.IP \(bu 2
Options: \fBen\fR, \fBpt\fR (Portuguese), \fBes\fR (Spanish)
.IP \(bu 2
Fallback to English if selected language not found
.RE
.SS Chat Settings
.TP
.B CHATS=[\fIid1\fR, \fIid2\fR, ...]
Whitelist of chat IDs where the bot responds.
.RS
.IP \(bu 2
Default: \fB[]\fR (empty = respond to all chats)
.IP \(bu 2
Private chat format: \fBnumber@c.us\fR
.IP \(bu 2
Group format: \fBnumber@g.us\fR or \fBnumber-number@g.us\fR
.IP \(bu 2
Use \fBnode src/utils/get_id.js\fR to discover chat IDs
.RE
.SS Plugin Settings
.TP
.B PLUGINS=[\fIname1\fR, \fIname2\fR, ...]
List of plugins to load at startup.
.RS
.IP \(bu 2
Default: \fB[]\fR (no plugins loaded)
.IP \(bu 2
Each name must match a folder in \fIsrc/plugins/\fR
.IP \(bu 2
Order matters: plugins load in listed order
.IP \(bu 2
Comment out or remove to disable without deleting files
.RE
.SS Built-in Plugins
.TP
.B many
Lists all available commands. Required for \fB!many\fR to work.
.TP
.B figurinha
Converts images/GIFs/videos to WhatsApp stickers.
.TP
.B video
Downloads videos from URLs.
.TP
.B audio
Downloads audio from videos as voice messages.
.TP
.B adivinha\(,c\(oao
Guessing game (1-100).
.TP
.B forca
Hangman game.
.TP
.B obrigado
Responds to thank-you messages.
.SH CUSTOM SETTINGS
You can add any custom key-value pairs for use by plugins:
.PP
.nf
# In manybot.conf
ADMIN_NUMBER=5511999999999@c.us
API_KEY=your_secret_key
MAX_DOWNLOAD_SIZE=50MB
.fi
.PP
Access in plugins:
.nf
import { ADMIN_NUMBER, API_KEY, MAX_DOWNLOAD_SIZE } from "../../config.js";
.fi
.SH EXAMPLES
.SS Minimal Configuration
.nf
# Basic bot setup
CLIENT_ID=my_bot
CMD_PREFIX=!
LANGUAGE=en
PLUGINS=[
many
]
.fi
.SS Production Configuration
.nf
# Production bot with whitelist
CLIENT_ID=bot_prod
CMD_PREFIX=/
LANGUAGE=pt
CHATS=[
5511999999999@c.us,
5511888888888-123456789@g.us
]
PLUGINS=[
many,
figurinha,
video,
audio,
obrigado
]
# Custom settings
ADMIN_NUMBER=5511999999999@c.us
LOG_LEVEL=info
.fi
.SS Development Configuration
.nf
# Debug/development setup
CLIENT_ID=bot_dev
CMD_PREFIX=!
LANGUAGE=en
# Respond to all chats
CHATS=[]
# All plugins for testing
PLUGINS=[
many,
figurinha,
video,
audio,
adivinha\(,c\(oao,
forca,
obrigado
]
.fi
.SH FILES
.TP
.I manybot.conf
Main configuration file (must be created by user)
.TP
.I manybot.conf.example
Example configuration with documentation comments
.SH NOTES
\(bu Keys are case-sensitive
.br
\(bu Values are read as strings unless they're list syntax
.br
\(bu Inline comments supported: \fBKEY=value # comment\fR
.br
\(bu Multiline lists must end with \fB]\fR on its own line or last item line
.br
\(bu Whitespace in values is trimmed
.br
\(u Missing optional values use built-in defaults
.SH SEE ALSO
.BR manybot (1),
.BR manybot-plugin (1),
.BR manyplug (1)
.SH AUTHOR
Written by synt-xerror.

30
manybot.conf.example Normal file
View File

@@ -0,0 +1,30 @@
# ManyBot Configuration File
# Copy this file to manybot.conf and customize as needed
# Bot identification
CLIENT_ID=meu_bot
# Command prefix (default: !)
CMD_PREFIX=!
# Language setting (en, pt, es)
# Default: en (English)
LANGUAGE=en
# Allowed chats (leave empty for all chats)
# Format: chatId1@g.us, chatId2@g.us for groups
# Format: number@c.us for private chats
CHATS=[
]
# Active plugins
PLUGINS=[
many,
figurinha,
audio,
video,
adivinhação,
forca,
obrigado,
a
]

660
package-lock.json generated
View File

@@ -14,6 +14,9 @@
"qrcode-terminal": "^0.12.0",
"wa-sticker-formatter": "^4.4.4",
"whatsapp-web.js": "^1.24.0"
},
"devDependencies": {
"conventional-changelog-cli": "^5.0.0"
}
},
"node_modules/@babel/code-frame": {
@@ -39,6 +42,33 @@
"node": ">=6.9.0"
}
},
"node_modules/@conventional-changelog/git-client": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.6.0.tgz",
"integrity": "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@simple-libs/child-process-utils": "^1.0.0",
"@simple-libs/stream-utils": "^1.2.0",
"semver": "^7.5.2"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"conventional-commits-filter": "^5.0.0",
"conventional-commits-parser": "^6.3.0"
},
"peerDependenciesMeta": {
"conventional-commits-filter": {
"optional": true
},
"conventional-commits-parser": {
"optional": true
}
}
},
"node_modules/@gar/promise-retry": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.2.tgz",
@@ -51,6 +81,16 @@
"node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/@hutson/parse-repository-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-5.0.0.tgz",
"integrity": "sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/@isaacs/fs-minipass": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
@@ -127,6 +167,35 @@
"node": ">=18"
}
},
"node_modules/@simple-libs/child-process-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz",
"integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@simple-libs/stream-utils": "^1.2.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://ko-fi.com/dangreen"
}
},
"node_modules/@simple-libs/stream-utils": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz",
"integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://ko-fi.com/dangreen"
}
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
@@ -149,6 +218,13 @@
"undici-types": "~7.18.0"
}
},
"node_modules/@types/normalize-package-data": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/yauzl": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
@@ -180,6 +256,13 @@
"node": ">=6.5"
}
},
"node_modules/add-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
"integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
"dev": true,
"license": "MIT"
},
"node_modules/agent-base": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
@@ -293,6 +376,13 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/array-ify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
"integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
"dev": true,
"license": "MIT"
},
"node_modules/ast-types": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
@@ -746,6 +836,17 @@
"simple-swizzle": "^0.2.2"
}
},
"node_modules/compare-func": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
"integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"array-ify": "^1.0.0",
"dot-prop": "^5.1.0"
}
},
"node_modules/compress-commons": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
@@ -769,6 +870,227 @@
"license": "MIT",
"optional": true
},
"node_modules/conventional-changelog": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-6.0.0.tgz",
"integrity": "sha512-tuUH8H/19VjtD9Ig7l6TQRh+Z0Yt0NZ6w/cCkkyzUbGQTnUEmKfGtkC9gGfVgCfOL1Rzno5NgNF4KY8vR+Jo3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"conventional-changelog-angular": "^8.0.0",
"conventional-changelog-atom": "^5.0.0",
"conventional-changelog-codemirror": "^5.0.0",
"conventional-changelog-conventionalcommits": "^8.0.0",
"conventional-changelog-core": "^8.0.0",
"conventional-changelog-ember": "^5.0.0",
"conventional-changelog-eslint": "^6.0.0",
"conventional-changelog-express": "^5.0.0",
"conventional-changelog-jquery": "^6.0.0",
"conventional-changelog-jshint": "^5.0.0",
"conventional-changelog-preset-loader": "^5.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-angular": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.0.tgz",
"integrity": "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==",
"dev": true,
"license": "ISC",
"dependencies": {
"compare-func": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-atom": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-5.1.0.tgz",
"integrity": "sha512-fw7GpI9jHNCWGBnTsPRI452ypQbNupGwsjrXfozvRNE0c92pJRpoj9rXfzDKUYJcsmk0H4XKaQjhjelwI9z27w==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-cli": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-5.0.0.tgz",
"integrity": "sha512-9Y8fucJe18/6ef6ZlyIlT2YQUbczvoQZZuYmDLaGvcSBP+M6h+LAvf7ON7waRxKJemcCII8Yqu5/8HEfskTxJQ==",
"deprecated": "This package is no longer maintained. Please use the conventional-changelog package instead.",
"dev": true,
"license": "MIT",
"dependencies": {
"add-stream": "^1.0.0",
"conventional-changelog": "^6.0.0",
"meow": "^13.0.0",
"tempfile": "^5.0.0"
},
"bin": {
"conventional-changelog": "cli.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-codemirror": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-5.1.0.tgz",
"integrity": "sha512-iXhy63YczB+yWA9DrsYbquSYLvWKsK9M3WC+xQPEm8cOn4oXzKpmTp2uH3qi7+i10oTcGJTvq9lsBpZmMADaNg==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-conventionalcommits": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-8.0.0.tgz",
"integrity": "sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA==",
"dev": true,
"license": "ISC",
"dependencies": {
"compare-func": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-core": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-8.0.0.tgz",
"integrity": "sha512-EATUx5y9xewpEe10UEGNpbSHRC6cVZgO+hXQjofMqpy+gFIrcGvH3Fl6yk2VFKh7m+ffenup2N7SZJYpyD9evw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@hutson/parse-repository-url": "^5.0.0",
"add-stream": "^1.0.0",
"conventional-changelog-writer": "^8.0.0",
"conventional-commits-parser": "^6.0.0",
"git-raw-commits": "^5.0.0",
"git-semver-tags": "^8.0.0",
"hosted-git-info": "^7.0.0",
"normalize-package-data": "^6.0.0",
"read-package-up": "^11.0.0",
"read-pkg": "^9.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-ember": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-5.1.0.tgz",
"integrity": "sha512-XNcgGcdJt7wh341BBML0CI8DKpqE5lKD1WahzFHGZFvKTzJr1rZW976cw7beqKLOBbzdrH9ZIkE/s2TfbOuM3g==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-eslint": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-6.1.0.tgz",
"integrity": "sha512-beWr3qzuEMN9gznMWa8PhTVfGkGXoq+XnUzViNXg5KygrgV728ZRqZngz3uPhz5+ayUhPrpNFYqIE0qHWz9NAw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-express": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-5.1.0.tgz",
"integrity": "sha512-g/s9eLohrefYTSNQaB6+k0ONbiVx41YOKBbIOIM3ST/NtedAgppCJnrpKXVN9sOmpPkN4vjFwURlfvpEDUjoeg==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-jquery": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-6.1.0.tgz",
"integrity": "sha512-/sFhULybhFrMg+qc8MHHHSj7kTVMfx5C7rSM6Z9EjduVoAQJdGRq/wpv/SWPMQ+KPNSYHqDLwm/x2Z5hOcYvqQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-jshint": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-5.2.0.tgz",
"integrity": "sha512-OaatyvHXP1fjI7Mx0b1IkmhbhTsVHsytnsQSkOj4rhGbFMoTcfvbwm/vAtCzRMXOxojK1EDMBBmBj1pM9KNy/Q==",
"dev": true,
"license": "ISC",
"dependencies": {
"compare-func": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-preset-loader": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-5.0.0.tgz",
"integrity": "sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-changelog-writer": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.4.0.tgz",
"integrity": "sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@simple-libs/stream-utils": "^1.2.0",
"conventional-commits-filter": "^5.0.0",
"handlebars": "^4.7.7",
"meow": "^13.0.0",
"semver": "^7.5.2"
},
"bin": {
"conventional-changelog-writer": "dist/cli/index.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-commits-filter": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz",
"integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/conventional-commits-parser": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.3.0.tgz",
"integrity": "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@simple-libs/stream-utils": "^1.2.0",
"meow": "^13.0.0"
},
"bin": {
"conventional-commits-parser": "dist/cli/index.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -908,6 +1230,19 @@
"integrity": "sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==",
"license": "BSD-3-Clause"
},
"node_modules/dot-prop": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
"integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-obj": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
@@ -1156,6 +1491,19 @@
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
}
},
"node_modules/find-up-simple": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
"integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/fluent-ffmpeg": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
@@ -1289,6 +1637,40 @@
"node": ">= 14"
}
},
"node_modules/git-raw-commits": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz",
"integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@conventional-changelog/git-client": "^2.6.0",
"meow": "^13.0.0"
},
"bin": {
"git-raw-commits": "src/cli.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/git-semver-tags": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-8.0.1.tgz",
"integrity": "sha512-zMbamckSNdlT4U48IMFa2Cn6FTzM+2yF6/gEmStPJI8PiLxd/bT6dw10+mc6u5Qe4fhrc/y9nU290FWjQhAV7g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@conventional-changelog/git-client": "^2.6.0",
"meow": "^13.0.0"
},
"bin": {
"git-semver-tags": "src/cli.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -1323,6 +1705,48 @@
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
"node_modules/handlebars": {
"version": "4.7.9",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz",
"integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.5",
"neo-async": "^2.6.2",
"source-map": "^0.6.1",
"wordwrap": "^1.0.0"
},
"bin": {
"handlebars": "bin/handlebars"
},
"engines": {
"node": ">=0.4.7"
},
"optionalDependencies": {
"uglify-js": "^3.1.4"
}
},
"node_modules/hosted-git-info": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
"integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
"dev": true,
"license": "ISC",
"dependencies": {
"lru-cache": "^10.0.1"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/hosted-git-info/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/http-cache-semantics": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
@@ -1432,6 +1856,19 @@
"node": ">=0.8.19"
}
},
"node_modules/index-to-position": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz",
"integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -1480,6 +1917,16 @@
"node": ">=8"
}
},
"node_modules/is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -1654,6 +2101,19 @@
"node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/meow": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
"integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
@@ -1868,6 +2328,13 @@
"node": ">= 0.6"
}
},
"node_modules/neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true,
"license": "MIT"
},
"node_modules/netmask": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
@@ -1984,6 +2451,21 @@
"node": "^20.17.0 || >=22.9.0"
}
},
"node_modules/normalize-package-data": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz",
"integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"hosted-git-info": "^7.0.0",
"semver": "^7.3.5",
"validate-npm-package-license": "^3.0.4"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -2334,6 +2816,62 @@
"rc": "cli.js"
}
},
"node_modules/read-package-up": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
"integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"find-up-simple": "^1.0.0",
"read-pkg": "^9.0.0",
"type-fest": "^4.6.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-pkg": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
"integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/normalize-package-data": "^2.4.3",
"normalize-package-data": "^6.0.0",
"parse-json": "^8.0.0",
"type-fest": "^4.6.0",
"unicorn-magic": "^0.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-pkg/node_modules/parse-json": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz",
"integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.26.2",
"index-to-position": "^1.1.0",
"type-fest": "^4.39.1"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -2673,12 +3211,48 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"devOptional": true,
"license": "BSD-3-Clause",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
"integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"spdx-expression-parse": "^3.0.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-exceptions": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
"dev": true,
"license": "CC-BY-3.0"
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-license-ids": {
"version": "3.0.23",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz",
"integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/ssri": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz",
@@ -2830,6 +3404,32 @@
"streamx": "^2.12.5"
}
},
"node_modules/temp-dir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz",
"integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.16"
}
},
"node_modules/tempfile": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/tempfile/-/tempfile-5.0.0.tgz",
"integrity": "sha512-bX655WZI/F7EoTDw9JvQURqAXiPHi8o8+yFxPF2lWYyz1aHnmMRuXWqL6YB6GmeO0o4DIYWHLgGNi/X64T+X4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"temp-dir": "^3.0.0"
},
"engines": {
"node": ">=14.18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/text-decoder": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
@@ -2906,12 +3506,39 @@
"node": "*"
}
},
"node_modules/type-fest": {
"version": "4.41.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
"integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typed-query-selector": {
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz",
"integrity": "sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==",
"license": "MIT"
},
"node_modules/uglify-js": {
"version": "3.19.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
"integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
"dev": true,
"license": "BSD-2-Clause",
"optional": true,
"bin": {
"uglifyjs": "bin/uglifyjs"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/undici-types": {
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
@@ -2919,6 +3546,19 @@
"license": "MIT",
"optional": true
},
"node_modules/unicorn-magic": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
"integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/unique-filename": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz",
@@ -3010,6 +3650,17 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"spdx-correct": "^3.0.0",
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/wa-sticker-formatter": {
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/wa-sticker-formatter/-/wa-sticker-formatter-4.4.4.tgz",
@@ -3087,6 +3738,13 @@
"which": "bin/which"
}
},
"node_modules/wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",

View File

@@ -9,5 +9,11 @@
"qrcode-terminal": "^0.12.0",
"wa-sticker-formatter": "^4.4.4",
"whatsapp-web.js": "^1.24.0"
},
"devDependencies": {
"conventional-changelog-cli": "^5.0.0"
},
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
}
}