Forum teuk.org

📸 MB671 — Let the Moving Portraits Reveal Instagram Without Freezing Time

in Mediabot · started by TeuK · 4d ago

TeuK · 4d ago

Version: 3.4dev-20260819_151028
Commit: e9125a9

Instagram previews in Mediabot already worked when Instagram exposed useful metadata.

The problem was what happened when it did not.

A single unavailable post could make Mediabot spend several seconds trying HTTP and then launching Chromium, blocking normal IRC processing while ultimately returning nothing useful.

MB671 fixes both sides of that problem:

better Instagram previews
+
no more synchronous Instagram stall

🧪 The original failure

The investigation started with this real URL:

https://www.instagram.com/p/DcA9SsWtiNIOyeLRbzqL5B4O9moN4Wep6znlII0/

The old handler logged:

_handle_instagram() no usable title extracted
SLOW PRIVMSG: processing took 7.43s
event loop stalled

So the visible problem was “no Instagram details”.

The more important runtime problem was:

Instagram could block the IRC event loop for several seconds.

🔬 What Instagram actually returned

A dedicated read-only probe reproduced the exact handler behavior.

For the problematic post, plain HTTP returned:

HTTP 200
633 KB
<title>Instagram</title>
no og:description
no useful description

The handler then launched Chromium.

Chromium returned:

~1.6 MB rendered DOM
<title>Instagram</title>
still no useful metadata

Total handler runtime:

6.35 seconds

A second metadata probe measured:

HTTP      : ~0.76s
Chromium  : ~5.03s
Total     : ~5.78s

Chromium therefore added roughly five seconds while revealing nothing new.


🛰️ Public versus unavailable content

The same diagnostics were then run against a known public Reel:

https://www.instagram.com/reel/DH56yy7p3lZ/

That page exposed useful metadata directly over HTTP:

55K likes
282 comments
@natgeo
April 1, 2025
caption text

The existing handler completed in:

~0.9s

without needing Chromium.

A Meta oEmbed comparison confirmed the distinction:

Problematic post:

HTTP 400
OAuthException
code=24
The requested resource does not exist

Public Reel:

HTTP 200
provider=Instagram
type=rich

So Mediabot’s shortcode parsing was not the problem.

Some Instagram resources simply do not expose public metadata to an unauthenticated client.


⚡ Instagram is now asynchronous

The major runtime change is that Instagram metadata fetching now runs through:

Mediabot::AsyncWorker

Network latency no longer blocks the IRC event loop.

The Instagram path is also deliberately bounded.

Chromium is no longer invoked by the Instagram handler.

Structural guards confirm:

INSTAGRAM_ASYNC_BOUNDARY=OK
INSTAGRAM_CHROMIUM_CALLS=0

🎨 The existing Instagram badge is unchanged

The visual contract was preserved exactly.

The historical badge remains:

[Instagram]

with the same IRC color construction.

A hard IRC reset follows the badge before the rich metadata.

That means the information after the badge uses the IRC client’s normal text colors and remains readable on both light and dark themes.

No forced foreground color was added to the details.


📷 Type-aware Instagram previews

MB671 now understands the main Instagram URL families and renders them distinctly.

Examples:

📷 Post
🎬 Reel
🎥 Video
📖 Story
✨ Highlight
👤 Profile

When Instagram provides useful metadata, Mediabot extracts as much as is safely available.

A rich Reel can now look like:

[Instagram] 🎬 Reel · @natgeo · ❤️ 55K · 💬 282 · 📅 April 1, 2025 · Beautiful. Breathtaking. Home. 🌍 ...

A public Post:

[Instagram] 📷 Post · @nasaearth · ❤️ 1,147 · 💬 15 · 📅 December 11, 2025 · ...

A Profile:

[Instagram] 👤 Profile · @natgeo · National Geographic (...) · 269M Followers, 195 Following, 32K Posts ...

🛟 Clean fallbacks

When Instagram does not expose useful public details, Mediabot no longer remains silent.

It returns a deterministic type-aware fallback.

