Resolve a giphy token with no metadata to look it up in

`![gif](giphy|zUW23b6FmzB5e)` is a token, not an address, and the only thing
that turned it into one was a lookup in the comment's own `media_metadata`.
Reddit ships plenty of comments carrying such a token and no `media_metadata`
at all, and with nothing to look it up in the token itself was what the
comment showed.

Giphy is the one of the three token kinds whose id means something off
Reddit, so that one can be resolved without the lookup. A variant name after
the id is dropped: Giphy does not serve every variant of every gif, but the
full one is always there.

The other two still resolve only through the metadata. An emote id and an
upload id name nothing outside Reddit, so with no entry for them there is
still nothing to point them at.

Closes #10

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PLkmgp1fWbA4XbarxKdRKt
This commit is contained in:
2026-08-30 23:36:53 -03:00
co-authored by Claude Opus 5
parent 91d4c2da50
commit 4669fe0b6a
3 changed files with 90 additions and 18 deletions
+30 -12
View File
@@ -192,14 +192,30 @@ function bodyOf(link: Link): string | undefined {
/** The whole of `![...](...)`, with the target captured. */
const INLINE_IMAGE = /!\[([^\]\n]*)\]\(([^)\s]+)\)/g;
/**
* A Giphy token, which unlike the others says what it points at.
*
* Reddit writes a variant name after the id on some of them
* (`giphy|abc123|downsized`); only the id is kept, because Giphy does not
* serve every variant for every gif but always serves the full one.
*/
const GIPHY_TOKEN = /^giphy\|([A-Za-z0-9]+)(?:\|[a-z_]+)?$/;
/**
* Point a comment's inline images at something fetchable.
*
* Reddit writes them as `![gif](giphy|Ve7wX45)`, `![img](emote|t5_2th52|4358)`
* or `![img](jo8gf0ca92zd1)` — a token rather than an address. In every case
* the token is a key in that same comment's `media_metadata`, which is where
* the real URL is, so one lookup covers all three and none of them needs
* naming here.
* or `![img](jo8gf0ca92zd1)` — a token rather than an address. Usually the
* token is a key in that same comment's `media_metadata`, which is where the
* real URL is, so one lookup covers all three and none of them needs naming
* here.
*
* Usually, not always: Reddit ships plenty of comments carrying a Giphy token
* and no `media_metadata` at all, and with nothing to look the token up in
* those showed the token itself where the gif should have been. Giphy is the
* one kind that can be resolved without the lookup, the id in it being Giphy's
* own, so it falls back to Giphy's address for that id. The other two cannot:
* their ids mean nothing off Reddit.
*
* A target that is already an address is not a key, so it falls through
* untouched.
@@ -208,15 +224,17 @@ export function resolveInlineImages(
body: string,
meta: Record<string, MediaMeta> | undefined,
): string {
if (!meta) return body;
return body.replace(INLINE_IMAGE, (whole, alt: string, token: string) => {
const entry = meta[token];
if (!entry || entry.status !== 'valid') return whole;
// An animated one has both; the GIF plays in an `<img>` on its own, which
// an MP4 does not.
const url = entry.s?.gif ?? entry.s?.u;
return url ? `![${alt}](${url})` : whole;
const entry = meta?.[token];
if (entry?.status === 'valid') {
// An animated one has both; the GIF plays in an `<img>` on its own,
// which an MP4 does not.
const url = entry.s?.gif ?? entry.s?.u;
if (url) return `![${alt}](${url})`;
}
const giphy = GIPHY_TOKEN.exec(token)?.[1];
return giphy ? `![${alt}](https://i.giphy.com/media/${giphy}/giphy.gif)` : whole;
});
}