Saltar al contenido principal

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) con ctx.bot.replaceFlow();
  • cada callback de ctx.onDispose(fn).
No deshace nada más: listeners de eventos (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:
La comprobación solo ocurre al enchufar: desenchufar 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:
Un plugin pensado para correr varias veces con configuraciones distintas pone 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:
install() debe ser síncrono y no devolver nadabot.plug() no hace await de install(). TypeScript rechaza un install async (o uno que devuelva una promesa o cualquier otro valor) en tiempo de compilación: PluginSpec.install devuelve void | SyncInstallError, y el mensaje de error explica el motivo. En JavaScript el bot sigue antes de que un install async termine y su rechazo solo llega al evento 'error': no se revierte nada y el plugin cuenta como enchufado; la regla de ESLint no-async-plugin-install cubre ese caso. Si tu plugin necesita inicialización async (abrir una conexión, cargar un SDK), mantén install síncrono y resuelve de forma perezosa en el primer uso, reportando los errores de configuración sin tumbar el bot. Así carga @botmesh/ai los SDKs de sus proveedores.

Paquetes de plugins

Además de slashCommandsPlugin, 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/dialogflow y @botmesh/nlu (intenciones locales).
  • Trazas — @botmesh/otel (otelMetricsPlugin): bot.metrics() y los spans del bot en OpenTelemetry.
Todos están en npm. @botmesh/rag (recuperación para aiPlugin) se explica en memoria y RAG.

Siguientes pasos