Examples:

[Instagram] 📷 Post · public details unavailable
[Instagram] 🎬 Reel · public details unavailable
[Instagram] ✨ Highlight · public details unavailable

That behavior was validated with deliberately invalid URLs as well as the original real-world unavailable post.


📖 Story false-positive hardening

Stories exposed another Instagram quirk.

A deliberately nonexistent Story:

https://www.instagram.com/stories/natgeo/9999999999999999999/

still returned:

HTTP 200
og:url = the requested Story URL

and generic metadata:

Watch this story by National Geographic on Instagram before it disappears.
283M Followers, 195 Following, 0 Posts

That is not Story content.

It is Instagram’s generic Story viewer/profile shell.

MB671 now recognizes that precise combination and suppresses it.

The result becomes:

[Instagram] 📖 Story · @natgeo · public details unavailable

A Story with genuinely useful metadata remains eligible for the rich rendering path.


🧪 Real IRC validation

The new handler was tested directly on the development bot with a varied set of real and synthetic URLs.

Public Reel:

https://www.instagram.com/reel/DH56yy7p3lZ/

Result:

🎬 Reel · @natgeo · ❤️ 55K · 💬 282 · 📅 April 1, 2025 · ...

Same shortcode as a Post:

https://www.instagram.com/p/DH56yy7p3lZ/

Result:

📷 Post · @natgeo · ❤️ 55K · 💬 282 · 📅 April 1, 2025 · ...

Another Reel:

https://www.instagram.com/reel/DGOSAUyC903/

Result:

🎬 Reel · @natgeohistory · ❤️ 20K · 💬 52 · 📅 February 18, 2025 · ...

NASA Earth posts returned author, likes, comments, dates and captions.

The NatGeo profile returned profile-level information.

The original problematic post cleanly returned:

📷 Post · public details unavailable

Invalid Reels and Posts also returned correct type-aware fallbacks.

The invalid Story returned:

📖 Story · @natgeo · public details unavailable

The invalid Highlight returned:

✨ Highlight · public details unavailable

🧯 Event-loop validation

After the IRC test matrix, the development journal was checked for:

SLOW PRIVMSG
event loop stalled
_handle_instagram

No matching stall or slow-PRIVMSG event was found during the validation window.

So the important runtime objective was met:

Instagram failure no longer freezes normal IRC processing.

🧪 Focused regression

After Story hardening:

PASSED : 323/323
RC=0

Coverage includes:

Instagram badge/reset contract
URL fast paths
Facebook/Instagram adjacent URL behavior
AsyncWorker contract
Instagram rich async behavior
module structure

⚡ Fast validation lane

The fast lane passed:

PASSED : 5242/5242
RC=0
Runtime: 171s

✅ Complete-suite certification

Because MB671 changes both URL handling and AsyncWorker use, the complete suite was run before commit.

Final result:

PASSED : 14001/14001
RC=0
Runtime: 769s

Yes — Mediabot has now crossed fourteen thousand tests.


🔒 Operational scope

MB671 introduces:

no database schema change
no migration
no configuration change
no service change
no systemd change

The change stays inside the URL/Instagram handling and its regression coverage.


📦 Commit scope

Final commit:

8 files changed
598 insertions
152 deletions

New regression file:

t/cases/853_mb671_instagram_rich_async.t

✨ Commit

e9125a9
📸 Let the Moving Portraits Reveal Instagram Without Freezing Time

Version:

3.4dev-20260819_151028

🧭 What changed in practice

Before MB671:

Instagram URL
    ↓
HTTP
    ↓
maybe Chromium
    ↓
possibly 5–8 seconds blocked
    ↓
sometimes no output

After MB671:

Instagram URL
    ↓
bounded AsyncWorker
    ↓
use public metadata when available
    ↓
rich type-aware preview
        or
clean type-aware fallback
    ↓
IRC loop keeps running

The Moving Portraits can finally tell us what they know without freezing the rest of Hogwarts. 📸✨

You must be logged in to reply.