iToverDose/Yazılım· 27 MAYIS 2026 · 16:06

Açık Kaynaklı Bir Sosyal Medya Planlayıcıyı Laravel ile Nasıl Geliştirdim?

Düzenli içerik paylaşımı için birden fazla sosyal ağda çalışan, kendi sunucunuzda barındırılan bir araç mı arıyorsunuz? Laravel kullanarak nasıl kendi açık kaynaklı planlayıcınızı geliştirebileceğinizi keşfedin.

DEV Community4 dk okuma0 Yorumlar

Sosyal medya hesaplarınız için haftalık içerik planlaması yapmak istediğinizde, çoğu araç sizden erişim token'larınızı, taslaklarınızı ve analizlerinizi kendi sunucularında barındırmanızı talep eder. Peki ya tüm bu verileri kendi sunucunuzda, tamamen ücretsiz ve bağımsız bir şekilde yönetmek isterseniz?

İşte tam da bu ihtiyaçtan yola çıkarak geliştirdiğim TryPost, Buffer, Hootsuite ve Later gibi popüler planlayıcıların aksine verilerinizi kendi sunucunuzda barındırmanıza olanak tanıyan açık kaynaklı bir çözüm. AGPL lisansı altında yayınlanan bu araç, X, LinkedIn, Facebook, Instagram, TikTok, YouTube, Pinterest, Threads, Bluesky ve Mastodon gibi 10 farklı platformda otomatik içerik yayınlama desteğine sahip. Üstelik Laravel 13, Vue 3 ve Inertia.js gibi yaygın teknolojilerle inşa edildiği için mevcut projelerinize kolayca entegre edilebiliyor.

Peki bu sistem nasıl çalışıyor? Platformlar arası entegrasyon, OAuth işlemleri, token yenileme mekanizmaları ve çoklu kullanıcı desteği gibi teknik detayların yanı sıra, yapay zeka araçlarından (Claude veya Cursor) nasıl faydalanabileceğinizi de bu rehberde bulacaksınız.

Tek Bir Composer, On Platform: Entegrasyonların Yönetimi

Sosyal medya planlayıcı geliştirmenin en karmaşık kısmı, her platformun farklı API yapısına, içerik sınırlamalarına ve hatta "gönderi" kavramına sahip olmasıdır. Örneğin:

  • X (eski Twitter) 280 karakter sınırına sahipken, LinkedIn 3.000 karaktere izin verir.
  • Instagram görsel olmadan gönderi yayınlamanıza izin vermez.
  • Threads ve Bluesky ise kendi protokollerini kullanır.

Bu çeşitlilik, uygulamanın geri kalanına yayılmadan tek bir yerde yönetilmelidir. Bunun için kullanılan yaklaşım, her platformun özelliklerini ve sınırlamalarını özetleyen bir enum tanımıdır:

enum Platform: string
{
    case X = 'x';
    case LinkedIn = 'linkedin';
    case Instagram = 'instagram';
    case Threads = 'threads';
    case Bluesky = 'bluesky';
    // Diğer platformlar...

    public function maxContentLength(): int
    {
        return match ($this) {
            self::X => 280,
            self::LinkedIn => 3000,
            // Diğer platformlar için sınırlar...
        };
    }

    public function queue(): string
    {
        return "social-{$this->value}";
    }
}

Her platform için ayrı bir Publisher sınıfı oluşturulur ve yayınlama anında doğru sınıfın seçilmesi için basit bir hizmet yerleştirici (service locator) kullanılır:

private function publisher(): SocialPublisher
{
    return match ($this->postPlatform->platform) {
        Platform::X => app(XPublisher::class),
        Platform::LinkedIn => app(LinkedInPublisher::class),
        Platform::Instagram => app(InstagramPublisher::class),
        // Diğer platformlar için eşleştirmeler...
    };
}

Bu yapı sayesinde yeni bir platform eklemek oldukça basit hale gelir: enum dosyasına yeni bir platform ekleyin, ilgili Publisher sınıfını yazın ve hizmet yerleştirici listesine kaydedin. Uygulamanın geri kalanında (takvim, içerik oluşturucu, planlayıcı) hiçbir değişiklik yapmanıza gerek kalmaz.

OAuth ve Token Yenileme: Kritik Bir Detay

Sosyal medya hesaplarını bağlarken OAuth protokolü kullanılır. Laravel'in Socialite paketi bu süreci kolaylaştırırken, Instagram gibi bazı platformlar için özel sağlayıcılar da geliştirilmiştir. Ancak en kritik nokta, erişim token'larının güvenli bir şekilde saklanmasıdır. Laravel'in encrypted cast özelliği, token'ları veritabanında şifrelenmiş olarak saklamanıza olanak tanır:

protected function casts(): array
{
    return [
        'access_token' => 'encrypted',
        'refresh_token' => 'encrypted',
        'token_expires_at' => 'datetime',
        'scopes' => 'array',
    ];
}

