Skip to content

DrAliRagab/Socialize

Repository files navigation

Socialize

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:

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

Instagram:

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

X / Twitter:

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

LinkedIn:

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

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:

  • If a provider expects a URL (for example Facebook/Instagram) and you pass a local file, Socialize stores a temporary public file URL, uses it, then cleans it up.
  • 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 image -> temporary URL flow for URL-based providers
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();
    $response = $e->responseBody();
}

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 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 check

License

MIT

About

Socialize your Laravel project easily

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages