Usar un plugin
config lo tipa el plugin (definePlugin<MiConfig>()): una opción
desconocida es un error de compilación, y una configuración declarada con la
interfaz de configuración del plugin se pasa tal cual.
bot.plug(plugin, config?) devuelve una función unplug (no el bot, así
que las llamadas a plug() no se encadenan). Al llamarla, primero ejecuta el
uninstall(ctx) del plugin, si lo tiene, y después revierte, de lo más nuevo
a lo más antiguo, lo que el plugin registró vía ctx.bot:
- comandos (
command()), matchers (when(),onMessage(),onType()), conversaciones y disparadores de flows (conversation(),use(flow)); - hooks (
before(),after(),onError(),hook()); - plugins anidados (
ctx.bot.plug()); - flows registrados en caliente con
ctx.bot.registerFlow(), o creados (no reemplazados) conctx.bot.replaceFlow(); - cada callback de
ctx.onDispose(fn).
ctx.bot.on() / once()),
herramientas inyectadas (ctx.bot.provide() / ctx.tools), mensajes de
idioma (ctx.bot.locale()), tareas programadas (schedule(), every(),
delay()), handlers de inactividad (onIdle()), un flow que replaceFlow()
sobrescribió (no se restaura), el estado de handoff, escrituras en el store ni
timers o conexiones propios. Deshazlos en ctx.onDispose() (o en
uninstall()). Llamar a unplug dos veces no hace nada. Si install() lanza de
forma síncrona, lo que alcanzó a registrar se revierte antes de que el error te
llegue; si devuelve una promesa que rechaza, el rechazo va al evento 'error'
y no se revierte nada.
Dependencias entre plugins (requires)
Un plugin puede listar por nombre los plugins que necesita. bot.plug() los
comprueba antes de ejecutar install() y lanza un error descriptivo si falta
alguno:
inbox después no
desenchufa crm. Un plugin anidado dentro de otro (ctx.bot.plug() desde
install()) puede requerir a su padre.
Una instancia por nombre (multiple)
bot.plug() rechaza un plugin cuyo name ya está enchufado en el bot, así un
plugin registrado dos veces por error nunca ejecuta sus handlers dos veces:
multiple: true en su spec (todas las instancias deben ponerlo). Cada
instancia se desenchufa por separado y cualquiera de ellas cumple requires.
Incluido: slashCommands
Config:{ greeting?: string; unknownMessage?: string }. El prefijo de
comandos es una opción del bot (new Bot({ commandPrefix })), no del
plugin. Las respuestas son textos internos en el
idioma del bot.
Los
/comandos desconocidos reciben automáticamente una respuesta de
“comando desconocido” (unknownMessage).
Crear un plugin
Plugin simple
Plugin configurable con cleanup
Estructura de un plugin
definePlugin(spec) devuelve el spec sin cambios, tipado. Un plugin también
puede ser una función (config) => spec.
El
ctx que recibe install:
Paquetes de plugins
Además deslashCommandsPlugin, estos paquetes traen plugins listos:
- IA —
@botmesh/ai: respuestas con LLM (aiPlugin), con herramientas, memoria y RAG y streaming. - Voz —
@botmesh/voice(voicePlugin): voz a texto para las notas de voz entrantes y respuestas con texto a voz. - Integraciones —
@botmesh/chatwoot,@botmesh/tickets,@botmesh/moderation,@botmesh/dialogflowy@botmesh/nlu(intenciones locales). - Trazas —
@botmesh/otel(otelMetricsPlugin):bot.metrics()y los spans del bot en OpenTelemetry.
@botmesh/rag (recuperación para aiPlugin) se
explica en memoria y RAG.
Siguientes pasos
- Inyección de dependencias — comparte herramientas entre plugins
- Ejemplo: rate limiter — plugin completo