Ap11e & Mewing
Mewing Mewing
Yo Ap11e, I'm thinking of building a snack timer bot that logs my breaks like a speedrun—want to help me code it and add some crazy emote triggers? Also, what new tech are you tinkering with to finally beat lag?
Ap11e Ap11e
Hey! Love the snack‑timer speedrun idea. I’d start a quick Node/Discord bot with discord.js, use setInterval to count your break time, and push the stats to a tiny SQLite DB so you can graph it later. For the emotes, add a mapping like `!break` → 🍕, `!snack` → 🍫, and trigger them when the timer hits 10, 20, 30 minutes, etc. A simple switch in the interval callback will do. On the lag front, I’m messing with WebGPU for rendering on the edge, and using edge‑function compute to pre‑warm data so the bot feels instant. Let me know what stack you’re on, and I’ll dive into code snippets!
Mewing Mewing
That sounds epic! I’ll hit up Node with discord.js, setInterval for the timer, and SQLite for the log—perfect for later graphing. Love the idea of auto‑emote triggers at 10, 20, 30 minutes; we can even throw in a surprise 🍔 at 45 to keep the hype going. I’m on a slightly older PC, so WebGPU is a good bet—let’s keep that lag at bay and maybe set up a tiny fallback queue if the edge compute hiccups. You ready to drop some code snippets? Let’s make this snack‑time a community event!
Ap11e Ap11e
**Basic setup** ```js // index.js const { Client, Intents } = require('discord.js'); const sqlite3 = require('sqlite3').verbose(); const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); const db = new sqlite3.Database('./snacks.db'); db.serialize(() => { db.run(`CREATE TABLE IF NOT EXISTS logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT, start_ts INTEGER, end_ts INTEGER, duration INTEGER )`); }); const emotes = { 10: '🍕', 20: '🍫', 30: '🥨', 45: '🍔' }; client.on('ready', () => console.log(`Logged in as ${client.user.tag}`)); client.on('messageCreate', async msg => { if (msg.author.bot) return; if (msg.content.startsWith('!break')) { startTimer(msg); } }); ``` **Timer & emotes** ```js function startTimer(msg) { const userId = msg.author.id; const start = Date.now(); let minutes = 0; const interval = setInterval(async () => { minutes = Math.floor((Date.now() - start) / 60000); if (emotes[minutes]) { await msg.channel.send(`${emotes[minutes]} ${msg.author} break #${minutes} minutes`); } if (minutes >= 60) { clearInterval(interval); const duration = Date.now() - start; db.run(`INSERT INTO logs (user_id, start_ts, end_ts, duration) VALUES (?, ?, ?, ?)`, [userId, start, Date.now(), duration], err => { if (err) console.error(err); }); await msg.channel.send(`🔥 ${msg.author} break finished! Total: ${minutes} min`); } }, 60000); } ``` **Fallback queue for lag** ```js const queue = []; function safeSend(channel, content) { if (channel.send) { channel.send(content).catch(err => { queue.push({ channel, content, err }); }); } } setInterval(() => { while (queue.length) { const { channel, content } = queue.shift(); channel.send(content).catch(() => {}); // drop if still failing } }, 5000); ``` **Run the bot** ```js client.login('YOUR_BOT_TOKEN'); ``` Just drop the code into a folder, `npm install discord.js sqlite3`, replace the token, and run `node index.js`. The bot will log every break, ping the emotes, and store everything in the SQLite DB for later charts. Happy hacking!
Mewing Mewing
Nice! Now you can even throw in a `!stop` command so people can quit early, or a `!stats` to pull their last break length. Maybe add a leaderboard with a quick query on the DB so everyone knows who’s the most committed snack‑taker. Keep that queue solid—if the channel hiccups, you’re all set. Time to test it out and watch the emote fireworks!
Ap11e Ap11e
Add a few more handlers and a quick leaderboard. ```js const timers = new Map(); // userId -> interval client.on('messageCreate', async msg => { if (msg.author.bot) return; const args = msg.content.split(/\s+/); const cmd = args[0]; if (cmd === '!break') { if (timers.has(msg.author.id)) { await msg.channel.send(`${msg.author} you already have a timer running`); return; } startTimer(msg); // same as before timers.set(msg.author.id, interval); } if (cmd === '!stop') { const interval = timers.get(msg.author.id); if (interval) { clearInterval(interval); timers.delete(msg.author.id); await msg.channel.send(`${msg.author} break stopped early`); } else { await msg.channel.send(`${msg.author} no active timer`); } } if (cmd === '!stats') { db.get(`SELECT duration FROM logs WHERE user_id = ? ORDER BY start_ts DESC LIMIT 1`, [msg.author.id], async (err, row) => { if (row) { const mins = Math.floor(row.duration / 60000); await msg.channel.send(`${msg.author} last break: ${mins} minutes`); } else { await msg.channel.send(`${msg.author} no breaks logged yet`); } }); } if (cmd === '!leaderboard') { db.all(`SELECT user_id, SUM(duration) AS total FROM logs GROUP BY user_id ORDER BY total DESC LIMIT 5`, async (err, rows) => { let msgText = '**Top snack‑takers**\n'; for (const [i, r] of rows.entries()) { const mins = Math.floor(r.total / 60000); msgText += `${i+1}. <@${r.user_id}> – ${mins} min\n`; } await msg.channel.send(msgText); }); } }); ``` That covers starting, stopping, personal stats, and a top‑5 list. The queue helper we already added will keep your messages from getting stuck if the channel hiccups. Ready to fire up the bot and let the emotes roll!