media-cache
reuse a file_id instead of re-uploading the same file. the first send uploads the
local file and stores the returned file_id; every subsequent send under the same key
skips the upload entirely.
installation
pnpm add @yaebal/media-cachebasic usage
create a MediaCache instance with mediaCache(), then call cache.photo or cache.document instead of ctx.sendPhoto / ctx.sendDocument directly. supply a stable string key to identify each asset.
import { Bot } from "@yaebal/core";
import { mediaCache } from "@yaebal/media-cache";
import { media } from "@yaebal/core";
const bot = new Bot(token);
const cache = mediaCache(); // defaults to in-memory storage
bot.command("logo", async (ctx) => {
// first call: uploads the file and stores its file_id under "logo"
// subsequent calls: skips the upload, sends the cached file_id instead
await cache.photo(ctx, "logo", media.path("./assets/logo.png"));
});how caching works
on the first call for a key the source is sent as-is (a path, url, or buffer). telegram returns a
message containing the uploaded file's file_id. media-cache stores that
id under your key. on the next call it calls media.fileId(cached) instead — no
upload, just the id.
for photos, the last (largest) size in the array is cached — that's the highest-quality variant telegram returns.
persistent storage
the default storage is in-memory and lost on restart. pass any StorageAdapter<string> from @yaebal/session to persist across
restarts.
import { mediaCache } from "@yaebal/media-cache";
import { RedisStorage } from "./my-redis-storage.js"; // your StorageAdapter<string>
const cache = mediaCache({ storage: new RedisStorage() });documents
import { media } from "@yaebal/core";
// send a PDF and cache it under "report-2024"
await cache.document(ctx, "report-2024", media.path("./report.pdf"), {
caption: "Q4 report",
});independent keys
keys are caller-supplied strings. distinct keys always cache independently — useful for per-locale or per-variant assets.
// "logo-en" and "logo-ru" are independent — distinct keys cache independently
await cache.photo(ctx, "logo-en", media.path("./logo-en.png"));
await cache.photo(ctx, "logo-ru", media.path("./logo-ru.png"));api
| export | kind | description |
|---|---|---|
mediaCache(options?) | function | creates a MediaCache instance |
MediaCache | interface | the object returned by mediaCache() |
MediaCacheOptions | interface | storage?: StorageAdapter<string> |
MediaCache methods
| method | description |
|---|---|
photo(ctx, key, source, extra?) | send a photo, caching the file_id under key |
document(ctx, key, source, extra?) | send a document, caching its file_id under key |
source accepts anything @yaebal/core's MediaSource accepts
— media.path(), media.url(), media.buffer(), or a bare file_id string. extra is forwarded as send options (caption, parse_mode,
etc.).