Autenticación
La autenticación en Bluesky admite dos métodos: App Password y OAuth. En nuevas implementaciones, considera también adoptar OAuth.
App Password
use Revolution\Bluesky\Facades\Bluesky;
$profile = Bluesky::login(
identifier: config('bluesky.identifier'),
password: config('bluesky.password'),
)->getProfile();
Si vas a reutilizar la sesión, usa LegacySession.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;
Bluesky::login(identifier: config('bluesky.identifier'), password: config('bluesky.password'));
cache()->put('bluesky_legacy_session', Bluesky::agent()->session()->toArray(), now()->addDay());
Bluesky::withToken(LegacySession::create(cache('bluesky_legacy_session', [])));
if (! Bluesky::check()) {
Bluesky::refreshSession();
}
OAuth
El token obtenido con Socialite se convierte en OAuthSession para usarlo.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;
$session = OAuthSession::create(session('bluesky_session'));
$timeline = Bluesky::withToken($session)->getTimeline();
El flujo OAuth completo se explica en Socialite.
Crear una publicación
Publicación de texto simple
use Revolution\Bluesky\Facades\Bluesky;
$response = Bluesky::withToken()->post('test');
Construir la publicación con TextBuilder
Para manejar correctamente enlaces, etiquetas y menciones, usa TextBuilder.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\RichText\TextBuilder;
$post = TextBuilder::make(text: 'test')
->newLine()
->mention('@example.bsky.social')
->newLine()
->link('https://bsky.app/')
->newLine()
->tag('#Laravel')
->toPost();
$response = Bluesky::withToken()->post($post);
Adjuntar imágenes
use Illuminate\Support\Facades\Storage;
use Revolution\Bluesky\Embed\Images;
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Record\Post;
Bluesky::withToken();
$images = Images::create()->add(
alt: 'App screenshot',
blob: fn (): array => Bluesky::uploadBlob(
Storage::get('test.png'),
Storage::mimeType('test.png')
)->json('blob')
);
$post = Post::create(text: 'image post')->embed($images);
$response = Bluesky::post($post);
Tarjeta de enlace externo
use Revolution\Bluesky\Embed\External;
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Record\Post;
$external = External::create(
title: 'Title',
description: 'Description',
uri: 'https://example.com'
);
$post = Post::create(text: 'external card')->embed($external);
$response = Bluesky::withToken()->post($post);
Respuestas y citas
Respuesta
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Record\Post;
use Revolution\Bluesky\Types\ReplyRef;
use Revolution\Bluesky\Types\StrongRef;
$reply = ReplyRef::to(
root: StrongRef::to(uri: 'at://', cid: 'cid'),
parent: StrongRef::to(uri: 'at://', cid: 'cid')
);
$post = Post::create(text: 'reply')->reply($reply);
$response = Bluesky::withToken()->post($post);
Publicación con cita
use Revolution\Bluesky\Embed\QuoteRecord;
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Record\Post;
use Revolution\Bluesky\Types\StrongRef;
$quote = QuoteRecord::create(StrongRef::to(uri: 'at://', cid: 'cid'));
$post = Post::create(text: 'quote')->embed($quote);
$response = Bluesky::withToken()->post($post);
Obtener el feed
use Revolution\Bluesky\Facades\Bluesky;
$response = Bluesky::withToken()->getTimeline();
$items = $response->collect('feed');
Si solo necesitas obtener publicaciones públicas, puedes usar métodos que no requieren autenticación.
use Revolution\Bluesky\Facades\Bluesky;
$feed = Bluesky::getAuthorFeed(actor: 'alice.bsky.social')->json('feed');
Búsqueda
use Revolution\Bluesky\Facades\Bluesky;
$response = Bluesky::withToken()->searchPosts(q: '#bluesky', limit: 10);
searchPosts() no está disponible actualmente sin autenticación debido a una restricción temporal del lado de la API.