Token yenileme işlemi sırasında karşılaşılan en önemli sorunlardan biri, yenileme yarış koşullarıdır. Bazı platformlar her token kullanımında yenileme token'ını değiştirir. Örneğin, beş farklı gönderi aynı dakika içinde yayınlanmaya çalışırsa ve beş farklı iş parçacığı token'ın süresinin dolduğunu tespit edip yenilemeye çalışırsa, ilk yenileme gerçekleştiren iş parçacığı dışındakiler "geçersiz token" hatası alır. Bu da sağlıklı bir hesabın aniden bağlantısının kesilmesine neden olabilir.

Bu sorunu çözmek için iki temel kural uygulanmıştır:

  1. Token yenilemeden önce gönderiyi dene: İlk olarak gönderiyi yayınlamaya çalış, yalnızca 401 hatası aldığında token yenilemeye geç.
public function publishWithFreshToken(PostPlatform $postPlatform): array
{
    try {
        return $this->publisher()->publish($postPlatform);
    } catch (TokenExpiredException) {
        $this->refreshToken($postPlatform->socialAccount);
        return $this->publisher()->publish($postPlatform);
    }
}
  1. Token yenileme sırasında kilitleme kullan: Token yenileme işlemini bir önbellek kilidi altında gerçekleştirerek, yalnızca bir iş parçacığının token'ı yenilemesine izin ver.
public function refreshToken(SocialAccount $account): void
{
    $lock = Cache::lock("token-refresh:{$account->id}", 30);
    if (!$lock->get()) {
        $account->refresh(); // Başka bir iş parçacığı token'ı yeniliyor
        return;
    }
    try {
        match ($account->platform) {
            Platform::LinkedIn => $this->refreshLinkedIn($account),
            Platform::X => $this->refreshX($account),
            // Diğer platformlar...
        };
    } finally {
        $lock->release();
    }
}

Planlama Mekanizması: Güvenilir ve Ölçeklenebilir

Planlama süreci, basit bir komutun her dakika çalıştırılmasıyla başlar. Bu komut, yayınlanması gereken gönderileri bulur ve her biri için ayrı bir görev (job) oluşturur.

// routes/console.php
Schedule::command(ProcessScheduledPosts::class)
    ->everyMinute()
    ->withoutOverlapping()
    ->onOneServer();

Ancak kritik olan nokta, aynı gönderinin birden fazla kez yayınlanmasını önlemektir. Bu, atomik bir durum değişikliği ile sağlanır: Koşullu bir UPDATE işlemi hem bir kilitleme görevi görür hem de gönderinin durumunu Publishing olarak günceller.

public function handle(): void
{
    Post::query()->due()->each(function (Post $post) {
        $claimed = Post::whereKey($post->id)
            ->where('status', Status::Scheduled)
            ->update(['status' => Status::Publishing]);

        if ($claimed === 1) {
            PublishPost::dispatch($post);
        }
    });
}

Bu sayede yalnızca durumunu Scheduleddan Publishinga güncelleyen iş parçacığı yayın görevini gönderir. Diğerleri ise hiçbir değişiklik yapılmadığını görür ve işlemlerine devam eder. Bu yaklaşımda herhangi bir dağıtık kilit mekanizmasına veya ek altyapıya ihtiyaç duyulmaz.

Görevler daha sonra Laravel Horizon tarafından yönetilir ve ölçeklenebilir bir şekilde çalıştırılır. Tüm bu süreç, uygulamaya yeni platformlar eklemekten token yönetimine kadar oldukça sağlam bir temel oluşturur.

Verilerinizi kendi sunucunuzda barındırmak ve bağımsız bir planlayıcıya sahip olmak, içerik stratejinizi daha güvenilir ve kontrol edilebilir hale getirebilir. TryPost gibi açık kaynaklı projeler, sadece başlangıç noktasıdır. Gelecekte yapay zeka entegrasyonlarının ve daha geniş platform desteğinin de bu alanda önemli gelişmelere yol açması bekleniyor. Kendi benzersiz ihtiyaçlarınıza uygun bir çözüm geliştirmek için Laravel ve diğer modern araçlardan ilham alabilirsiniz.

Yapay zeka özeti

Buffer ve Hootsuite alternatifi olan açık kaynaklı bir sosyal medya planlayıcıyı Laravel ile nasıl geliştirebileceğinizi öğrenin. OAuth, token yönetimi ve platform entegrasyonları hakkında detaylı rehber.

Yorumlar

00
YORUM BIRAK
ID #RAJSGQ

0 / 1200 KARAKTER

İnsan doğrulaması

4 + 7 = ?

Editör onayı sonrası yayına girer

Moderasyon · Spam koruması aktif

Henüz onaylı yorum yok. İlk yorumu sen bırak.