// bot.js
import { Bot, defineBot, flow, isMainModule, slashCommandsPlugin } from '@botmesh/core'
import { BaileysProvider } from '@botmesh/baileys'
// Administradores del bot: sus ids de usuario, tal como los muestra /id (WhatsApp: 573001234567@s.whatsapp.net)
const ADMINS = (process.env.ADMINS ?? 'ana').split(',')
const createBot = defineBot((provider) => {
// 1. Los valores por defecto que importan en grupos: se enruta todo mensaje del grupo
// (groupMode: 'all') y cada participante tiene su propia conversación (conversationScope: 'participant')
const bot = new Bot({ provider, lang: 'es' })
const rules = new Map() // id del grupo → texto de las normas
const scores = new Map() // id del grupo → Map(nombre → puntos)
const isAdmin = (ctx) => ADMINS.includes(ctx.sender)
const nameOf = (ctx) => ctx.pushName ?? ctx.sender
bot.plug(slashCommandsPlugin) // /id, /help, /cancel...
// 2. Un quiz por participante: dos personas pueden jugar a la vez
bot.use(
flow({ pattern: 'quiz', match: 'contains' })
.scope('group')
.ask((ctx) => `🧠 ${nameOf(ctx)}, ¿2 + 2?`, 'q1')
.ask((ctx) => `🌍 ${nameOf(ctx)}, ¿capital de Francia?`, 'q2')
.say((ctx, c) => {
const points = (c.state.q1.trim() === '4' ? 1 : 0) + (['paris', 'parís'].includes(c.state.q2.trim().toLowerCase()) ? 1 : 0)
const board = scores.get(ctx.from) ?? new Map()
board.set(nameOf(ctx), (board.get(nameOf(ctx)) ?? 0) + points)
scores.set(ctx.from, board)
return `🏁 ${nameOf(ctx)}: ${points}/2`
}),
)
// 3. Comandos para todos
bot.command('rules', (ctx) => ctx.reply(rules.get(ctx.from) ?? 'Todavía no hay normas.'))
bot.command('scores', (ctx) => {
const board = [...(scores.get(ctx.from) ?? [])].sort((a, b) => b[1] - a[1])
return ctx.reply(board.length ? board.map(([name, points]) => `${name}: ${points}`).join('\n') : 'Aún no hay puntos. Envía "quiz".')
})
// 4. Comandos solo para administradores
bot.command('setrules', async (ctx, args) => {
if (!isAdmin(ctx)) return ctx.reply('⛔ Solo los administradores pueden cambiar las normas.')
rules.set(ctx.from, `📜 ${args.join(' ')}`)
await ctx.reply('✅ Normas actualizadas.')
})
bot.command('resetscores', async (ctx) => {
if (!isAdmin(ctx)) return ctx.reply('⛔ Solo los administradores pueden reiniciar los puntos.')
scores.delete(ctx.from)
await ctx.reply('🧹 Puntos borrados.')
})
// 5. En privado, explica; en un grupo, responde solo cuando alguien menciona al bot
bot.onMessage((ctx) => {
if (!ctx.isGroup) return ctx.reply('Añádeme a un grupo y envía "quiz" allí.')
if (provider.selfId != null && ctx.mentions.includes(provider.selfId)) {
return ctx.reply(`👋 ¡Hola ${nameOf(ctx)}! Envía "quiz" para jugar, /scores o /rules.`)
}
})
return bot
})
export default createBot
// `node bot.js` se conecta a WhatsApp; `npx botmesh dev bot.js` se salta este bloque
if (isMainModule(import.meta)) {
const bot = await createBot(new BaileysProvider({ session: 'bot-grupo' }))
bot.on('ready', () => console.log('✅ Conectado'))
await bot.start()
}