Sloth Digest: I Taught Gemma to Read My Group Chats So I Don’t Have To A developer built Sloth Digest, a small Node and Express web app that uses Google's open-weight Gemma model to condense noisy group chats from WhatsApp, Slack, Telegram or email into summaries, with a rough "minutes saved" estimate based on a 200-words-per-minute reading speed. The app runs Gemma either locally through Ollama or via a hosted Gemini API, switchable with a single AI_PROVIDER environment variable, so the local mode keeps private chat text entirely on the user's machine. The developer acknowledged the hosted demo is not private like local mode, and capped input at 12,000 characters with rate limiting on the server. This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady https://dev.to/challenges/hacktoberfest-week3-2026-10-19 Sloth Digest is a small web app that reads your group chats so you don't have to. You paste in a noisy chat from WhatsApp, Slack, Telegram or email. A few seconds later you get three things: It also shows a rough "minutes saved" figure. It divides the words you skipped by an average reading speed of 200 words per minute, so treat it as an estimate. Anyone who has come back to 200 unread messages and had to scroll for the one line that said "pay by Saturday" gets to be a little lazier. That was the goal. Live demo: https://sloth-digest.onrender.com https://sloth-digest.onrender.com There is a Try a sample chat button, so you can see a full result without pasting anything private. The sample is a made-up chat about a trip and a deadline. https://github.com/ypunit757-prog/Sloth-Digest https://github.com/ypunit757-prog/Sloth-Digest The stack is deliberately small: a Node + Express server and a plain JavaScript frontend, with no framework and no build step. The open-source AI piece is Gemma , Google's open-weight model. The server has one switch, AI PROVIDER , that decides how Gemma is run: gemma3:4b . Inference is fully local. The route handler is the same either way. Only the model call changes: js const text = PROVIDER === "gemini" ? await askGemini model, buildPrompt chat : await askOllama model, buildPrompt chat ; const digest = extractJson text ; A few things I learned along the way: /api/ , so the Gemini key lives in a Render environment variable. The server also rate-limits requests and caps input at 12,000 characters. Group chats are some of the most private text we have. They hold family plans, money, health news and gossip. Pasting that into a closed API means trusting a company with it. Because Gemma has open weights, I could build the same app so it runs entirely on my own machine . With Ollama it works offline, costs nothing per run, and sends nothing anywhere. A closed API wouldn't let me make that promise. Open weights also gave me freedom to move . The same model family runs locally and on a hosted API, and I switched between them with one environment variable. If a model improves or a price changes, I can swap it without rewriting the app. I'll be honest about the trade-off: my hosted demo calls Gemma through an API, so the demo is not private the way local mode is. The local mode is the privacy-first version, and the hosted one is there so you can try it quickly. The app's own estimate for the sample chat about 120 words is roughly half a minute of reading saved. That's small for one chat, but it adds up over a busy week of active group chats. render.yaml blueprint, so the whole deploy is one click plus an API key.