Files
manybot/docs/PLUGINS.md
2026-04-21 11:48:41 -03:00

8.3 KiB

🔌 Criando Plugins

Guia completo para criar plugins no ManyBot.


ManyPlug CLI

ManyPlug é a ferramenta oficial para gerenciar plugins do ManyBot. Com ela você pode criar, instalar e validar plugins facilmente.

Instalação

npm install -g @freakk.dev/manyplug

Ou para desenvolvimento:

git clone https://git.maneos.net/synt-xerror/manyplug
cd manyplug
npm link

Comandos

Comando Descrição
manyplug init <nome> Cria estrutura de um novo plugin
manyplug install [nome] Instala do registro ou --local <caminho>
manyplug list Lista plugins instalados
manyplug validate [caminho] Valida o manyplug.json

Exemplos

# Criar novo plugin
cd src/plugins
manyplug init meu-plugin --category utility

# Instalar de outro diretório
manyplug install --local ../outro-plugin

# Validar manifesto
manyplug validate ./meu-plugin

📑 Índice


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 }:

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.

{
  "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

{
  "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

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

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

// 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:

// 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:

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

{
  "ola": "Olá, {{nome}}! 👋",
  "erro": {
    "naoEncontrado": "Item não encontrado."
  }
}

index.js

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:

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:

PLUGINS=[
    # ... outros plugins
    meu-plugin
]

Reinicie o bot para carregar.


Veja Também