🤦🏼‍♂️ @andreas@neumeier.org

business card.

  • Notes
  • Followers 12
  • Following 42
  • Remote follow
🤦🏼‍♂️'s avatar
🤦🏼‍♂️
@andreas@neumeier.org

My adventure in implementing #ActivityPub:

With the support of #ChatGPT I roughly understand how the protocol works and have a working implementation for at least #WebFinger and a json-LD conforming profile page.

There are some gaps in the structures, e.g. I can lookup my own user profile, @andreas@pramari.de, from microblog.pub, but not from mastodon.social yet. Obviously following does not yet work, although I have the data structures in place to store followers by profile.

Next up is the implementation of a mechanism to follow.

  • permalink
  • 17 days ago
  • 2 replies
🤦🏼‍♂️'s avatar
🤦🏼‍♂️
@andreas@neumeier.org

in reply to this object

Todays progress in my #ActivityPub adventure for the @andreas@pramari.de project: nothing much. Mostly (already) refactoring code and linting, that was compatible with my state of mind. However, I found a #tutorial that seemed reasonable to start from: https://github.com/timmot/activity-pub-tutorial In productive outcomes: the profile store now support generation of #public- and #private #keys. The generation is triggered on profile creation. I learned keys will be required in a later step to provide a signature.

GitHub - timmot/activity-pub-tutorial: Get up and running with ActivityPub quickly. GitHub
  • permalink
  • interact from your instance
  • 15 days ago
  • 1 like
  • 1 reply
Likes
@Omstero@mastodon.gamedev.place
🤦🏼‍♂️'s avatar
🤦🏼‍♂️
@andreas@neumeier.org

in reply to this object

Today in #ActivityPub. Progress with the Inbox for my future actor on the #fediverse The server should now be able to receive events in the Inbox. With that, it does already differentiate over the activity type as defined for Server to Server Interaction. Today, it does take the actor, the activity if 'Follow' and create a following relationship later on. That will come handy once we start publishing to all Followers. It does roughly look like this:

class InboxView(View): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super().dispatch(*args, **kwargs) def post(self, request, *args, **kwargs): try: # Assuming the request payload is a valid JSON activity body = request.body.decode('utf-8') activity = json.loads(body) # Deserialize the JSON payload except ValueError: return JsonResponse({'error': 'Invalid JSON'}, status=400) # Process the incoming activity # Save the activity to the database, perform necessary actions, etc. from .models import Activity activity_type = activity.get('type') activity_actor = activity.get('actor') activity_object = activity.get('object', {}) object_type = activity_object.get("type") object_content = activity_object.get("content") match(activity_type): case 'Follow': # Store the follower in the database follower_profile, created = Profile.objects.get_or_create( username=activity_actor ) if created: follower_profile.save() profile_to_follow = Profile.objects.get(username=request.user.username) follower_profile.following.add(profile_to_follow) # Optionally, you can send a response indicating the success of the follow request response = { "type": "Follow", "actor": request.build_absolute_uri( reverse( "profile", args=[request.user.username] ) ), "object": request.build_absolute_uri( reverse( "profile", args=[activity_actor] ) ), "id": "unique-id-for-the-response", } return JsonResponse(response) case 'Create': # Save the Follow activity to the database pass case _: logger.error("Activity Actor: {}".format(activity_actor)) logger.error("Activity Object: {}".format(activity_object)) print(activity) follow_activity = Activity( actor=activity_actor, verb=f'Unkown: {activity_type}', object=activity_object ) follow_activity.save() return JsonResponse({"error": "Invalid activity type"}, status=400) # Return a success response return JsonResponse({'status': 'success'})

With that, @andreas@pramari.de comes a bit closer.

ActivityPub www.w3.org
  • permalink
  • 10 days ago
  • 1 like
  • 1 reply
🤦🏼‍♂️'s avatar
🤦🏼‍♂️
@andreas@neumeier.org

in reply to this object

Further advancements with @andreas@pramari.de: Yakshaving. Google Cloud SDK outdated. And Python on the development machine outdated, too.

  • permalink
  • 10 days ago
@reiver ⊼ (Charles) :batman:'s avatar
@reiver ⊼ (Charles) :batman:
@reiver@mastodon.social

in reply to this object

@andreas

Did you learn about host-meta?

And that it should be called before you call WebFinger?

  • permalink
  • 17 days ago
🤦🏼‍♂️'s avatar
🤦🏼‍♂️
@andreas@neumeier.org

in reply to this object

@reiver@mastodon.social kind of. I am implementing the server component that clients are calling.

/.well-known/host-meta is currently implemented as a static file.

What do I have to pay attention to in this flow?

  • permalink
  • 17 days ago
  • 1 reply
@reiver ⊼ (Charles) :batman:'s avatar
@reiver ⊼ (Charles) :batman:
@reiver@mastodon.social

in reply to this object

@andreas

If you are implementing a server, then you will likely have to contact other servers.

(For example, to do a remote-follow.)

You should request host-meta on the remote-server first, to see where WebFinger is. And not just assume it is at the /.well-known/ path.

  • permalink
  • 16 days ago
🤦🏼‍♂️'s avatar
🤦🏼‍♂️
@andreas@neumeier.org

in reply to this object

@reiver@mastodon.social Appreciate the pointer. I'm not there yet, but will consider when implementing the follow function. Right now I'm only over the 'being followed' part.

  • permalink
  • 16 days ago
  • 1 like

andreas (c) 2000-2023