// bot.js
import { Bot, defineBot, definePlugin, isMainModule, slashCommandsPlugin } from '@botmesh/core'
import { BaileysProvider } from '@botmesh/baileys'
// 1. El plugin: responde preguntas frecuentes y cuenta cuáles pregunta la gente
export const faqPlugin = definePlugin({
name: 'faq',
version: '1.0.0',
description: 'FAQ por palabras clave con contadores',
install(ctx, config = {}) {
const answers = config.answers ?? {}
const hits = new Map(Object.keys(answers).map((topic) => [topic, 0]))
// 2. Una herramienta: cualquier handler o plugin la lee como ctx.tools.faq
ctx.bot.provide('faq', {
topics: () => [...hits.keys()],
stats: () => Object.fromEntries(hits),
})
// 3. Lo registrado con ctx.bot se quita solo al desconectar el plugin
ctx.bot.command('faq', (c) => c.reply(`❓ Pregúntame por: ${[...hits.keys()].join(', ')}`))
for (const [topic, answer] of Object.entries(answers)) {
ctx.bot.when(topic, async (c) => {
hits.set(topic, hits.get(topic) + 1)
await c.reply(answer)
})
}
// 4. Lo demás lo deshaces tú: un temporizador y la herramienta publicada
const report = setInterval(() => ctx.logger.info({ hits: Object.fromEntries(hits) }, 'faq stats'), config.reportEvery ?? 3_600_000)
report.unref()
ctx.onDispose(() => clearInterval(report))
ctx.onDispose(() => delete ctx.tools.faq)
},
// 5. Corre primero al desconectar el plugin
uninstall(ctx) {
ctx.logger.info('faq plugin removed')
},
})
const createBot = defineBot((provider) => {
const bot = new Bot({ provider, lang: 'es' })
bot.plug(slashCommandsPlugin)
// 6. Usar el plugin: plug() devuelve la función que lo desconecta
const unplugFaq = bot.plug(faqPlugin, {
answers: {
horario: '🕘 Abrimos de lunes a sábado, de 9:00 a 18:00.',
envios: '🚚 Los pedidos llegan en 2 o 3 días hábiles.',
devoluciones: '↩️ Puedes devolver cualquier producto en 30 días.',
},
})
// 7. Leer la herramienta del plugin desde tus propios handlers
bot.command('faqstats', (ctx) => {
const faq = ctx.tools.faq
if (!faq) return ctx.reply('La FAQ está desactivada.')
const lines = Object.entries(faq.stats()).map(([topic, n]) => `• ${topic}: ${n}`)
return ctx.reply(`📊 Consultas de la FAQ\n${lines.join('\n')}`)
})
// Un interruptor de administración (protege estos comandos en un bot real)
bot.command('faqoff', (ctx) => {
unplugFaq()
return ctx.reply('🔌 Plugin de FAQ desconectado.')
})
bot.onMessage((ctx) => ctx.reply('Envía /faq para ver qué puedo responder.'))
return bot
})
export default createBot
if (isMainModule(import.meta)) {
const bot = await createBot(new BaileysProvider({ session: 'faq-bot' }))
bot.on('ready', () => bot.logger.info('connected'))
await bot.start()
}