// bot.js
import { Bot, defineBot, isMainModule, slashCommandsPlugin } from '@botmesh/core'
import { BaileysProvider } from '@botmesh/baileys'
// 1. One message tree per language (in a bigger bot: locales/en.json, locales/es.json)
const en = {
greeting: '👋 Hello {name}! Send "order" for a coffee, "stats" for your count, or /lang es.',
order: { size: 'Which size?', small: 'Small', large: 'Large', done: '☕ One {size} coffee, coming up!' },
cups: { zero: 'You have not ordered yet.', one: 'You have ordered {count} coffee.', other: 'You have ordered {count} coffees.' },
lang: { changed: '🇬🇧 From now on I will answer in English.', usage: 'Use /lang en or /lang es.' },
fallback: 'Send "hi", "order" or "stats".',
}
const es = {
greeting: '👋 ¡Hola {name}! Envía "pedido" para un café, "cuenta" para ver cuántos llevas, o /lang en.',
order: { size: '¿De qué tamaño?', small: 'Pequeño', large: 'Grande', done: '☕ ¡Un café {size}, en camino!' },
cups: { zero: 'Todavía no has pedido.', one: 'Has pedido {count} café.', other: 'Has pedido {count} cafés.' },
lang: { changed: '🇪🇸 Desde ahora te respondo en español.', usage: 'Usa /lang en o /lang es.' },
fallback: 'Envía "hola", "pedido" o "cuenta".',
}
const createBot = defineBot((provider) => {
// 2. Serve two languages; guess Spanish from the first word of a message
const bot = new Bot({
provider,
i18n: {
defaultLocale: 'en',
locales: ['en', 'es'],
detect: (ctx) => (/^(hola|buenas|pedido|cuenta)\b/i.test(ctx.body) ? 'es' : undefined),
},
})
bot.locale('en', en)
bot.locale('es', es)
// 3. Remember a detected language, so the next messages keep it
bot.before('message', async (ctx, next) => {
if (ctx.langSource === 'detector') await ctx.setLang(ctx.lang)
await next()
})
// Built-in texts (/help, /cancel, timeouts...) follow ctx.lang too
bot.plug(slashCommandsPlugin)
// 4. Switch on demand: stored in the user's profile (ctx.user)
bot.command('lang', async (ctx, [code]) => {
if (code !== 'en' && code !== 'es') return ctx.reply(ctx.t('lang.usage'))
await ctx.setLang(code)
await ctx.reply(ctx.t('lang.changed'))
})
bot.when(['hi', 'hello', 'hola'], (ctx) => ctx.reply(ctx.t('greeting', { name: ctx.pushName ?? '' })))
// 5. A conversation in the user's language: c.t() follows the latest message
bot.conversation(
'order',
async (c, ctx) => {
const size = await c.choose(c.t('order.size'), { small: c.t('order.small'), large: c.t('order.large') })
await ctx.user.set('cups', ((await ctx.user.get('cups')) ?? 0) + 1)
await c.say(c.t('order.done', { size: c.t(`order.${size}`).toLowerCase() }))
},
{ trigger: ['order', 'pedido'] },
)
// 6. Plural forms: the count picks zero / one / other
bot.when(['stats', 'cuenta'], async (ctx) => ctx.reply(ctx.t('cups', { count: (await ctx.user.get('cups')) ?? 0 })))
bot.onMessage((ctx) => ctx.reply(ctx.t('fallback')))
return bot
})
export default createBot
// `node bot.js` connects to WhatsApp; `npx botmesh dev bot.js` skips this block
if (isMainModule(import.meta)) {
const bot = await createBot(new BaileysProvider({ session: 'coffee-bot' }))
bot.on('ready', () => console.log('✅ Connected'))
await bot.start()
}