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

Laravel Buffer Laravel Package

jeffersongoncalves/laravel-buffer

A Laravel integration for the Buffer API that lets you schedule and manage social media posts directly from your application. It provides a simple, configurable wrapper for connecting your Buffer account and publishing content across supported networks.

View on GitHub
Deep Wiki
Context7

Getting Started

This package wraps the Buffer API so you can schedule and inspect social posts from Laravel instead of hand-rolling Guzzle calls. Since 1.0.0 is the first stable tag, treat the changelog and the package's src/ + config/ as the source of truth — the release notes themselves are just a tag.

Minimal setup:

  1. composer require jeffersongoncalves/laravel-buffer
  2. Publish the config: php artisan vendor:publish --tag=buffer-config (check php artisan vendor:publish for the exact tag — providers registered by the package will list it).
  3. Add credentials to .env — typically a Buffer access token (and possibly a client id/secret if the package ships an OAuth flow). Read the published config/buffer.php first; it names the exact env keys.
  4. Register/confirm the facade alias or resolve the service from the container (app(Buffer::class) / the facade shown in the package README).

First use case: read your channels, then post something. Resolve the client, call the "list profiles/channels" endpoint, grab a channel id, and push a single update with text + optional media to the queue or to a specific scheduled_at. Do this in php artisan tinker before writing any app code — it confirms your token scopes and shows you the response shape you'll be mapping in jobs.

Implementation Patterns

Wrap every call in a queued job. Buffer is an external HTTP dependency; calling it inline from a controller or an Eloquent observer will eventually time out a web request. A PublishToBuffer job with retry(3) and backoff([30, 120, 600]) is the standard shape:

final class PublishToBuffer implements ShouldQueue
{
    public function __construct(public Post $post) {}

    public function handle(Buffer $buffer): void
    {
        $update = $buffer->updates()->create([
            'profile_ids' => [$this->post->channel_id],
            'text'        => $this->post->body,
            'media'       => ['photo' => $this->post->image_url],
            'scheduled_at' => $this->post->publish_at->toIso8601String(),
        ]);

        $this->post->update(['buffer_update_id' => $update->id]);
    }
}

(The exact method names come from the package's client class — read it once and mirror it.)

Persist the remote id. Store buffer_update_id on your model. You will need it for edits, deletes, and for reconciling status later. Without it you're reduced to fuzzy text matching.

Use "add to queue" vs "schedule at" deliberately. Buffer has two distinct modes: now/queue (drops into the next free slot for that channel's posting schedule) and scheduled_at (explicit timestamp). Model these as two enum cases in your own app, because they behave completely differently when you're bulk-importing content.

Multi-tenant / multi-account. If each of your users has their own Buffer token, don't rely on the singleton config. Resolve a client instance per tenant with their stored token and pass it into the job — the config file is the default, not the ceiling. Cache the channel list per tenant with a short TTL; it changes rarely and costs a request every time.

Testing. The package almost certainly goes through Laravel's HTTP client, so Http::fake() with a canned Buffer payload lets you assert your job without network. Fake the package's endpoints (check src/ for the base URL) rather than wrapping it in your own HTTP layer.

Integration tip: keep a thin BufferPublisher service of your own that speaks your domain (publish(Post $post)), and let it delegate to the package. That gives you one place to swap packages, add idempotency keys, and add logging — and it keeps package types out of your controllers.

Gotchas and Tips

  • Rate limits are per-token and unforgiving. Buffer throttles aggressively. If you're backfilling a month of content, chunk with Bus::batch()->chunk() and add release() on 429 rather than letting the job fail. A failed schedule is silent — nothing gets posted and nobody notices until a client asks.
  • Timezones. scheduled_at is absolute; the queue is relative to the channel's configured timezone, which you don't control from Laravel. If exact publish times matter, use scheduled_at with an explicit UTC/Z offset, not the queue.
  • Media must be publicly reachable. Buffer fetches the image URL server-side. Local storage/app paths and localhost URLs will fail at Buffer's end, not yours — the create call succeeds and the post later shows a broken image. Use signed/public URLs with a generous expiry.
  • Token handling. A 401 usually means an expired OAuth token or a revoked personal token, and it often surfaces as a generic HTTP exception. Catch and map it to a "reconnect your account" UI state rather than retrying forever — retrying a 401 just burns queue attempts.
  • Text-length limits are per-network. Buffer will reject or truncate over-long posts depending on the endpoint. Validate against the strictest target channel before dispatching, so users get feedback in the form and not in a failed job.
  • Debugging. Log the raw response body on non-2xx ($response->body()), because the package may only throw a status-coded exception. A ?debug=true middleware logging all outgoing HTTP via Http::globalRequestMiddleware() is worth adding during integration.
  • 1.0.0 means no upgrade history yet. Pin with ^1.0 and watch for the first few patch releases — pre-1.0 packages often carry naming churn into their first stable tag. Read the config file after every minor bump; config keys are the most common silent breaking change.
  • Extension points. If the package's client is bound in its service provider with a concrete class, you can swap it via $this->app->bind(...) in your own provider — useful for injecting a mocked client in feature tests without touching Http::fake().
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib