Command Palette

Search for a command to run...

Proxy de imagens

Use o proxy de imagens do Nowly quando o Discord não conseguir carregar uma imagem de presença diretamente de um CDN externo compatível.

Para que serve

O proxy de imagens foi criado para uma situação específica: uma presença consegue ver uma imagem pública na página, mas o Discord não consegue carregá-la de forma confiável a partir da URL original.

Ele é útil para miniaturas de vídeo, avatares, pôsteres ou imagens de categorias servidas por um CDN externo quando:

  • a imagem é pública e já está visível no navegador;
  • a URL do CDN é longa demais para o Discord Rich Presence;
  • o Discord rejeita a imagem direta, a URL expira ou o download falha;
  • a presença precisa mostrar uma imagem do conteúdo em vez de apenas o logotipo do serviço.

Este não é um proxy de imagens de uso geral. A API aceita somente serviços e domínios explicitamente permitidos.

Como funciona

O fluxo recomendado usa uma URL curta temporária:

TXT
POST https://api.nowly.me/images-proxy
GET  https://api.nowly.me/images-proxy/<id>

A presença envia à API a URL real da imagem no CDN. A API verifica se o serviço é compatível, baixa a imagem, valida seu tipo MIME e tamanho e a armazena temporariamente em cache. Em seguida, retorna uma URL curta, como:

TXT
https://api.nowly.me/images-proxy/abc123...

Essa URL retorna diretamente os bytes da imagem com o Content-Type correto. Ela foi feita para largeImageKey ou smallImageKey.

import { createCachedImageProxyUrl } from "@nowly/sdk"

const image = await createCachedImageProxyUrl("tiktok", imageUrl)

await presence.setActivity({
  details: "Watching a video",
  largeImageKey: image ?? Assets.Logo,
})

O cache é temporário, atualmente de cinco minutos. O helper também mantém um cache na memória da presença para não chamar a API em toda atualização.

Endpoint direto

O proxy direto antigo continua disponível para testes manuais ou URLs que já são curtas o suficiente:

TXT
https://api.nowly.me/image-proxy?service=<service>&url=<encoded-url>
https://api.nowly.me/i?u=<encoded-url>

Os parâmetros url e u precisam ser codificados com encodeURIComponent. Para o Discord Rich Presence, prefira createCachedImageProxyUrl, pois o Discord limita as chaves de imagem a 300 caracteres.

Configuração em uma presença

Primeiro, obtenha a URL real da imagem na página:

const getPoster = (video: HTMLVideoElement): string | undefined => {
  if (video.poster) return video.poster

  const image = video.closest("[data-video]")?.querySelector("img")
  return image?.getAttribute("src") ?? undefined
}

Depois, passe a URL ao helper antes de definir a atividade:

import { createCachedImageProxyUrl } from "@nowly/sdk"

const poster = await createCachedImageProxyUrl("tiktok", getPoster(video))

await presence.setActivity({
  details: "Watching a video",
  largeImageKey: poster ?? Assets.Logo,
})

Mantenha sempre uma imagem alternativa. Se a página não tiver imagem, ela for grande demais ou a origem não for permitida, a presença deve continuar funcionando com Assets.Logo ou um recurso local.

Adicionar um serviço

Os domínios permitidos são verificados pela API, não pela presença. Uma presença não pode usar o proxy para um domínio arbitrário apenas solicitando isso em tempo de execução. Não há uma etapa de aprovação separada nem alteração no código da API: declare os hosts necessários diretamente no metadata.json da própria presença. Use o mesmo valor de service (o slug da presença) que você já passa ao helper:

"imageProxy": {
  "hostSuffixes": ["netflix.com", "nflxvideo.net", "nflximg.net"],
  "headers": { "Referer": "https://www.netflix.com/" }
}

Isso é publicado na API automaticamente com o restante do metadata.json. A API só confia nessa declaração para o ID service da própria presença. Uma presença não pode declarar hosts em nome de outra, e a solicitação só é permitida se o nome do host da URL de destino corresponder de fato a um dos sufixos declarados.

Quando seu PR altera imageProxy, o bot de prévia de presenças detecta isso automaticamente, adiciona uma seção Image Proxy Requested ao comentário com os hosts declarados e aplica a etiqueta image-proxy. Antes da integração, uma pessoa responsável pela revisão ainda precisa confirmar se os hosts são públicos e seguros para o proxy. Explique no PR por que o Discord não pode usar a URL direta e qual imagem o usuário verá.

Limites e segurança

O proxy fornece apenas imagens públicas de hosts declarados por uma presença revisada. Ele rejeita URLs que não sejam HTTPS, hosts que não correspondam aos sufixos declarados, respostas que não sejam imagens e arquivos grandes demais.

Os endpoints são públicos e não exigem autenticação (as presenças os chamam diretamente do navegador, portanto não há segredo para anexar). Eles compartilham o limite global de requisições da API; não há cota por presença. Não use o proxy para conteúdo de contas privadas, recursos autenticados, URLs de rastreamento, entradas arbitrárias de usuários ou conteúdo que não seja imagem.