⚡ AutomationsAI|Portal de Cursos →

Verificando acesso...

MÓDULO 3.2

🐘 Mastodon

Publique no Fediverso em 30 minutos: escolha de instância, criação de app, token de autenticação, post de status, upload de mídia e controle de visibilidade.

6
Tópicos
30
Minutos
Básico
Nível
Prático
Tipo
1

🌍 Escolher a instância

Mastodon não é um site único — é uma rede federada. Cada servidor (instância) tem suas próprias regras, comunidade e moderação, mas todos conversam entre si via ActivityPub. Seu identificador será @usuario@instancia.tld, como um e-mail.

A escolha da instância importa: ela define seu domínio público, suas regras de moderação e a estabilidade do seu acesso. Para começar, fique numa instância pública grande e bem-administrada — depois pode migrar (o Mastodon suporta export/import de quem você segue).

# Instâncias públicas populares e estáveis
mastodon.social   # oficial, mantida pela equipe Mastodon gGmbH
fosstodon.org     # foco em software livre e tech
mas.to            # generalista, registro aberto
hachyderm.io      # tech/SRE/devops, moderação rígida
techhub.social    # tech/dev, instância PT-BR amigável

# Inspecionar metadados de uma instância antes de entrar
curl https://mastodon.social/api/v2/instance | jq '.title, .description, .languages'

💡 Dica prática

Se você quer controle total e custo zero a longo prazo, considere self-host com docker-compose. Mas comece numa instância pública — operar Mastodon em produção exige Redis, Postgres, ElasticSearch e cuidado com moderação federada.

Conceitos-chave

Fediverso

Rede de servidores que falam ActivityPub entre si.

Instância

Servidor Mastodon com regras e comunidade próprias.

Handle

Formato @user@host identifica globalmente.

Migração

Você leva seguidores e listas ao mudar de instância.

2

⚙️ Criar app em /settings/applications

O Mastodon expõe uma API REST direta e — diferente do Twitter/X — você cria seu próprio app pela UI, sem fila de aprovação. Vá em Settings → Development → New application, dê um nome, marque os scopes que precisa e salve.

Para um bot/integração que só posta, o scope mínimo é write:statuses (e write:media se for anexar imagens). Evite marcar read ou admin se não precisar — princípio do menor privilégio.

# Alternativa via API (sem UI) — registra app programaticamente
curl -X POST https://mastodon.social/api/v1/apps \
  -F 'client_name=meu-bot' \
  -F 'redirect_uris=urn:ietf:wg:oauth:2.0:oob' \
  -F 'scopes=write:statuses write:media' \
  -F 'website=https://exemplo.com'

# Resposta JSON
# {
#   "id": "1234567",
#   "name": "meu-bot",
#   "client_id":  "AbCdEf...",
#   "client_secret": "XyZ123..."
# }

🔒 Dica prática

Escopos do Mastodon são hierárquicos: write implica write:statuses, write:media, etc. Sempre prefira o mais granular possível — se vazar o token, o estrago é menor.

Conceitos-chave

Application

Identidade do cliente que fala com a API.

Scopes

Permissões: read, write, follow, push.

redirect_uri

oob = out-of-band, sem callback web.

Menor privilégio

Marque só os scopes que o app realmente usa.

3

🔑 Token de app e Bearer auth

Após criar o app, o Mastodon gera um access token pessoal logo abaixo do client_id/client_secret. Esse token autentica como você dentro dos scopes marcados — basta copiar e usar como Authorization: Bearer ....

Para OAuth completo (terceiros logando no seu app) o fluxo é diferente, mas para um bot pessoal esse token estático resolve. Guarde-o em variável de ambiente — nunca em código versionado.

# Exportar token e instância como env vars
export MASTODON_HOST="https://mastodon.social"
export MASTODON_TOKEN="abc123def456...seu_token_aqui"

# Validar token — retorna seu perfil
curl -H "Authorization: Bearer $MASTODON_TOKEN" \
  "$MASTODON_HOST/api/v1/accounts/verify_credentials"

# Resposta JSON
# {
#   "id": "108123",
#   "username": "neimaldaner",
#   "acct": "neimaldaner",
#   "display_name": "Nei",
#   ...
# }

✓ O que FAZER

  • Guardar token em .env fora do git.
  • Testar com verify_credentials antes de publicar.
  • Revogar e recriar o app se o token vazar.
  • Usar um token por integração — facilita auditoria.

✗ O que NÃO fazer

  • Colar o token num gist público para "debugar rápido".
  • Reaproveitar o mesmo token em N bots diferentes.
  • Mandar o token como ?access_token= na URL (vai pro log).
  • Dar scope admin:* para um bot que só posta.

Conceitos-chave

Access token

Credencial estática emitida pelo Mastodon.

Bearer auth

Header Authorization: Bearer <token>.

verify_credentials

Endpoint canônico para validar token.

Revogação

Apagar o app na UI invalida o token na hora.

4

📝 POST /api/v1/statuses

O endpoint para publicar um toot (status) é POST /api/v1/statuses. O único campo obrigatório é status (texto, até 500 caracteres na maioria das instâncias). Os demais são opcionais: visibility, sensitive, spoiler_text, language, scheduled_at.

# Post simples
curl -X POST "$MASTODON_HOST/api/v1/statuses" \
  -H "Authorization: Bearer $MASTODON_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "Olá Fediverso! 🐘 Postando via API.",
    "visibility": "public",
    "language": "pt"
  }'

