### Initialize and Use simpl.db Database Source: https://context7.com/indra87g/sakurabot/llms.txt Demonstrates the setup and usage of simpl.db for persistent JSON storage. It covers initializing the database with specific file paths and auto-save options, setting default keys, and performing basic user and currency operations. Dependencies include 'simpl.db' and 'path'. ```javascript const { Database } = require('simpl.db'); const path = require('path'); const db = new Database({ dataFile: path.join(__dirname, 'database.json'), autoSave: true, tabSize: 2 }); // Initialize default keys if (!db.has('users')) db.set('users', []); if (!db.has('premium')) db.set('premium', []); if (!db.has('sakuranite')) db.set('sakuranite', {}); if (!db.has('inventory')) db.set('inventory', {}); // User operations const users = db.get('users') || []; users.push(userId); db.set('users', users); // Currency operations const getSakuranite = (userId) => db.get(`sakuranite.${userId}`) || 0; const updateSakuranite = (userId, amount) => db.set(`sakuranite.${userId}`, amount); // Inventory operations const inventory = db.get(`inventory.${userId}`) || {}; inventory['Copper'] = (inventory['Copper'] || 0) + 5; db.set(`inventory.${userId}`, inventory); ``` -------------------------------- ### Format Bot Uptime using tools.utils.formatUptime() Source: https://context7.com/indra87g/sakurabot/llms.txt Calculates and formats the bot's uptime from a given start timestamp into a human-readable string (e.g., '0d 2h 15m 30s'). It requires a start timestamp as input and returns a formatted string. Useful for displaying bot operational time. ```javascript const { formatUptime } = require('./tools/utils'); global.botStartTime = Date.now(); // After some time has passed const uptime = formatUptime(global.botStartTime); // Result: "0d 2h 15m 30s" // Usage in command bot.command('uptime', (ctx) => { ctx.reply(`Bot uptime: ${formatUptime(global.botStartTime)}`); }); ``` -------------------------------- ### Start 'Tebak Gambar' Game on WhatsApp Source: https://context7.com/indra87g/sakurabot/llms.txt Implements the 'tebakgambar' game for a WhatsApp bot, fetching image-based puzzles from an external API. It manages game sessions, sets timeouts, and provides hints and surrender options. Dependencies include 'axios' for API requests and utility functions for random element selection and time conversion. ```javascript // wa/commands/game/tebakgambar.js const axios = require("axios"); module.exports = { name: "tebakgambar", code: async (sock, m, { from, waBot }) => { // Check for existing game session if (waBot.games.has(from)) { return await sock.sendMessage(from, { text: "A game is already running in this chat!" }, { quoted: m }); } const apiUrl = "https://raw.githubusercontent.com/BochilTeam/database/master/games/tebakgambar.json"; const { data } = await axios.get(apiUrl); const result = tools.cmd.getRandomElement(data); const game = { name: "tebakgambar", answer: result.jawaban.toLowerCase(), reward: 500, timeout: 60000, startTime: Date.now() }; waBot.games.set(from, game); await sock.sendMessage(from, { image: { url: result.img }, caption: `— TEBAK GAMBAR —\n\n` + `${result.deskripsi}\n\n` + `Bonus: ${game.reward} Sakuranite\n` + `Time limit: ${tools.msg.convertMsToDuration(game.timeout)}\n\n` + `Type your answer directly. Type 'hint' for clue or 'surrender' to give up.` }, { quoted: m }); // Set timeout game.timeoutRef = setTimeout(async () => { if (waBot.games.has(from)) { waBot.games.delete(from); await sock.sendMessage(from, { text: `Time's up! The answer was: ${game.answer.toUpperCase()}` }); } }, game.timeout); } }; ``` -------------------------------- ### WhatsApp Command Module Structure Source: https://context7.com/indra87g/sakurabot/llms.txt Defines the standard structure for WhatsApp command modules in the Sakurabot project. Each module includes a name, optional aliases, and an asynchronous `code` handler function that receives `sock`, `m` (message), and `ctx` (context) parameters. ```javascript // wa/commands/user/daily.js const moment = require('moment-timezone'); module.exports = { name: 'daily', aliases: ['claim'], code: async (sock, m, { sender, db, getSakuranite, updateSakuranite, from }) => { const lastDaily = db.get(`last_daily.${sender}`) || 0; const now = moment().tz('Asia/Jakarta').startOf('day').valueOf(); if (lastDaily === now) { return await sock.sendMessage(from, { text: 'You have already claimed your daily reward!' }, { quoted: m }); } const reward = Math.floor(Math.random() * (800 - 75 + 1)) + 75; updateSakuranite(sender, getSakuranite(sender) + reward); db.set(`last_daily.${sender}`, now); await sock.sendMessage(from, { text: `Daily Reward Claimed!\nYou received: ${reward} Sakuranite` }, { quoted: m }); } }; ``` -------------------------------- ### Initialize Telegram Bot with Telegraf Source: https://context7.com/indra87g/sakurabot/llms.txt Launches the Telegram bot using the Telegraf library. It sets up essential middleware for checking banned users, tracking users, managing cooldowns, and verifying channel subscriptions. Requires Telegraf and Markup. ```javascript const { Telegraf, Markup } = require('telegraf'); const launchTelegramBot = () => { const bot = new Telegraf(config.bot.botfather_token); // Middleware: Check banned users bot.use((ctx, next) => { const bans = db.get('bans') || []; const userBan = bans.find(ban => ban.id === ctx.from.id); if (userBan) return ctx.reply('You have been banned!'); return next(); }); // Middleware: Add user to database bot.use((ctx, next) => { const users = db.get('users') || []; if (!users.includes(ctx.from.id)) { users.push(ctx.from.id); db.set('users', users); } return next(); }); // Register command bot.command('start', async (ctx) => { await ctx.reply(`Hello, ${ctx.from.first_name}!`); }); bot.launch(); global.tgBot = bot; }; ``` -------------------------------- ### Initialize WhatsApp Bot with Baileys Source: https://context7.com/indra87g/sakurabot/llms.txt Initializes the WhatsApp bot using the Baileys library. It handles authentication, sets up message event listeners, and manages connection updates. This function requires Baileys and pino for logging. ```javascript const { default: makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, makeCacheableSignalKeyStore } = require("@whiskeysockets/baileys"); const startWaBot = async () => { const { state, saveCreds } = await useMultiFileAuthState('./state'); const { version } = await fetchLatestBaileysVersion(); const sock = makeWASocket({ version, auth: { creds: state.creds, keys: makeCacheableSignalKeyStore(state.keys, pino({ level: "silent" })), }, browser: ["Ubuntu", "Chrome", "20.0.04"] }); sock.ev.on("creds.update", saveCreds); sock.ev.on("connection.update", (update) => { const { connection, lastDisconnect } = update; if (connection === "open") { console.log("WhatsApp bot connected!"); global.waSock = sock; } }); sock.ev.on("messages.upsert", async (chatUpdate) => { const m = chatUpdate.messages[0]; if (!m.message || m.key.fromMe) return; await handler(sock, m, db, waBot, items); }); return sock; }; ``` -------------------------------- ### Build API URLs with tools.utils.createUrl Source: https://context7.com/indra87g/sakurabot/llms.txt A utility function to construct well-formatted API URLs, including query parameters. It supports both predefined API endpoints and custom base URLs, simplifying API interaction within the bot. ```javascript const { createUrl } = require('./tools/utils'); // Using predefined API const apiUrl1 = createUrl('turu', '/api/endpoint', { query: 'value' }); // Result: "https://mending-turu.web.id/api/endpoint?query=value" // Using custom URL const apiUrl2 = createUrl('https://custom-api.com', '/v1/users', { id: '123', format: 'json' }); // Result: "https://custom-api.com/v1/users?id=123&format=json" // Available predefined APIs: // - turu: https://mending-turu.web.id // - iyayn: https://api.iyayn.web.id // - bagus: https://api.baguss.xyz // - deline: https://api.deline.web.id // - nekolabs: https://api.nekolabs.web.id ``` -------------------------------- ### Configure SakuraBot with config.json Source: https://context7.com/indra87g/sakurabot/llms.txt The main configuration file for SakuraBot, defining bot name, phone number, API tokens, owner details, system settings, and message templates. This JSON file is essential for setting up the bot's core behavior and platform integration. ```json { "bot": { "name": "SAKURABOT", "phoneNumber": "6281234567890", "thumbnail": "https://example.com/thumbnail.png", "prefix": "/", "botfather_token": "YOUR_BOTFATHER_TOKEN" }, "owner": { "name": "YourName", "id": "6281234567890", "id_tele": "123456789", "report": true }, "system": { "alwaysOnline": true, "autoRead": true, "cooldown": 10000, "port": 5000, "usePairingCode": true, "useServer": true }, "msg": { "banned": "You have been banned!", "cooldown": "This command is on cooldown, wait...", "owner": "This command is only accessible by owner!" } } ``` -------------------------------- ### Implement Async Delay with tools.cmd.delay() Source: https://context7.com/indra87g/sakurabot/llms.txt Provides an asynchronous delay function that returns a promise resolving after a specified number of milliseconds. This is crucial for managing rate limits and ensuring sequential execution of asynchronous operations. It takes milliseconds as input. ```javascript const { delay } = require('./tools/cmd'); async function sendMultipleMessages(ctx, messages) { for (const message of messages) { await ctx.reply(message); await delay(500); // Wait 500ms between messages } } // Chained usage await sock.sendMessage(jid, { text: 'First message' }); await delay(1000); await sock.sendMessage(jid, { text: 'Second message after 1 second' }); ``` -------------------------------- ### Format Byte Sizes with tools.msg.formatSize() Source: https://context7.com/indra87g/sakurabot/llms.txt Converts byte counts into a human-readable format using appropriate unit suffixes (e.g., KiB, MiB, GiB). It can also format transfer rates by accepting a boolean flag. Useful for displaying file sizes or network transfer speeds. ```javascript const { formatSize } = require('./tools/msg'); const fileSize = formatSize(1536000); // Result: "1.46 MiB" const transferRate = formatSize(2048000, true); // Result: "1.95 MiB/s" // Usage in file info command const stats = fs.statSync(filePath); await ctx.reply(`File size: ${formatSize(stats.size)}`); ``` -------------------------------- ### Centralized Error Handling with tools.cmd.handleError() Source: https://context7.com/indra87g/sakurabot/llms.txt Provides a centralized mechanism for handling errors. It logs the error, notifies the user, and can optionally report the error to bot owner(s). It accepts context, error object, a boolean for axios usage, and a boolean for owner reporting as parameters. ```javascript const { handleError } = require('./tools/cmd'); module.exports = { name: 'fetch', code: async (sock, m, ctx) => { try { const response = await axios.get('https://api.example.com/data'); await sock.sendMessage(m.key.remoteJid, { text: response.data }); } catch (error) { // Logs error, notifies user, reports to owner if enabled await handleError(ctx, error, true, true); // Parameters: (context, error, useAxios, reportToOwner) } } }; ``` -------------------------------- ### Validate Message Media Type with tools.cmd.checkMedia() Source: https://context7.com/indra87g/sakurabot/llms.txt Checks if a message's type matches any of the required media types (image, video, audio, document, sticker, or text). It can also check quoted messages using `checkQuotedMedia`. Returns the matched media type or false if no match is found. Useful for command handlers that expect specific media inputs. ```javascript const { checkMedia, checkQuotedMedia } = require('./tools/cmd'); // Check message type const messageType = 'imageMessage'; const required = ['image', 'video']; const result = checkMedia(messageType, required); // Result: 'image' (matched type) or false (no match) // In command handler module.exports = { name: 'sticker', code: async (sock, m, { type, quotedType }) => { const mediaType = checkMedia(type, ['image', 'video']) || checkQuotedMedia(quotedType, ['image', 'video']); if (!mediaType) { return await sock.sendMessage(m.key.remoteJid, { text: 'Please send or reply to an image/video!' }); } // Process media... } }; ``` -------------------------------- ### Implement Telegram Gacha Command Source: https://context7.com/indra87g/sakurabot/llms.txt This JavaScript code defines a Telegram command for a gacha system. It allows users to spend tickets for random rewards like Sakuranite currency, items, or digital files. The command checks for available items, user tickets, and handles different reward types including ZONK (no prize), Sakuranite, and file rewards. ```javascript // tg/commands/misc/gacha.js module.exports = { name: 'gacha', category: 'misc', code: async (ctx, { isOwner, getGachaTickets, updateGachaTickets, getSakuranite, updateSakuranite }) => { const userId = ctx.from.id; const gachaDir = path.resolve(__dirname, '../../gacha'); const files = fs.readdirSync(gachaDir); if (files.length < 5) { return ctx.reply('Gacha not ready. Not enough items.'); } const userTickets = getGachaTickets(userId); if (!isOwner(userId) && userTickets < 1) { return ctx.reply('No tickets! Use /daily to get more.'); } if (!isOwner(userId)) { updateGachaTickets(userId, userTickets - 1); } const randomFile = files[Math.floor(Math.random() * files.length)]; // Handle ZONK (no prize) if (randomFile.toUpperCase() === 'ZONK') { return ctx.reply('Sorry, no luck this time. Try again!'); } // Handle Sakuranite prize if (randomFile.toUpperCase().startsWith('SAKURANITE-')) { const amount = parseInt(randomFile.split('-')[1], 10); updateSakuranite(userId, getSakuranite(userId) + amount); return ctx.reply(`You won ${amount} Sakuranite!`); } // Send file prize await ctx.reply(`You won: ${randomFile}!`); await ctx.replyWithDocument({ source: path.join(gachaDir, randomFile) }); } }; ``` -------------------------------- ### Claim Daily Reward with Telegraf Source: https://context7.com/indra87g/sakurabot/llms.txt Handles the '/daily' command for Telegram users, allowing them to claim daily rewards. It checks if the reward has already been claimed today using stored data and rewards Sakuranite and Gacha Tickets. Dependencies include 'moment-timezone' for date handling. ```javascript const moment = require('moment-timezone'); module.exports = { name: 'daily', category: 'user', code: async (ctx, { db, isOwner, getSakuranite, updateSakuranite, getGachaTickets, updateGachaTickets }) => { const userId = ctx.from.id; const lastDaily = db.get(`last_daily.${userId}`); const now = moment().tz('Asia/Jakarta'); if (lastDaily && now.isSame(moment(lastDaily), 'day')) { return ctx.reply('Already claimed today. Come back tomorrow!'); } const sakuraniteReward = Math.floor(Math.random() * (750 - 50 + 1)) + 50; const ticketsReward = 5; updateSakuranite(userId, getSakuranite(userId) + sakuraniteReward); updateGachaTickets(userId, getGachaTickets(userId) + ticketsReward); db.set(`last_daily.${userId}`, now.valueOf()); return ctx.reply( `Daily Reward Claimed!\n` + `- ${sakuraniteReward} Sakuranite\n` + `- ${ticketsReward} Gacha Tickets` ); } }; ``` -------------------------------- ### Convert Milliseconds to Duration with tools.msg.convertMsToDuration() Source: https://context7.com/indra87g/sakurabot/llms.txt Converts a duration in milliseconds into a human-readable string, including units like years, months, days, hours, minutes, and seconds. This is useful for displaying time intervals in a user-friendly format. ```javascript const { convertMsToDuration } = require('./tools/msg'); const duration1 = convertMsToDuration(3661000); // Result: "1 jam 1 menit 1 detik" const duration2 = convertMsToDuration(86400000); // Result: "1 hari" // Usage in game timeout await sock.sendMessage(from, { text: `Time limit: ${convertMsToDuration(60000)}` }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.