Proxy d'image
Utilisez le proxy d'image Nowly lorsque Discord ne peut pas charger directement une image de présence depuis un CDN externe pris en charge.
À quoi ça sert
Le proxy d'image est prévu pour un cas précis : une présence peut voir une image publique dans la page, mais Discord ne parvient pas à la charger correctement depuis l'URL d'origine.
C'est typiquement utile pour des miniatures de vidéos, des avatars, des posters ou des images de catégorie servies par un CDN externe lorsque :
- l'image est publique et déjà visible dans le navigateur ;
- l'URL CDN est trop longue pour Discord Rich Presence ;
- Discord refuse, laisse expirer ou ne télécharge pas correctement l'image directe ;
- la présence doit afficher une image liée au contenu plutôt que seulement le logo du service.
Ce n'est pas un proxy d'image générique. L'API accepte uniquement les services et les domaines explicitement autorisés.
Fonctionnement
Le flux recommandé passe par une URL courte temporaire :
TXTPOST https://api.nowly.me/images-proxy
GET https://api.nowly.me/images-proxy/<id>La présence envoie à l'API l'URL CDN réelle de l'image. L'API vérifie que le service est pris en charge, télécharge l'image, valide son type MIME et sa taille, puis la stocke temporairement en cache. Elle renvoie ensuite une URL courte du type :
TXThttps://api.nowly.me/images-proxy/abc123...Cette URL renvoie directement les octets de l'image avec le bon Content-Type. Elle est conçue pour 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,
})Le cache est court, actuellement cinq minutes. Le helper garde aussi un cache mémoire côté présence pour éviter de rappeler l'API à chaque mise à jour.
Endpoint direct
L'ancien proxy direct reste disponible pour les tests manuels ou les URL déjà assez courtes :
TXThttps://api.nowly.me/image-proxy?service=<service>&url=<url-encodée>
https://api.nowly.me/i?u=<url-encodée>Les paramètres url et u doivent être encodés avec encodeURIComponent. Pour Discord Rich Presence, préférez createCachedImageProxyUrl, car Discord limite les clés d'image à 300 caractères.
Mise en place dans une présence
Récupérez d'abord l'URL réelle de l'image depuis la page :
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
}Envoyez ensuite cette URL au helper avant de définir l'activité :
import { createCachedImageProxyUrl } from "@nowly/sdk"
const poster = await createCachedImageProxyUrl("tiktok", getPoster(video))
await presence.setActivity({
details: "Watching a video",
largeImageKey: poster ?? Assets.Logo,
})Gardez toujours un visuel de secours. Si la page ne fournit aucune image, si l'image est trop lourde ou si l'origine n'est pas autorisée, la présence doit continuer à fonctionner avec Assets.Logo ou un fichier local.
Ajouter un service
Les domaines autorisés sont vérifiés côté API, pas côté présence - une présence ne peut pas proxifier un domaine arbitraire juste en le demandant à l'exécution. Il n'y a pas d'étape d'approbation séparée ni de changement de code côté API : vous déclarez directement les hosts dont votre présence a besoin dans son propre metadata.json, avec le même service (le slug de votre présence) que vous passez déjà au helper :
"imageProxy": {
"hostSuffixes": ["netflix.com", "nflxvideo.net", "nflximg.net"],
"headers": { "Referer": "https://www.netflix.com/" }
}C'est publié vers l'API automatiquement, de la même façon que le reste de votre metadata.json l'est déjà. L'API ne fait confiance à cette déclaration que pour le service id de votre propre présence : une présence ne peut pas déclarer des noms d'hôte au nom d'une autre, et une requête n'est autorisée que si le hostname de l'URL cible correspond réellement à l'un des suffixes déclarés.
Quand votre PR touche imageProxy, le bot de preview des présences le détecte automatiquement, ajoute une section Image Proxy Requested à son commentaire listant les noms d'hôte déclarés, et applique un label image-proxy. Un relecteur doit tout de même confirmer que ces noms d'hôte sont publics et sûrs à proxifier avant de merger - expliquez dans votre PR pourquoi Discord ne peut pas utiliser l'URL directe et quelle image sera affichée.
Limites et sécurité
Le proxy ne sert que des images publiques dont les hosts ont été déclarés par une présence relue. Il refuse les URL non HTTPS, les hosts qui ne correspondent à aucun suffixe déclaré, les réponses qui ne sont pas des images et les fichiers trop lourds.
Les endpoints eux-mêmes sont publics et non authentifiés (les présences les appellent directement depuis le navigateur, il n'y a donc pas de secret à y attacher) et partagent la limite de débit globale de l'API - il n'y a pas de quota dédié par présence. Ne l'utilisez pas pour des comptes privés, des ressources authentifiées, des URL de tracking, des entrées utilisateur arbitraires ou du contenu qui n'est pas une image.