Thoughts on ActivityPub + Dating apps

Hey folks!

I’ve been working on RetroMeet for the last few months and while the first version is not yet out of the window I was thinking about federation.

RetroMeet is a dating app and the dev of Alovoa also expressed the interest in implementing AP. I had read the AP spec a long time ago and did another read today and I have some thoughts and mostly some questions. Mostly if AP is really the thing for it.

This is a mix-and-match of my ideas, sorry if it’s confusing!

  1. Interop between RetroMeet and other federation software

    While most of the cases I saw for AP implementation wanted to leverage the existing social graph of Mastodon and other AP implementations, that is not the case for RetroMeet. RetroMeet profiles should only be visible for other RetroMeet (and other dating apps such as alovoa). Not only that, but the basic interactions between two users are not the same as in Mastodon or Friendica. Users cannot publish posts/Notes and following in that sense doesn’t fully make sense. I know that the spec says the followers collection can be dropped, so I can just reject any follow requests. Which also leads to the next point

  2. Allowlist only

    Now, this sounds like an implementation detail, but it is linked to the next point. I think it makes sense for RetroMeet that it only federates with other allowed servers. This is because the dating space is quite adversarial. I want to avoid data leaking if possible (though I am aware that it is the internet and the best I can do is try to avoid it, but can’t really control it).

    In the same point, I’m thinking of only allowing AP S2S with signed requests as the ones Mastodon implements (aka “authorized fetch”)

  3. Server discovery

    While most of the fediverse software seems to have some kind of centralized directory of servers, I was thinking of something more akin to Grokster “supernode” idea. A server would know the address of a retromeet supernode (a hard-coded one) but then through it it would discover other supernodes of the network. Those supernodes then aggregate information about nodes present in the network. This would also allow for the allowlist discovery to be suggested to the admins of instances.

  4. People around you

    The “empty feeling” of other AP software is very much a deterrent for using dating apps. If there’s no one to talk to, there’s nothing to do in the app. One thing I was thinking is that users will have a location, so any time a user changes location, I could fetch users from a collection of users around that new location (I’m ignoring here some implementation details such as caching previous calls to the same location, etc).

    This kinda still makes sense for AP, right? If, say, users were in /near?location=xxxx. (xxxx could be a name, an id, lat/long coords, etc), this could return a collection of users in that server close to that location (assuming all previous authorization concerns)

  5. Could liking a profile be matched to a following?

    I said following did not make sense, but I was thinking of the interaction of liking another profile and giving special rights to profiles that one likes and that are mutuals (for instance, making more parts of one’s profile available or only allowing messages from profiles that one has liked). For RetroMeet this would be a “like” interaction between two profiles, but it is so close to the AP definition of followers that I’m wondering if it would be useful using it. One of my fears of using “like” is that it will be mixed with AP definition of likes, OTOH using followers implies a different nature of relationship in the context of AP.

Sorry, this is really a mixed bag of thoughts. I guess I’m looking for other people that have been thinking of non-microblogging (or even long form) for AP to weigh in on those ideas.

I think there are a lot of disadvantages as you identified, so I’m kind of wondering what you see as the advantages or possible user flows that you want to make possible here. Based on what you’ve described, I don’t see any. To be clear, my perception of ActivityPub is mostly as a way to send notifications in the form of activities which can later be composed into “activity streams”. The side effects of the ActivityPub outbox allow for some publishing of web resources, as well as basic manipulation. Neither of these things serve the problem domain particularly well here.

I could see maybe having some integrations in the way of identity, but not so much in the way of communication, whether that be messaging or publishing. For example, you can indicate that you have a fediverse profile, or a website, or so on. But it’s unclear how much of what you do on-platform should be externalized onto a personal website.

Probably it would be helpful to think more about the expected interactions and boundaries of your service, and in what ways and in which contexts it makes sense to cross boundaries or enable cross-service interactions. I’d say don’t feel pressured into thinking that everything has to fit into the ActivityPub box.

To explore one of the examples you bring up of “liking another profile”, you could model this with a Like activity and the likes collection, but I suspect that this wouldn’t actually be very useful unless you wanted to track who “likes” you. In this sense, people can send a notification that they “like” you:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://dating.example/users/1/activities/1"
  "actor": "https;//dating.example/users/1",
  "type": "Like",
  "object": "https;//dating.example/users/2",
  "to": "https;//dating.example/users/2"
}

And then this activity results in the following state for user 1:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https;//dating.example/users/1",
  "type": "Person",
  "name": "Alex",
  "inbox": "https://dating.example/users/1/inbox",
  "likes": {
    "id": "https://dating.example/users/1/likes_of_me",
    "type": "Collection",
    "totalItems": 0
  },
  "liked": {
    "id": "https://dating.example/users/1/who_i_like",
    "type": "Collection",
    "totalItems": 1,
    "items": ["https;//dating.example/users/2"]
  }
}

And the following resulting state for user 2:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https;//dating.example/users/2",
  "type": "Person",
  "name": "Blake",
  "inbox": "https://dating.example/users/2/inbox",
  "likes": {
    "id": "https://dating.example/users/2/likes_of_me",
    "type": "Collection",
    "totalItems": 1,
    "items": [
      "https://dating.example/users/1/activities/1"
    ]
  },
  "liked": {
    "id": "https://dating.example/users/1/who_i_like",
    "type": "Collection",
    "totalItems": 0
  }
}

You could then do whatever logic you wanted against, say, making sure 2 users are mutually liked before indicating a match or allowing them to message each other. But again… is this kind of interaction flow “worth it” or desired in any way for the functionality of your application?

So, my primary thinking here is that it makes sense to decentralize the services: Alovoa or RetroMeet could scale horizontally, having different services housing different users. (In my mind the very ideal case would be different servers house users geographically, which would mean that they would need very few extra profiles outside of their geographical area, but I digress)

To expand on the interactions, what I’m thinking is this: the Actor could be a Person, but it could also be something more specialized (naming things is hard, but let’s say a Dater). A Dater could have more specialized fields, collections of pictures, gender, sexual preferences and etc

The messages between two Daters could use the same abstraction as Mastodon’s DMs, Notes sent to: a specific user.

Your example with liking is much like what I had in mind: Each user would have a collection of “people who like me” and “people I like”, though both are kinda private collections, and only the person that likes and the person that is liked are aware of the interaction.

In terms of functionality, let’s say you only want to show certain photos on your profile to people whom you have a mutual Like relationship with (“a match”, in most of the dating apps lingo), or that you only want to authorize people that you liked to create a new conversation with you.

I could see maybe having some integrations in the way of identity , but not so much in the way of communication , whether that be messaging or publishing. For example, you can indicate that you have a fediverse profile, or a website, or so on. But it’s unclear how much of what you do on-platform should be externalized onto a personal website.

Indeed, for me, there’s no interest in communicating with Microblogging Fediverse apps, I could link them, but for that I don’t need AP, the mutual link mechanism of “verification” that exists in some software could be used for this.

I’m more thinking of avoiding the bikeshedding of coming up with a protocol to communicate between the servers.

Does that clarify the idea a bit?

It might be somewhat unavoidable, is what I’m saying… Basically, reusing AS2 or AP doesn’t actually get you much unless you want to actively notify resources.

For protocol considerations, it would be more helpful to think about what is being decentralized – data storage? or are you doing a sort of RPC?

In my mind data storage is my main decentralization use case.

I don’t think it is an RPC situation, I’m not expecting to do live calls between other servers for fetching users elsewhere, the call I mentioned on my first post is a mitigation for the quiet server situation, but that would be done in the background, continuously, and not live while searching for nearby users.