Recipes

Complete patterns, not fragments. Every recipe assumes the Getting Started socket (with the store wired and saveCreds hooked) already exists.

1 โ€” Prefix command bot

const PREFIX = '/'
const commands = {
  ping: async (sock, m) => sock.aunuHandler.reply(m.key.remoteJid, { text: 'Pong ๐Ÿ–ค' }, m),
  menu: async (sock, m) =>
    sock.aunuHandler.send(m.key.remoteJid, {
      text: ['*AunuCore Bot*', '/ping โ€” check the bot', '/menu โ€” this menu'].join('
')
    })
}

sock.ev.on('messages.upsert', async ({ messages, type }) => {
  if (type !== 'notify') return
  for (const m of messages) {
    if (m.key.fromMe || !m.message) continue
    const text = m.message.conversation || m.message.extendedTextMessage?.text || ''
    if (!text.startsWith(PREFIX)) continue
    const name = text.slice(PREFIX.length).split(' ')[0].toLowerCase()
    const cmd = commands[name]
    if (cmd) {
      await sock.readMessages([m.key])
      await cmd(sock, m).catch(err => console.error(name, err))
    }
  }
})

2 โ€” Group welcome & goodbye

sock.ev.on('group-participants.update', async ({ id, participants, action }) => {
  const meta = await sock.groupMetadata(id).catch(() => null)
  for (const p of participants) {
    const num = '@' + p.split('@')[0]
    if (action === 'add') {
      await sock.sendMessage(id, {
        text: `Welcome ${num} to *${meta?.subject || 'the group'}* โ€” ${meta?.participants.length || ''} members strong. Read the description, say hi!`,
        mentions: [p]
      })
    }
    if (action === 'remove') {
      await sock.sendMessage(id, { text: `${num} left the group.`, mentions: [p] })
    }
  }
})

Mentions only notify when the JID is in the mentions array and written as @number in the text โ€” both halves above matter.

3 โ€” Sticker maker (reply to an image)

import { downloadMediaMessage } from 'aunubaileys'

// inside your command handler, for the command /sticker:
const quoted = m.message.extendedTextMessage?.contextInfo?.quotedMessage
const imgMsg = quoted?.imageMessage ? { message: quoted, key: m.key } : null
if (!imgMsg) return sock.aunuHandler.reply(jid, { text: 'Reply to an image with /sticker.' }, m)
const buffer = await downloadMediaMessage(imgMsg, 'buffer', {})
// Convert to 512x512 WebP first (sharp/jimp โ€” optional peers), then:
await sock.sendMessage(jid, { sticker: buffer }, { quoted: m })

For a whole pack instead of one sticker, collect the converted WebPs and send them with the stickerPack content form from Sending Messages.

4 โ€” Tally poll results

import { getAggregateVotesInPollMessage } from 'aunubaileys'

sock.ev.on('messages.update', (updates) => {
  for (const { key, update } of updates) {
    if (!update.pollUpdates?.length) continue
    store.loadMessage(key.remoteJid, key.id).then(pollMsg => {
      if (!pollMsg) return
      const results = getAggregateVotesInPollMessage({ message: pollMsg.message, pollUpdates: update.pollUpdates })
      console.log(results.map(r => r.name + ': ' + r.voters.length + ' votes').join('
'))
    })
  }
})

This is why the store matters: votes arrive as bare updates โ€” the original poll message (with its options and encryption key) comes from your store.

5 โ€” Scheduled channel announcements, safely

import { wrapAntiBan } from 'aunubaileys'
sock = wrapAntiBan(sock) // announcements inherit rate limits + typing

const CHANNEL = '120363xxxxxxxxx@newsletter'
async function announce(text) {
  await sock.sendMessage(CHANNEL, { text, ai: false })
}
// e.g. from cron / setInterval in your own scheduler:
setInterval(() => announce('Daily build is out โ€” see the changelog.'), 24 * 60 * 60 * 1000)

6 โ€” Save every document you're sent

import { downloadMediaMessage } from 'aunubaileys'
import { createWriteStream } from 'node:fs'
import { pipeline } from 'node:stream/promises'

sock.ev.on('messages.upsert', async ({ messages, type }) => {
  if (type !== 'notify') return
  for (const m of messages) {
    const doc = m.message?.documentMessage
    if (!doc) continue
    const stream = await downloadMediaMessage(m, 'stream', {})
    await pipeline(stream, createWriteStream('./inbox/' + (doc.fileName || m.key.id)))
    await sock.aunuHandler.react(m.key.remoteJid, '๐Ÿ–ค', m.key)
  }
})