Podcastindex-org / pi-activitypub-server

An activitypub bridge for the podcast index api
MIT License
13 stars 3 forks source link

Outbox contents don't match note objects, mismatched `id`s #7

Open qazmlp opened 2 months ago

qazmlp commented 2 months ago

Looking at Postcasting 2.0, the outbox contains Create activities with objects shaped like this:

…
{
  "id": "https://ap.podcastindex.org/episodes?id=920666&statusid=PC20-175&resource=activity",
  "type": "Create",
  "actor": "https://ap.podcastindex.org/podcasts?id=920666",
  "published": "2024-04-12T19:21:03+00:00",
  "directMessage": false,
  "to": [
    "https://www.w3.org/ns/activitystreams#Public"
  ],
  "object": {
    "id": "https://ap.podcastindex.org/episodes?id=920666&statusid=PC20-175&resource=post",
    "type": "Note",
    "summary": null,
    "inReplyTo": null,
    "published": "2024-04-12T19:21:03+00:00",
    "url": "https://ap.podcastindex.org/episodes?id=920666&statusid=PC20-175&resource=public",
    "attributedTo": "https://ap.podcastindex.org/podcasts?id=920666",
    "to": [
      "https://www.w3.org/ns/activitystreams#Public"
    ],
    "cc": null,
    "sensitive": false,
    "conversation": "tag:ap.podcastindex.org,2024-04-12T19:21:03+00:00:objectId=PC20-175:objectType=Conversation",
    "content": "<p>Episode 175: Everyone's an Actor</p><p><p>Podcasting 2.0 April 12th 2024 Episode 175: \"Everyone's and Actor\"</p>\n<p>Adam & Dave Dive deep into App Social Interactions </p><p>Listen: https://op3.dev/e/mp3s.nashownotes.com/PC20-175-2024-04-12-Final.mp3</p>",
    "attachment": []
      }
    },
…

If I navigate to the Note using its id (…&resource=post), I see different data and the ID doesn't contain this suffix:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams"
  ],
  "id": "https://ap.podcastindex.org/episodes?id=920666&statusid=PC20-175",
  "type": "Note",
  "summary": null,
  "inReplyTo": null,
  "published": "2024-04-12T19:21:03+00:00",
  "url": null,
  "attributedTo": "https://ap.podcastindex.org/podcasts?id=920666",
  "to": [
    "https://www.w3.org/ns/activitystreams#Public"
  ],
  "cc": [
    "https://ap.podcastindex.org/followers?id=920666"
  ],
  "sensitive": false,
  "conversation": "https://ap.podcastindex.org/contexts?id=920666&statusid=PC20-175",
  "content": "<p>Title: <a href=\"https://podcastindex.org/podcast/920666?episode=21265199886\">Episode 175: Everyone's an Actor</a></p><p>Shownotes:<br><p>Podcasting 2.0 April 12th 2024 Episode 175: \"Everyone's and Actor\"</p>\n<p>Adam & Dave Dive deep into App Social Interactions and Phase 7 of the namespace</p>\n\n<p>ShowNotes</p>\n<p>We are LIT</p>\n<p>Social Interact - Cross App Comments</p>\n<p>Owncast - Fr</p><p><a href=\"https://steno.fm/show/917393e3-1b1e-5cef-ace4-edaa54e1f810/episode/UEMyMC0xNzU=\">Transcript</a></p><p><a href=\"https://antennapod.org/deeplink/subscribe?url=http://mp3s.nashownotes.com/pc20rss.xml\">AntennaPod</a> | <a href=\"https://anytimeplayer.app/subscribe?url=http://mp3s.nashownotes.com/pc20rss.xml\">Anytime Player</a> | <a href=\"https://podcasts.apple.com/podcast/id1584274529\">Apple Podcasts</a> | <a href=\"https://castamatic.com/guid/917393e3-1b1e-5cef-ace4-edaa54e1f810\">Castamatic</a> | <a href=\"https://curiocaster.com/podcast/pi920666\">CurioCaster</a> | <a href=\"https://fountain.fm/show/920666\">Fountain</a> | <a href=\"https://gpodder.net/subscribe?url=http://mp3s.nashownotes.com/pc20rss.xml\">gPodder</a> | <a href=\"https://overcast.fm/itunes1584274529\">Overcast</a> | <a href=\"https://pcasts.in/feed/http://mp3s.nashownotes.com/pc20rss.xml\">Pocket Casts</a> | <a href=\"https://podcastaddict.com/feed/http://mp3s.nashownotes.com/pc20rss.xml\">Podcast Addict</a> | <a href=\"https://app.podcastguru.io/podcast/1584274529\">Podcast Guru</a> | <a href=\"https://podnews.net/podcast/pi920666\">Podnews</a> | <a href=\"https://api.podverse.fm/api/v1/podcast/podcastindex/920666\">Podverse</a> | <a href=\"https://truefans.fm/917393e3-1b1e-5cef-ace4-edaa54e1f810\">Truefans</a></p><p>Or <a href=\"https://op3.dev/e/mp3s.nashownotes.com/PC20-175-2024-04-12-Final.mp3\">Listen</a> right here.</p>",
  "attachment": [
    {
      "name": null,
      "type": "Document",
      "value": null,
      "mediaType": null,
      "url": "https://noagendaassets.com/enc/1684513486.722_pcifeedimage.png",
      "blurhash": null,
      "width": 640,
      "height": null
    }
  ],
  "actor": "https://ap.podcastindex.org/podcasts?id=920666",
  "tag": [],
  "replies": null
}

The Create's id (…&resource=activity) mistakenly returns just the Note instead of the Create object too when resolved.


I see a few failure modes that could result from this. For example, a server that fetches an actor's outbox to backfill the profile timeline whenever its first local follower appears could end up with defective versions of these posts, distinct duplicates, or reject them entirely.

Boosting the outbox-retrieved version of these Notes onto other instances would most likely also fail in many cases, as Announces normally don't contain their object inline and ids must be treated as opaque blobs. It's possible it could still work in some circumstances, but this would depend on the receiver resolving one id to another and editing its ingested copy of the Announce in response, which it probably shouldn't do if it wants to avoid glitches.