Weave 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

Social Media Aggregator Bundle Laravel Package

milosa/social-media-aggregator-bundle

The Milosa Social Media Aggregator Bundle for Symfony lets you collect and display social media posts in one unified feed. Configure providers, aggregate content, and render results in your PHP app with minimal setup. Ideal for dashboards and marketing pages, with simple configuration and template-f...

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're adopting first. This is a Symfony bundle — not a Laravel package. There is no Illuminate\Support\ServiceProvider, no package discovery, no config/*.php file, and no facade. As of v0.0.10 the plugin system has been removed and every integration now lives in this one repository, so there is no longer a plugin registry to discover providers through — you read src/ and find them directly. The repo is archived (last tagged release Dec 2020), so treat it as source code to read and mine, not a dependency to composer require and forget.

Where to look, in order:

  1. composer.json — check the symfony/* constraints. A 2020 bundle will typically require Symfony 4.4/5.x. Laravel 10/11 ship Symfony 6/7 components, so composer require may hard-fail on conflict. If it does, stop here and vendor the classes manually.
  2. src/ — find the aggregator/feed class (the thing that returns a combined list) and the provider/adapter interface each platform implements. Since v0.0.10 merged the plugins in, all platform providers are colocated here; this is the only part with real value.
  3. DependencyInjection/ + Resources/config/services.* — shows how providers are registered and which parameters (API keys, limits, platform toggles) are expected. Note that the v0.0.10 merge means this file grew: every provider is now wired unconditionally, so check whether you can actually disable platforms you don't use.
  4. README — usually contains the sample config/packages/*.yaml block; that's your de-facto config schema. It may still describe the old plugin installation flow, so trust the YAML over the prose.

Minimal first run (Symfony-style, in a scratch app or a Laravel dev container):

composer require milosa/social-media-aggregator-bundle

Register the bundle in bundles.php, copy the YAML config from the README into config/packages/, fill in the platform credentials, then resolve the aggregator service from the container and foreach over the returned messages.

First use case to target: a read-only "social wall" endpoint — one route, one call into the aggregator, one normalized JSON response. Don't try to solve two-way posting or per-user OAuth on day one; this package is a read aggregator.

Implementation Patterns

1. Wrap, don't spread. Write a single Laravel service provider that binds the aggregator (or your own extracted SocialFeed class) as a singleton, and inject that everywhere. Never let a controller touch the bundle's container directly.

$this->app->singleton(SocialFeed::class, fn () => new SocialFeed(
    providers: [
        new TwitterProvider(config('services.twitter.token')),
        new FacebookProvider(config('services.facebook.token')),
    ],
));

2. Adapter-per-platform is the real architecture. The bundle's model is one class per network returning a common message shape — and after v0.0.10 that's all still intact, just consolidated. Keep that contract and add your own providers as separate files implementing the same interface — this is also the cleanest way around the MPL-2.0 file-level copyleft.

3. Normalize at the boundary, not in the view. Map each platform payload to your own DTO (id, platform, author, body, mediaUrl, publishedAt, permalink). Every network names those fields differently and will rename them again. Your Blade/API layer should never see platform-specific keys.

4. Pull into a table, don't render live. The single biggest reliability win: an artisan social:sync command on the scheduler that writes messages into social_messages, deduped on (platform, external_id). Your feed endpoint then queries your own DB. API outages, rate limits, and token expiry stop being page-load failures.

5. Cache the API layer, queue the sync. Wrap each provider call in Cache::remember("social:{$platform}:{$account}", now()->addMinutes(10), ...) and run the sync in a queued job. The bundle has no caching or rate-limit handling of its own.

6. Test by faking the provider, not the network. Because providers are plain classes behind an interface, bind a stub implementation in the test container. Where the bundle does its own HTTP, use Laravel's Http::fake() — but only if it's built on Symfony HttpClient, which you'll need to verify in src/.

7. The removed plugin system changes what you fork. Previously you could in principle swap a plugin package without touching this repo; now you cannot. Fork strategy should be "copy src/Provider/* into app/Social/Providers/ and rewrite the HTTP layer", not "keep the bundle and override a plugin".

Gotchas and Tips

  • v0.0.10 is a breaking restructure on a 0.x package. Removing the plugin system means any install instructions, forks, or plugin repos you find referenced in blog posts and issues are now stale. It also confirms the project had real churn after its last tagged release, yet is still archived — treat every version boundary as potentially breaking.
  • Archived + 2020 = API drift. Twitter/X has moved to v2, Facebook Graph versions expire every ~2 years, Instagram's Basic Display API has been reshaped. Assume the shipped provider implementations are broken until proven otherwise; budget for rewriting each one. The aggregation shape survives, the endpoint calls almost certainly don't.
  • One consolidated autoloader loads every provider. With plugins folded in, a broken/unmaintained provider can now fail earlier (class load, DI compile) rather than only when enabled. Another argument for copying the files you need instead of installing the bundle.
  • Symfony/Laravel container mismatch. Configuration in a Symfony bundle is compiled YAML with %parameters%, and older bundles use !tagged / compiler passes that Symfony 6.1+ removed or renamed. If you install it, you'll be translating DI config by hand — usually not worth it versus copying src/ into app/Social/.
  • env() in bundle config won't survive config:cache. Move every credential into config/services.php and read it through config(). This is the number-one silent production break for ported Symfony config.
  • Tokens are per-user, not per-app. The bundle's config schema almost certainly assumes static app credentials. Real feeds need per-account OAuth with refresh. Store tokens in your own table with an expires_at and refresh before calling.
  • One failing platform kills the whole feed unless you isolate it. Wrap every provider call in its own try/catch, log the platform, and return partial results — never let a single expired token blank the page.
  • Pagination semantics differ wildly: since_id (Twitter), cursor strings (Facebook/Instagram), until/before (others). Don't try to unify into one cursor until you've read each provider's loop; a "fetch N" abstraction per platform is more honest.
  • Media URLs expire. Instagram/Facebook CDN links are short-lived and the original may be deleted. Copy media to your own disk on ingest if it matters.
  • Ordering and timezones. Platforms return ISO-8601 with different offsets, sometimes Unix timestamps. Normalize to UTC CarbonImmutable at the boundary and sort on that, not on string comparison.
  • Debugging: the bundle is opaque, so inspect what's actually bound. In tinker, app()->make(...) the aggregator and dump() the raw per-provider responses before normalization. Log the raw payload for one sync cycle — it's the fastest way to see which platform broke.
  • Licensing: MPL-2.0 is file-level copyleft. Using it as a dependency is fine commercially; if you modify files from the bundle and distribute, those files must be published. Keeping your own providers and DTOs in new files keeps your codebase clean — and v0.0.10's consolidation makes "new files only" more important, since the in-repo providers are now the code you'd most want to edit.
  • Extension points worth reusing: the provider interface, the aggregator's ordering/dedup logic, and the message DTO. Everything else — DI wiring, config schema, the Symfony-specific glue — is what you're paying to replace.
  • If you only take one thing: skip the bundle entirely for a Laravel app. Read src/, lift the interface and the merge/dedup logic, and write the HTTP calls against Laravel's Http client with retry() and throw() semantics you actually control. At 16 stars and zero dependents, the maintenance risk of depending on it outweighs the ~200 lines you'd otherwise write.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource