Search by

draliragab / socialize

Unified Laravel social media publishing for Facebook, Instagram, X, and LinkedIn.

Maintainers

Package info

github.com/DrAliRagab/Socialize

pkg:composer/draliragab/socialize

Transparency log

Statistics

Installs: 771

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v3.5.0 2026-08-26 00:37 UTC

README

Unified social publishing for Laravel.

Socialize gives you one fluent API to share content to Facebook, Instagram, X, and LinkedIn, while still letting you use provider-specific features when needed.

Why Socialize

  • One shared fluent API across providers
  • Provider-specific chaining for platform-only features
  • URL and local file media support with automatic normalization
  • Named profile support per provider (multi-account ready)
  • Strict typing, custom exceptions, and high test coverage
  • Built for modern Laravel (11/12) and PHP 8.4+

Supported Providers

  • Facebook (facebook)
  • Instagram (instagram)
  • X / Twitter (twitter or x)
  • LinkedIn (linkedin)

Requirements

  • PHP ^8.4
  • Laravel ^11.0 | ^12.0

Installation

composer require draliragab/socialize

Publish configuration:

php artisan vendor:publish --tag="socialize-config"

Quick Start

use DrAliRagab\Socialize\Facades\Socialize;

$result = Socialize::provider('facebook')
    ->message('New release is live')
    ->link('https://example.com/release')
    ->share();

$id = $result->id();
$url = $result->url();

Comment on an existing post (all providers):

$comment = Socialize::provider('facebook')
    ->commentOn($id, 'Thanks everyone!');

Share then immediately add a comment:

$comment = Socialize::provider('linkedin')
    ->message('New release is live')
    ->link('https://example.com/release')
    ->shareAndComment('Happy to answer questions below.');

Switch provider with the same shared methods:

foreach (['facebook', 'instagram', 'twitter', 'linkedin'] as $provider) {
    Socialize::provider($provider)
        ->message('Hello from Socialize')
        ->link('https://example.com')
        ->share();
}

Fluent API

Shared methods

  • message(?string $message)
  • link(?string $url, ?string $articleTitle = null)
  • imageUrl(?string $url)
  • videoUrl(?string $url)
  • media(string $source, ?string $mediaType = null)
  • mediaId(string $id)
  • mediaIds(array $ids)
  • metadata(array $metadata)
  • option(string $key, mixed $value)
  • share(): ShareResult
  • commentOn(string $postId, string $message): CommentResult
  • shareAndComment(string $message): CommentResult
  • delete(string $postId): bool

Provider-specific methods

Facebook:

  • reel()
  • videoTitle(string $title)
  • published(bool $published = true)
  • scheduledAt(string|int|DateTimeInterface $dateTime)
  • targeting(array $targeting)

Instagram:

  • carousel(array $imageUrls)
  • altText(string $text)
  • reel()

Facebook videos remain regular Page videos by default. Add reel() to use Meta's dedicated Reels publishing workflow:

Socialize::facebook()
    ->message('Reel caption')
    ->videoTitle('Reel title')
    ->videoUrl('https://cdn.example.com/reel.mp4')
    ->reel()
    ->share();

X / Twitter:

  • replyTo(string $postId)
  • quote(string $postId)
  • poll(array $options, int $durationMinutes)

LinkedIn:

  • visibility(string $visibility)
  • distribution(string $distribution)
  • mediaUrn(string $mediaUrn)
  • videoTitle(string $title)
  • poll(array $options, int $durationMinutes)

Facebook and LinkedIn expose a video title separately from the post text. message() maps to Facebook description or LinkedIn commentary, while videoTitle() maps to Facebook title or LinkedIn content.media.title. Instagram and X do not expose a separate video title.

Poll notes:

  • poll() is supported for twitter and linkedin.
  • For LinkedIn, message() is used as the poll question (max 140 chars).
  • LinkedIn accepts only these poll durations (minutes): 1440, 4320, 10080, 20160.

Media Handling (URL + Local File)

Socialize keeps the API fluent and provider-agnostic:

  • Local Facebook Reels and local Instagram videos, Reels, Stories, and carousel videos are uploaded directly from disk through Meta's resumable upload endpoints.
  • Media types that still use URL-based publishing, including Instagram images and regular Facebook Page photos/videos, are exposed through a temporary public URL and cleaned up afterward.
  • If a provider expects uploaded media IDs/URNs (for example X/LinkedIn) and you pass a URL, Socialize downloads and uploads it automatically.

Examples:

// Local Facebook Reel -> direct binary upload
Socialize::provider('facebook')
    ->media('/absolute/path/reel.mp4', 'video')
    ->message('Local Reel')
    ->reel()
    ->share();

// Local image -> temporary URL flow where Meta still requires a URL
Socialize::provider('facebook')
    ->media('/absolute/path/banner.jpg', 'image')
    ->message('Local image test')
    ->share();

// URL image -> provider upload flow for upload-based providers
Socialize::provider('linkedin')
    ->media('https://picsum.photos/1200/800', 'image')
    ->message('URL image test')
    ->share();

LinkedIn Link Title (Optional)

LinkedIn can require richer link content. You can pass an optional title using the second link() argument:

Socialize::provider('linkedin')
    ->message('Product update')
    ->link('https://example.com/post', 'Product update details')
    ->share();

This argument is optional and safe to keep in cross-provider fluent code.

Using Profiles

