From 44dbc063eedc4537af917bfbbebcb02c5d20073a Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 22 Feb 2026 09:59:26 +0000 Subject: [PATCH] Make followers/following collections public (paginated format) Mastodon requires OrderedCollection with a `first` page link to consider the collection public. Without it, it shows "This user has chosen to not make this information available." Co-Authored-By: Claude Opus 4.6 --- bp/actors/routes.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/bp/actors/routes.py b/bp/actors/routes.py index 060f867..bcb8979 100644 --- a/bp/actors/routes.py +++ b/bp/actors/routes.py @@ -353,13 +353,28 @@ def register(url_prefix="/users"): abort(404) domain = _domain() + collection_id = f"https://{domain}/users/{username}/followers" follower_list = await services.federation.get_followers(g.s, username) + page_param = request.args.get("page") + + if not page_param: + return Response( + response=json.dumps({ + "@context": "https://www.w3.org/ns/activitystreams", + "type": "OrderedCollection", + "id": collection_id, + "totalItems": len(follower_list), + "first": f"{collection_id}?page=1", + }), + content_type=AP_CONTENT_TYPE, + ) return Response( response=json.dumps({ "@context": "https://www.w3.org/ns/activitystreams", - "type": "OrderedCollection", - "id": f"https://{domain}/users/{username}/followers", + "type": "OrderedCollectionPage", + "id": f"{collection_id}?page=1", + "partOf": collection_id, "totalItems": len(follower_list), "orderedItems": [f.follower_actor_url for f in follower_list], }), @@ -373,11 +388,27 @@ def register(url_prefix="/users"): abort(404) domain = _domain() + collection_id = f"https://{domain}/users/{username}/following" + page_param = request.args.get("page") + + if not page_param: + return Response( + response=json.dumps({ + "@context": "https://www.w3.org/ns/activitystreams", + "type": "OrderedCollection", + "id": collection_id, + "totalItems": 0, + "first": f"{collection_id}?page=1", + }), + content_type=AP_CONTENT_TYPE, + ) + return Response( response=json.dumps({ "@context": "https://www.w3.org/ns/activitystreams", - "type": "OrderedCollection", - "id": f"https://{domain}/users/{username}/following", + "type": "OrderedCollectionPage", + "id": f"{collection_id}?page=1", + "partOf": collection_id, "totalItems": 0, "orderedItems": [], }),