Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Activitypub Bundle Laravel Package

assemblee-virtuelle/activitypub-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require assemblee-virtuelle/activitypub-bundle
    

    Ensure your config/bundles.php includes:

    AssembleeVirtuelle\ActivityPubBundle\ActivityPubBundle::class => ['all' => true],
    
  2. Configuration Add to config/packages/activitypub.yaml:

    activitypub:
        domain: 'https://yourdomain.com'
        actor_model: App\Entity\YourActorEntity
        inbox_endpoint: '/api/inbox'
        outbox_endpoint: '/api/outbox'
    
  3. First Use Case: Basic Actor Setup Create an Actor entity (e.g., User or Group) extending ActivityPubBundle's base Actor class:

    use AssembleeVirtuelle\ActivityPubBundle\Entity\Actor;
    
    #[ORM\Entity]
    class User extends Actor
    {
        // Your custom fields (e.g., name, email)
    }
    
  4. Enable Routes The bundle provides default routes for inbox/outbox. Verify in config/routes.yaml:

    activitypub_inbox:
        path: /api/inbox
        controller: AssembleeVirtuelle\ActivityPubBundle\Controller\InboxController::handle
    
  5. Test with curl Fetch an actor's profile (replace :id with a valid entity ID):

    curl -H "Accept: application/activity+json" https://yourdomain.com/api/actors/:id
    

Implementation Patterns

Core Workflows

1. Actor Management

  • Create/Update Actors: Use the ActorManager service to hydrate entities with ActivityPub metadata:
    $actorManager = $this->get('activitypub.actor.manager');
    $actor = $actorManager->createActor($userEntity);
    $actorManager->persist($actor);
    
  • Fetch Remote Actors: Leverage the ActorFetcher to resolve remote actors by URL:
    $fetcher = $this->get('activitypub.actor.fetcher');
    $remoteActor = $fetcher->fetch('https://remote.com/users/john');
    

2. Activity Handling

  • Posting Activities: Create activities (e.g., Create, Like) via the ActivityFactory:
    $factory = $this->get('activitypub.activity.factory');
    $activity = $factory->createActivity(
        'Create',
        $actor,
        ['object' => $postEntity]
    );
    $activityManager = $this->get('activitypub.activity.manager');
    $activityManager->publish($activity);
    
  • Inbox Processing: Override InboxController to handle incoming activities:
    public function handle(Request $request, ActivityManager $activityManager)
    {
        $activity = $activityManager->processIncoming($request->getContent());
        // Custom logic (e.g., store, notify)
    }
    

3. Object Serialization

  • Custom Objects: Extend ActivityPubBundle\Object\Object for domain-specific objects (e.g., Note, Article):
    use AssembleeVirtuelle\ActivityPubBundle\Object\Object;
    
    class Post extends Object
    {
        #[ORM\Column]
        private string $content;
    
        public function getType(): string { return 'Note'; }
    }
    
  • Automatic Hydration: Use @ActivityPub\Object to auto-map Doctrine entities:
    #[ActivityPub\Object(type: 'Note')]
    #[ORM\Entity]
    class BlogPost { ... }
    

4. Webhooks and Polling

  • Outbox Polling: Schedule a cron job to fetch updates from followed actors:
    $followManager = $this->get('activitypub.follow.manager');
    $followManager->pollFollowedActors();
    
  • Webhook Integration: Configure a route to handle ActivityPub\Follow webhooks:
    activitypub_webhook:
        path: /api/webhook
        controller: App\Controller\WebhookController::handleFollow
    

Integration Tips

Symfony Ecosystem

  • Twig Integration: Use the activitypub.twig.extension to render ActivityPub links:
    {{ actor|activitypub_url('inbox') }}
    
  • Messenger Integration: Dispatch activities as messages for async processing:
    $this->get('messenger')->dispatch(
        new PublishActivityMessage($activity)
    );
    

Performance

  • Caching: Cache resolved remote actors and activities:
    # config/packages/cache.yaml
    frameworks:
        cache:
            app.activitypub: ~
    
  • Batch Processing: Use ActivityPubBundle\Batch\ActivityBatch for bulk operations (e.g., fetching multiple actors).

Testing

  • Mocking Actors: Use ActivityPubBundle\Test\ActorFactory for unit tests:
    $actor = $this->get('activitypub.test.actor_factory')->create();
    
  • HTTP Tests: Test inbox/outbox endpoints with HttpClient:
    $response = $client->request('POST', '/api/inbox', [
        'headers' => ['Content-Type' => 'application/activity+json'],
        'body' => json_encode($activityData),
    ]);
    

Gotchas and Tips

Pitfalls

1. Doctrine vs. Triple Store

  • The bundle defaults to Doctrine/ORM, but the roadmap targets Apache Jena Fuseki. If migrating later:
    • Override ActivityPubBundle\Storage\StorageInterface to swap implementations.
    • Expect breaking changes in future versions.

2. IDURIs and Canonical URLs

  • Issue: Incorrect id or url fields in actors/activities can break federation.
  • Fix: Ensure your Actor and Object entities implement getId() and getUrl() correctly:
    public function getId(): string { return $this->url; } // Must be absolute URL
    

3. Signature Validation

  • Issue: Incoming activities without valid signatures (e.g., from https://example.com) may fail silently.
  • Debug: Enable debug mode in activitypub.yaml:
    activitypub:
        debug:
            validate_signatures: true
    
  • Solution: Implement ActivityPubBundle\Validator\SignatureValidatorInterface for custom logic.

4. Rate Limiting

  • Issue: Polling remote actors or processing inboxes can overwhelm servers.
  • Fix: Use Symfony’s RateLimiter or add middleware:
    $limiter = $this->get('rate_limiter.activitypub');
    if (!$limiter->isAllowed('fetch_actor', 10, 60)) {
        throw new \RuntimeException('Rate limit exceeded');
    }
    

5. Type Mismatches

  • Issue: Activities with unsupported type (e.g., Announce) may not be processed.
  • Fix: Extend ActivityPubBundle\Activity\Activity or register custom handlers:
    # config/packages/activitypub.yaml
    activitypub:
        activity_handlers:
            Announce: App\Handler\AnnounceHandler
    

Debugging Tips

1. Enable Verbose Logging

Add to config/packages/monolog.yaml:

handlers:
    activitypub:
        type: stream
        path: "%kernel.logs_dir%/activitypub.log"
        level: debug
        channels: ["activitypub"]

2. Validate JSON-LD

Use JSON-LD Playground to validate serialized output:

$serializer = $this->get('activitypub.serializer');
$jsonLd = $serializer->serialize($activity, 'json-ld');

3. Check HTTP Headers

Ensure responses include:

Content-Type: application/activity+json
Link: <https://yourdomain.com>; rel="http://www.w3.org/ns/activitystreams#public"

4. Common Errors

  • InvalidActorException: Actor entity lacks required fields (@context, id, type).
  • SignatureVerificationFailed: Remote activity lacks or has invalid signature.
  • UnknownActivityType: Activity type not registered in the bundle.

Extension Points

1. Custom Activity Types

Extend ActivityPubBundle\Activity\Activity or create a new handler:

namespace App\Activity;

use AssembleeVirtuelle\ActivityPubBundle\Activity\Activity;

class CustomActivity extends Activity
{
    public function getType():
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
monarobase/country-list
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity