update documentation and remove systemd support
This commit is contained in:
370
README.md
370
README.md
@@ -1,308 +1,188 @@
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
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)
|
||||
|
||||

|
||||
|
||||
</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
188
README_EN.md
Normal file
@@ -0,0 +1,188 @@
|
||||
<div align="center">
|
||||
|
||||

|
||||
|
||||
<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)
|
||||
|
||||

|
||||
|
||||
</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>
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
277
docs/API (en).md
Normal 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
277
docs/API.md
Normal 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
146
docs/CONFIGURACAO.md
Normal 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
146
docs/CONFIGURATION.md
Normal 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
144
docs/INSTALACAO.md
Normal 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
144
docs/INSTALLATION.md
Normal 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
317
docs/PLUGINS (en).md
Normal 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
317
docs/PLUGINS.md
Normal 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
267
man/man1/manybot-plugin.1
Normal 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.confR:
|
||||
.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.confR:
|
||||
.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
171
man/man1/manybot.1
Normal 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
225
man/man5/manybot.conf.5
Normal 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
30
manybot.conf.example
Normal 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
660
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user