How to Collect Telegram Media Groups in Node.js The article explains that Telegram's Bot API sends each photo in an album as a separate update, requiring developers to handle buffering, race conditions, and duplicate prevention. To solve this, the author created "telegram-media," a lightweight TypeScript library for Node.js that collects these scattered updates into a single, normalized object. The library supports Redis storage for distributed environments and was extracted from a personal project to spare others from solving this complex infrastructure problem from scratch. When working with the Telegram Bot API, it is easy to expect that an album with multiple photos will arrive as a single event. But Telegram works differently. If a user sends an album of 3 photos, your bot doesn't receive one "post" object. Instead, it receives 3 separate updates in rapid succession: php Update 1 - photo 1 Update 2 - photo 2 Update 3 - photo 3 instead of: single post - photo 1, photo 2, photo 3 The Headache: Why this is hard Handling these updates manually forces you to deal with a lot of "plumbing" code that has nothing to do with your actual bot logic: Duplicate database records: Accidentally creating 3 posts instead of 1. Race conditions: Multiple updates hitting your server at the exact same time. Buffering & Timeouts: Deciding how long to wait for the "next" photo before assuming the group is complete. Ordering: Ensuring the photos stay in the order the user intended. Typical "infrastructure" code usually starts looking like this mess: js const mediaGroups = new Map ; // buffering logic... // sorting logic... // duplicate prevention... // cleanup jobs... // timeout handling... At some point, you realize you are rewriting low-level infrastructure instead of building your actual features. The Solution: telegram-media I built telegram-media—a lightweight TypeScript library for Node.js that collects these scattered Telegram updates into a single, normalized object. Installation npm install telegram-media Usage Example Here is how you can use it to collect media and save it to a database like Prisma using a Redis storage backend: js const collector = createTelegramMediaGroup { async onCollected post { // This only fires ONCE per media group await prisma.telegramPost.create { data: mapCollectedPostToPrismaInput post , } ; }, // Use Redis for distributed environments storage: createRedisMediaGroupStorage redisClient , timeoutMs: 3000, supportedMediaTypes: "photo", "video", "audio" , } ; Why I Built This? I ran into this problem while building a Telegram ingestion system for a personal project. At first, the logic seemed simple—just a small Set and a setTimeout. Then the edge cases hit: distributed workers fighting over the same group, incomplete groups caused by network lag, and Redis synchronization issues. I extracted the logic into a standalone package so no one else has to solve this from scratch. Key Features - Media Group Aggregation — Automatically groups related Telegram updates into a single normalized post. - Redis Support — Ready for production and distributed environments. - Duplicate Prevention — Handles Telegram retry updates safely. - Ordering — Preserves the original media sequence. - TypeScript — Fully typed for a better developer experience. Explore What do you think? I'd love to hear how others are handling media groups. Do you use a custom buffer, or do you just process each image individually and update the record as you go? Let me know in the comments