cd /news/developer-tools/how-to-collect-telegram-media-groups… · home topics developer-tools article
[ARTICLE · art-9922] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

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.

read2 min views19 publishedMay 22, 2026

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:

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:

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:

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!

── more in #developer-tools 4 stories · sorted by recency
── more on @telegram bot api 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-collect-teleg…] indexed:0 read:2min 2026-05-22 ·