Socialize::provider('facebook', 'marketing')
    ->message('Campaign announcement')
    ->share();

Error Handling

use DrAliRagab\Socialize\Exceptions\ApiException;

try {
    Socialize::provider('twitter')->message('Hello X')->share();
} catch (ApiException $e) {
    $provider = $e->provider()->value;
    $status = $e->status();
    $method = $e->requestMethod();
    $url = $e->requestUrl();
    $response = $e->responseBody();       // Parsed JSON, when available
    $responseText = $e->responseText();   // Bounded plain-text fallback
    $responseHeaders = $e->responseHeaders();
    $logContext = $e->context();           // Redacted, structured diagnostics
}

ApiException messages include common provider details such as nested debug messages, error type, code/subcode, status, retryability, and trace ID when supplied by the provider. Laravel automatically adds the exception's context() data when reporting it. The context includes the failed request method/URL, provider response, and selected diagnostic response headers; token, secret, authorization, signature, and cookie fields are redacted. responseBody() remains the unmodified provider JSON for callers that explicitly need it, so do not expose it publicly without applying your own redaction policy.

Model Trait

Use DrAliRagab\Socialize\Concerns\CanShareSocially to share directly from Eloquent models:

use DrAliRagab\Socialize\Concerns\CanShareSocially;

class Post extends Model
{
    use CanShareSocially;
}

$post->shareToFacebook();
$post->shareTo('linkedin');

The trait maps model fields using socialize.model_columns.

Configuration

All settings live in config/socialize.php.

General environment variables

  • SOCIALIZE_DEFAULT_PROFILE (optional, default: default)
  • SOCIALIZE_HTTP_TIMEOUT (optional, default: 120)
  • SOCIALIZE_HTTP_CONNECT_TIMEOUT (optional, default: 30)
  • SOCIALIZE_HTTP_RETRIES (optional, default: 1)
  • SOCIALIZE_HTTP_RETRY_SLEEP_MS (optional, default: 150)
  • SOCIALIZE_TEMP_MEDIA_DISK (optional, default: public)
  • SOCIALIZE_TEMP_MEDIA_DIRECTORY (optional, default: socialize-temp)
  • SOCIALIZE_TEMP_MEDIA_VISIBILITY (optional, default: public)

Facebook

  • SOCIALIZE_FACEBOOK_PAGE_ID (required)
  • SOCIALIZE_FACEBOOK_ACCESS_TOKEN (required)
  • SOCIALIZE_FACEBOOK_GRAPH_VERSION (optional, default: v25.0)
  • SOCIALIZE_FACEBOOK_BASE_URL (optional)

Instagram

  • SOCIALIZE_INSTAGRAM_IG_ID (required)
  • SOCIALIZE_INSTAGRAM_ACCESS_TOKEN (required)
  • SOCIALIZE_INSTAGRAM_GRAPH_VERSION (optional, default: v25.0)
  • SOCIALIZE_INSTAGRAM_BASE_URL (optional)
  • SOCIALIZE_INSTAGRAM_PUBLISH_RETRY_ATTEMPTS (optional, default: 20)
  • SOCIALIZE_INSTAGRAM_PUBLISH_RETRY_SLEEP_SECONDS (optional, default: 3)

X / Twitter

  • SOCIALIZE_TWITTER_BEARER_TOKEN (required for runtime publishing)
  • SOCIALIZE_TWITTER_BASE_URL (optional)
  • SOCIALIZE_TWITTER_MEDIA_PROCESSING_POLL_ATTEMPTS (optional, default: 15)

Token requirements:

  • Use OAuth 2.0 User Context token, not app-only bearer token
  • Required scopes: tweet.read, tweet.write, users.read, media.write
  • Add offline.access when refresh tokens are needed

LinkedIn

  • SOCIALIZE_LINKEDIN_AUTHOR (required, URN format like urn:li:person:...)
  • SOCIALIZE_LINKEDIN_ACCESS_TOKEN (required)
  • SOCIALIZE_LINKEDIN_VERSION (optional, default: 202602, format: YYYYMM)
  • SOCIALIZE_LINKEDIN_BASE_URL (optional)

Local End-to-End Tester

You can test real provider calls without creating a full Laravel app.

  1. Copy .testing.env.example to .testing.env
  2. Fill credentials
  3. Run:
php bin/local-tester.php --help

Examples:

php bin/local-tester.php share --provider=facebook --message="Hello" --link="https://example.com"
php bin/local-tester.php share --provider=facebook --message="Reel caption" --video-title="Reel title" --media-source="/absolute/path/reel.mp4" --media-type=video --reel --published=false
php bin/local-tester.php comment --provider=facebook --post-id="123_456" --comment="Nice post!"
php bin/local-tester.php share-and-comment --provider=linkedin --message="Launch" --link="https://example.com" --comment="Any feedback?"
php bin/local-tester.php share --provider=instagram --video-url="https://cdn.example.com/reel.mp4" --reel
php bin/local-tester.php share --provider=twitter --message="Launch day" --media-source="/absolute/path/image.jpg" --media-type=image
php bin/local-tester.php share --provider=linkedin --message="Professional update" --link="https://example.com" --link-title="Read more"
php bin/local-tester.php delete --provider=linkedin --post-id="urn:li:share:123"

Development Quality Commands

composer analyse
composer test
composer test-coverage
composer format
composer rector
composer verify

License

MIT