From 40acf104a1af5e96d16f0175a79f136b8b9f8020 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Tue, 28 Jul 2026 01:40:22 +0200 Subject: [PATCH] feat(share): spell out og:image:secure_url + type for the Facebook scraper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iPad Messenger app unfurls a share link on-device (fetches + renders the OG tags itself), but messenger.com desktop shows only what Facebook's server-side scraper cached — which is pickier. Add og:image:secure_url (public HTTPS) and og:image:type=image/jpeg for our poster so the card renders even when the scraper won't sniff the bytes. Reachability/stale-cache is a separate, live-diagnosis step. --- backend/app/downloads/og.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backend/app/downloads/og.py b/backend/app/downloads/og.py index a28ee99..f1bcdc9 100644 --- a/backend/app/downloads/og.py +++ b/backend/app/downloads/og.py @@ -73,6 +73,12 @@ def _watch_tags(token: str, db: Session) -> str | None: if image: # A real thumbnail → a large image card; without one, a plain (text) card is served. tags.append(_tag("og:image", image)) + # Facebook's scraper is pickier than Apple's on-device unfurl: spell out that the image is a + # public HTTPS JPEG so it renders the card even when it won't fetch/sniff the bytes itself. + if image.startswith("https://"): + tags.append(_tag("og:image:secure_url", image)) + if image.endswith("poster.jpg"): + tags.append(_tag("og:image:type", "image/jpeg")) tags.append(_tag("twitter:card", "summary_large_image", attr="name")) tags.append(_tag("twitter:image", image, attr="name")) else: