EN PT ID

Posts Longos do Bluesky 2026: Guia de Leitura para Criadores

6 de Julho de 2026 · 11 min read · Guide

O Bluesky ativou o formato de posts longos no final de maio de 2026, e o lado da leitura da web social nunca mais foi o mesmo. Durante dois anos, o X Articles foi a única plataforma grande onde era possível publicar uma peça de 5.000 palavras de forma nativa e ainda ter a peça indexada por um mecanismo de busca. Agora o Bluesky igualou essa superfície, e um criador que publica nas duas plataformas está lidando com dois esquemas diferentes, dois gráficos de respostas diferentes e zero ferramentas nativas para unificar o que escreveu.

Este guia é um playbook de leitura para esse mundo. É o fluxo que montamos na equipe do ThreadGrab após o lançamento de maio de 2026, e o mesmo que recomendamos para qualquer criador que agora publica posts longos no Bluesky e no X em paralelo. As quatro etapas abaixo assumem que você já escreve nas duas plataformas. Se não escreve, o playbook ainda funciona como setup de uma plataforma só, mas o roteamento multi-plataforma é onde a economia de tempo realmente se acumula.

Resumo: O Bluesky lançou posts longos em maio de 2026. Um fluxo de leitura tem quatro etapas: detectar posts longos, puxá-los para uma caixa de entrada única, converter para Markdown e cruzar o que você escreveu com o que você respondeu. O plumbing são APIs públicas e um script pequeno, sem vendor lock-in, e o ThreadGrab cuida da conversão para Markdown do lado da leitura para a parte pública do seu arquivo.

O que mudou em maio de 2026

O recurso de posts longos do Bluesky foi liberado para todos os usuários no final de maio de 2026. A mecânica não é a mesma do X Articles -- ela vive em cima do AT Protocol, o que significa que cada post longo ainda é um record em um PDS, mas o tipo de record é app.bsky.feed.post com um novo campo embeds que aponta para uma estrutura app.bsky.embed.recordWithMedia carregando um corpo em Markdown. O cliente oficial do Bluesky renderiza esse corpo em um cartão de scroll longo; clientes de terceiros como Skylight, Graysky e Ozone tratam de forma diferente, e alguns ainda removem a formatação na leitura.

No lado do X, os Articles continuaram sendo o único formato longo nativo pela mesma janela. O padrão de URL do X Articles é estável: https://x.com/<user>/status/<id> com /article/<id> como alternativo. URLs de posts longos do Bluesky seguem o mesmo formato de qualquer outro post: https://bsky.app/profile/<handle>/post/<rkey>, com o corpo dentro de um record.embed em vez de um campo irmão. Se você faz scraping de um mas não do outro, você está perdendo metade de onde o conteúdo longo vive em 2026.

Por que um playbook de leitura importa agora

Publicar posts longos em duas plataformas é fácil. Ler o que você escreveu seis meses depois não é. Cada plataforma tem sua própria UI, sua própria busca e suas próprias regras de retenção de arquivo. O X mantém seus Articles indefinidamente enquanto sua conta estiver ativa; PDSes do Bluesky podem ser migrados, mas uma conta desativada pode te trancar fora dos seus próprios posts longos se você não os exportou.

O playbook abaixo existe por três razões que não são teóricas:

O fluxo de leitura em 4 etapas

O fluxo completo tem quatro etapas, cada uma uma única ferramenta ou script. Nenhuma delas requer conta paga, e tudo roda em menos de 200 linhas de Python se você montar manualmente. A versão hospedada do ThreadGrab colapsa as etapas 2 e 3 em uma chamada, mas a versão manual é a referência canônica.

Etapa 1: detectar posts longos em ambas as plataformas

A primeira etapa é identificação. Você precisa de uma lista de quais dos seus próprios posts (ou quais posts que você segue) são longos. A forma mais limpa de fazer isso é uma consulta periódica do seu próprio feed de autoria, filtrada por comprimento de post e tipo de embed.

# Pseudo-codigo para "o que conta como post longo em cada plataforma"
def is_long_form_bluesky(post):
    embed = post.get("record", {}).get("embed", {})
    return (
        embed.get("$type") == "app.bsky.embed.recordWithMedia"
        and "app.bsky.richtext.facet" in str(embed)
        and len(embed.get("text", "")) > 1500
    )

def is_long_form_x(post):
    text = post.get("text", "") or post.get("note_tweet", {}).get("text", "")
    has_article = "/article/" in post.get("permalink", "")
    return has_article or len(text) > 4000

O limite do Bluesky é de aproximadamente 1.500 grafemas antes do cartão longo ser mostrado; X Articles começam em qualquer comprimento, mas a UI da plataforma é significativamente diferente acima de 4.000 caracteres. A lógica de detecção não precisa ser perfeita; o objetivo é um filtro de primeira passagem que você pode corrigir manualmente.

Etapa 2: puxar o conteúdo longo para uma caixa de entrada unificada

Uma vez que você tem uma lista, puxe os corpos. O Bluesky expoe isso através do endpoint público getPostThread do AppView; o X ainda requer o endpoint GET /2/tweets/:id com bearer token OAuth para Articles maiores que 4.000 caracteres. O script abaixo mostra um pull paralelo para os dois.

import requests, json, pathlib, datetime

OUT = pathlib.Path("./inbox/longform")
OUT.mkdir(parents=True, exist_ok=True)

def pull_bluesky(rkey, handle):
    r = requests.get(
        f"https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread",
        params={"uri": f"at://{handle}/app.bsky.post/{rkey}", "depth": 0},
        timeout=15,
    )
    r.raise_for_status()
    thread = r.json()["thread"]["post"]
    embed = thread["record"].get("embed", {})
    body = embed.get("text", "") or thread["record"].get("text", "")
    return {"platform": "bluesky", "id": rkey, "body": body, "ts": thread["indexedAt"]}

def pull_x(article_id, token):
    r = requests.get(
        f"https://api.x.com/2/tweets/{article_id}",
        params={"tweet.fields": "text,note_tweet,entities,created_at"},
        headers={"Authorization": f"Bearer {token}"},
        timeout=15,
    )
    r.raise_for_status()
    body = r.json()["data"].get("note_tweet", {}).get("text") or r.json()["data"]["text"]
    return {"platform": "x", "id": article_id, "body": body, "ts": r.json()["data"]["created_at"]}

# Exemplo: arquivar dois posts
for path in OUT.glob("*.json"):
    pass
out1 = pull_bluesky("3l5xabc123", "voce.bsky.social")
out2 = pull_x("1800000000000000000", "SEU_X_BEARER_TOKEN")
for entry in (out1, out2):
    stamp = datetime.datetime.fromisoformat(entry["ts"].replace("Z", "+00:00")).strftime("%Y%m%dT%H%M%SZ")
    (OUT / f"{stamp}_{entry['platform']}_{entry['id']}.json").write_text(json.dumps(entry, indent=2))

A saída é um arquivo JSON por post longo em um único diretório ./inbox/longform/. O nome do arquivo é ordenável por data, então o diretório já é um arquivo ordenado cronologicamente sem qualquer banco de dados.

Etapa 3: converter para Markdown para releitura e busca

Os blobs JSON não são o que você quer ler às 2 da manhã seis meses depois. Converta cada um para um arquivo Markdown com frontmatter, e você tem um arquivo grep-friendly, editor-friendly, versionável. A versão hospedada do ThreadGrab faz isso para a leitura pública; o script abaixo é o que usamos internamente para o arquivo privado do lado do autor.

def json_to_markdown(entry):
    fm = [
        "---",
        f"platform: {entry['platform']}",
        f"id: {entry['id']}",
        f"published: {entry['ts']}",
        f"url: " + (
            f"https://bsky.app/profile/voce.bsky.social/post/{entry['id']}"
            if entry["platform"] == "bluesky"
            else f"https://x.com/voce/status/{entry['id']}"
        ),
        "---",
    ]
    body_md = entry["body"]
    if entry["platform"] == "bluesky":
        body_md = body_md.replace("

", "

")
    return "
".join(fm) + "

" + body_md + "
"

import json, pathlib
for src in pathlib.Path("./inbox/longform").glob("*.json"):
    entry = json.loads(src.read_text())
    (pathlib.Path("./archive") / src.with_suffix(".md").name).write_text(json_to_markdown(entry))

Após rodar, você tem um diretório de arquivos .md que pode ler em qualquer editor, buscar com ripgrep, commitar no Git, ou alimentar de volta para um LLM futuro como material de corpus. O frontmatter mantém a tag de plataforma e a URL canônica para que você sempre possa voltar para a versão ao vivo.

Etapa 4: cruzar seus próprios posts com respostas

A etapa final é a que a maioria dos criadores pula: um gráfico de conversa unificado. Para cada post longo que você escreveu, você quer ver todas as respostas em ambas as plataformas em um só lugar. Isso não está embutido em nenhuma das UIs; é um script.

def replies_for(post):
    if post["platform"] == "bluesky":
        r = requests.get(
            "https://public.api.bsky.app/xrpc/app.bsky.feed.getReplies",
            params={"uri": post["embed_uri"], "limit": 100},
            timeout=15,
        )
        return [r["post"]["record"]["text"] for r in r.json().get("replies", [])]
    if post["platform"] == "x":
        r = requests.get(
            f"https://api.x.com/2/tweets/search/recent",
            params={"query": f"conversation_id:{post['id']}", "tweet.fields": "text,author_id"},
            headers={"Authorization": f"Bearer {post['token']}"},
            timeout=15,
        )
        return [t["text"] for t in r.json().get("data", [])]
    return []

A saída é um único arquivo de texto por post longo: 20260701T090000Z_x_1800000000000000000.md com uma seção ## Replies listando cada resposta de ambas as plataformas. Se você publicou uma peça em maio de 2026 e quer saber o que os leitores disseram sobre ela em julho, você abre um arquivo, não duas abas do navegador.

Como o ThreadGrab se encaixa

O serviço hospedado do ThreadGrab faz as etapas 2, 3 e 4 para qualquer post longo público no Bluesky ou X. Se você tem uma URL longa, o ThreadGrab retorna o corpo Markdown com frontmatter, a URL canônica da plataforma e o gráfico de respostas. O serviço hospedado é grátis para posts públicos, não requer token do X, e não escreve no seu PDS.

Para arquivos privados de autoria (seus próprios posts, antes de serem públicos), você ainda precisa do script acima. O serviço hospedado complementa, não substitui, o arquivo local. A divisão é intencional: o lado da leitura pública é o que o ThreadGrab faz de melhor, e o lado do autor privado é o que você faz de melhor porque só você sabe quais rascunhos quer manter.

Três coisas específicas que o ThreadGrab faz e que o script acima não faz:

Aponte o ThreadGrab para qualquer URL de post longo do Bluesky ou X. Você recebe o corpo Markdown, o link canônico da plataforma e o gráfico de respostas em uma única chamada. Sem token do X, sem PDS, sem instalação.

Experimente o ThreadGrab grátis

Quando não construir um playbook de leitura

Nem todo criador precisa disso. Se você publica posts longos em exatamente uma plataforma e lê seus próprios posts na UI nativa, o playbook é exagero. O fluxo de quatro etapas compensa quando pelo menos duas dessas condições são verdadeiras:

Se apenas uma dessas condições se aplica, o setup mais simples é o ThreadGrab público para os posts públicos e um único vault do Obsidian para os rascunhos privados. Se duas ou mais se aplicam, o script de quatro etapas acima vale o fim de semana que leva para montar.

Perguntas frequentes

Quando exatamente o Bluesky lançou os posts longos?

O Bluesky enviou o formato de posts longos para todos os usuários no final de maio de 2026. O recurso está disponível no cliente oficial do Bluesky, Skylight, Graysky e Ozone. Alguns clientes de terceiros ainda não renderizam o cartão longo corretamente; se você lê o Bluesky em um desses clientes, o post aparecerá truncado.

Preciso de uma conta paga do X ou Bluesky para usar este fluxo?

Não. Os endpoints públicos do AppView do Bluesky são abertos e não requerem autenticação para acesso somente leitura. O endpoint GET /2/tweets/:id do X requer uma conta de desenvolvedor gratuita com um bearer token, mas você não precisa de X Premium nem do tier pago da API do X para acesso somente leitura aos seus próprios Articles.

Posso usar isso para arquivar posts longos de outras pessoas?

Sim para os públicos. O endpoint público do ThreadGrab aceita qualquer URL longa do Bluesky ou X. Para posts privados ou rascunhos que você não possui, o script acima não funciona -- as plataformas expõem apenas os endpoints do lado do autor para o autor.

O playbook funciona para Threads ou LinkedIn Newsletter?

Não diretamente. O Threads não tem um recurso longo nativo em 2026; Threads posts longos colapsam em uma única thread. LinkedIn Newsletters tem um feed RSS público que você pode assinar, mas o corpo do artigo não é busca-vel através de uma API pública do mesmo jeito que Bluesky e X expõem. Se você publica em qualquer um, adicione uma quinta etapa para puxar o feed RSS e convertê-lo.

E se meu PDS do Bluesky migrar ou minha conta for desativada?

É exatamente por isso que o playbook existe. O arquivo Markdown é seu backup portátil. Se seu PDS migrar, a URL canônica no novo PDS ainda aponta para o mesmo rkey, e a cópia do arquivo é independente. Se sua conta for desativada, o cache público do ThreadGrab ainda pode manter o post por algum tempo, mas o arquivo Markdown é a garantia de longo prazo.