# Resposta — status criado
# {
#   "id": "111234567890123456",
#   "created_at": "2026-05-24T14:30:00.000Z",
#   "url": "https://mastodon.social/@user/111234567890123456",
#   "content": "<p>Olá Fediverso! 🐘 ...</p>",
#   "visibility": "public",
#   ...
# }

Para evitar duplicatas em retentativas, envie o header Idempotency-Key com um UUID. Se a mesma key chegar duas vezes em poucos minutos, o Mastodon retorna o status já criado em vez de duplicar.

# Post com idempotência (seguro para retry)
curl -X POST "$MASTODON_HOST/api/v1/statuses" \
  -H "Authorization: Bearer $MASTODON_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"status":"Mesma chave = mesmo post","visibility":"unlisted"}'

Dica prática

Mastodon aceita scheduled_at em ISO-8601 para agendar nativamente (mínimo 5 minutos no futuro). Útil se você não tem orquestrador próprio — mas o Postiz já cuida disso e te dá controle melhor.

Conceitos-chave

status

Texto do toot — limite varia por instância.

language

ISO 639-1 (ex: pt) ajuda timeline locais.

Idempotency-Key

UUID que previne duplicação em retry.

scheduled_at

Agendamento nativo (mín. 5 min no futuro).

5

🖼️ Upload de mídia em /api/v2/media

Anexar imagem/vídeo é um processo de dois passos: primeiro faz upload no endpoint de mídia (retorna um id), depois inclui esse id no array media_ids[] ao criar o status. A v2 é assíncrona — aceita o arquivo e retorna 202 enquanto processa.

1

Upload do arquivo (multipart)

Sempre inclua description — é o alt-text de acessibilidade, obrigatório por convenção da comunidade.

curl -X POST "$MASTODON_HOST/api/v2/media" \
  -H "Authorization: Bearer $MASTODON_TOKEN" \
  -F "file=@foto.jpg" \
  -F "description=Pôr do sol em Florianópolis com nuvens rosadas"

# Retorna o id (processamento assíncrono)
# { "id": "22348675309", "type": "image", "url": null, ... }
2

Anexar ao status

Use o id retornado em media_ids[]. Mastodon suporta até 4 imagens ou 1 vídeo por toot.

curl -X POST "$MASTODON_HOST/api/v1/statuses" \
  -H "Authorization: Bearer $MASTODON_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "Foto de hoje 🌅",
    "media_ids": ["22348675309"],
    "visibility": "public"
  }'

Dica prática

A cultura do Mastodon valoriza muito alt-text. Postar mídia sem description gera reações negativas e reduz alcance — bots de "CaptionBot" cobram publicamente. Sempre descreva.

Conceitos-chave

multipart/form-data

Encoding para enviar binários via HTTP.

v2 async

Processamento em background — pollar /media/:id.

alt-text

Campo description = acessibilidade.

Limites

4 imagens OU 1 vídeo/GIF por status.

6

👁️ Visibility e content warnings

Mastodon tem quatro níveis de visibilidade por post — escolhidos individualmente, não como configuração da conta. Combine com sensitive: true + spoiler_text para Content Warnings (CW), uma convenção forte na cultura local.

📊 Os quatro níveis de visibility

  • public: aparece em timelines federadas, locais e públicas. Indexável. Use para conteúdo que quer alcance máximo.
  • unlisted: visível para quem te segue e para quem abre o link, mas não aparece nas timelines públicas. Bom para threads longas.
  • private (followers-only): só seus seguidores veem. Não pode ser boostado por terceiros.
  • direct: mensagem direta — só vê quem você mencionar com @. Não é criptografada; use com cuidado.
# Toot com Content Warning + visibility unlisted
curl -X POST "$MASTODON_HOST/api/v1/statuses" \
  -H "Authorization: Bearer $MASTODON_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "Spoiler do último episódio: o personagem X morre no final.",
    "spoiler_text": "Spoiler S03E10",
    "sensitive": true,
    "visibility": "unlisted",
    "language": "pt"
  }'

# DM para um usuário específico
curl -X POST "$MASTODON_HOST/api/v1/statuses" \
  -H "Authorization: Bearer $MASTODON_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "@fulano@outra.instancia oi, te mando o link em DM",
    "visibility": "direct"
  }'

✓ O que FAZER

  • Usar CW para política, spoilers, conteúdo pesado, NSFW.
  • spoiler_text curto e descritivo, não clickbait.
  • Marcar language — ajuda na descoberta.
  • Respeitar o tom: Mastodon não é Twitter ragebait.

✗ O que NÃO fazer

  • Tratar direct como mensagem segura — não é E2E.
  • Postar tudo como public sem CW.
  • Bot postando em public a cada 30 segundos.
  • Usar spoiler_text como título caça-clique.

Conceitos-chave

visibility

Por post, não por conta — escolha consciente.

Content Warning

Aviso colapsável que o leitor escolhe expandir.

sensitive

Esconde mídia atrás de blur até clicar.

Etiqueta

Cultura local: CW + alt-text não são opcionais.

🎯 Resumo do Módulo

Instância escolhida — entendeu o Fediverso, identificou opções estáveis e o formato @user@host.
App criado — em /settings/applications com scopes write:statuses e write:media.
Token autenticado — Bearer auth validado via verify_credentials, secret fora do git.
Primeiro toot publicadoPOST /api/v1/statuses com idempotência e language tag.
Mídia anexada — fluxo de dois passos via /api/v2/media com alt-text obrigatório.
Visibility dominada — public/unlisted/private/direct + Content Warning conforme cultura local.

Próximo Módulo:

3.3 — Bluesky e o protocolo AT