// bot.js
import { Bot, defineBot, definePlugin, isMainModule, slashCommandsPlugin } from '@botmesh/core'
import { BaileysProvider } from '@botmesh/baileys'
// 1. The plugin: answers frequent questions and counts which ones people ask
export const faqPlugin = definePlugin({
name: 'faq',
version: '1.0.0',
description: 'Keyword FAQ with hit counters',
install(ctx, config = {}) {
const answers = config.answers ?? {}
const hits = new Map(Object.keys(answers).map((topic) => [topic, 0]))
// 2. A tool: any handler or plugin reads it as ctx.tools.faq
ctx.bot.provide('faq', {
topics: () => [...hits.keys()],
stats: () => Object.fromEntries(hits),
})
// 3. Handlers registered through ctx.bot are removed automatically on unplug
ctx.bot.command('faq', (c) => c.reply(`❓ Ask me about: ${[...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. Anything else is yours to undo: a timer and the provided tool
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. Runs first when the plugin is unplugged
uninstall(ctx) {
ctx.logger.info('faq plugin removed')
},
})
const createBot = defineBot((provider) => {
const bot = new Bot({ provider })
bot.plug(slashCommandsPlugin)
// 6. Use the plugin: plug() returns the function that unplugs it
const unplugFaq = bot.plug(faqPlugin, {
answers: {
hours: '🕘 We are open Monday to Saturday, 9:00 to 18:00.',
shipping: '🚚 Orders arrive in 2 to 3 business days.',
returns: '↩️ You can return any item within 30 days.',
},
})
// 7. Read the plugin's tool from your own handlers
bot.command('faqstats', (ctx) => {
const faq = ctx.tools.faq
if (!faq) return ctx.reply('The FAQ is off.')
const lines = Object.entries(faq.stats()).map(([topic, n]) => `• ${topic}: ${n}`)
return ctx.reply(`📊 FAQ hits\n${lines.join('\n')}`)
})
// An admin switch (protect admin commands in a real bot)
bot.command('faqoff', (ctx) => {
unplugFaq()
return ctx.reply('🔌 FAQ plugin unplugged.')
})
bot.onMessage((ctx) => ctx.reply('Send /faq to see what I can answer.'))
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()
}