Tenor vers couche compatible GIPHY
La façon la plus simple de quitter Tenor consiste à cibler la couche Heypster construite sur le modèle de GIPHY. Concrètement, vous ne remplacez pas Tenor par une API compatible Tenor, mais par une API Heypster exposée sous `/giphy` avec les conventions de GIPHY.
Le principal différentiel porte sur trois sujets : `key` devient `api_key`, la pagination à curseur `pos/next` devient une pagination numérique `offset/limit`, et le parsing passe de `results/media_formats` à `data/images`.
Authentification alignée sur GIPHY
Pagination à recalculer
Nouveau schéma de réponse
Avant / après
// avant (Tenor)
const API_HOST = 'https://tenor.googleapis.com';
fetch(`${API_HOST}/v2/search?q=party&key=YOUR_TENOR_KEY`);
// après (Heypster)
const API_HOST = 'https://heypster-gif.com/giphy';
fetch(`${API_HOST}/v1/gifs/search?q=party&api_key=YOUR_HEYPSTER_API_KEY`);
En provenance de Tenor, le premier changement consiste à remplacer l’hôte `https://tenor.googleapis.com` par `https://heypster-gif.com/giphy`. Le second est de remplacer le paramètre `key` par `api_key`, conformément à la couche compatible GIPHY exposée par Heypster.
# Tenor
curl "https://tenor.googleapis.com/v2/search?q=excited&key=YOUR_TENOR_KEY"
# Heypster
curl "https://heypster-gif.com/giphy/v1/gifs/search?q=excited&api_key=YOUR_HEYPSTER_API_KEY"
| Tenor | Heypster | Notes |
|---|---|---|
https://tenor.googleapis.com/v2/search |
https://heypster-gif.com/giphy/v1/gifs/search |
Recherche principale par mots-clés. |
https://tenor.googleapis.com/v2/featured |
https://heypster-gif.com/giphy/v1/gifs/trending |
Flux de découverte / tendances. |
https://tenor.googleapis.com/v2/categories |
https://heypster-gif.com/giphy/v1/gifs/categories |
Catégories exposées par la couche compatible GIPHY. |
https://tenor.googleapis.com/v2/autocomplete |
https://heypster-gif.com/giphy/v1/gifs/search/tags |
Suggestions de requêtes. |
https://tenor.googleapis.com/v2/search_suggestions |
https://heypster-gif.com/giphy/v1/tags/related/{term} |
Suggestions liées à un terme précis. |
https://tenor.googleapis.com/v2/trending_terms |
https://heypster-gif.com/giphy/v1/trending/searches |
Requêtes tendances. |
https://tenor.googleapis.com/v2/search?random=true |
https://heypster-gif.com/giphy/v1/gifs/random |
Heypster renvoie un item unique, pas une liste aléatoire. |
https://tenor.googleapis.com/v2/posts?ids=<ids> |
https://heypster-gif.com/giphy/v1/gifs?ids=<ids> |
Liste d’IDs séparés par des virgules. |
https://tenor.googleapis.com/v2/anonid |
https://heypster-gif.com/giphy/v1/randomid |
Identifiant aléatoire côté API compatible GIPHY. |
| Tenor | Heypster | Description |
|---|---|---|
key |
api_key |
Le nom du paramètre change. |
q |
q |
Le terme de recherche reste inchangé. |
pos |
offset |
Tenor utilise un token ; Heypster suit la logique GIPHY avec une pagination numérique. |
contentfilter |
rating |
Le filtrage de contenu suit le vocabulaire GIPHY. |
anon_id / anonid |
/giphy/v1/randomid |
Utilisez le workflow `randomid` si votre produit a besoin d’un identifiant anonyme cohérent. |
media_formats |
images |
Le mapping des formats passe par l’objet `images`. |
Tenor utilise `pos` et renvoie un token `next`. En migrant vers Heypster via notre couche compatible GIPHY, vous passez à une pagination numérique classique : `limit` fixe la taille de page, `offset` indique combien d’éléments ignorer.
// Tenor
const response1 = await fetch('https://tenor.googleapis.com/v2/search?q=cats&key=KEY');
const data1 = await response1.json();
const response2 = await fetch(`https://tenor.googleapis.com/v2/search?q=cats&key=KEY&pos=${data1.next}`);
// Heypster
const response1 = await fetch('https://heypster-gif.com/giphy/v1/gifs/search?q=cats&api_key=KEY&limit=25&offset=0');
const data1 = await response1.json();
const response2 = await fetch('https://heypster-gif.com/giphy/v1/gifs/search?q=cats&api_key=KEY&limit=25&offset=25');
Un parser Tenor lit généralement `results` et `next`. Ici, il faut relire `data`, `pagination` et `meta`. C’est le principal changement structurel après la pagination.
{
"data": [],
"pagination": {
"total_count": 500,
"count": 25,
"offset": 0
},
"meta": {
"status": 200,
"msg": "OK",
"response_id": "heypster-response-id"
}
}
const payload = await response.json();
const items = payload.data;
const offset = payload.pagination?.offset ?? 0;
const count = payload.pagination?.count ?? items.length;
const nextOffset = offset + count;
const status = payload.meta?.status;
| Tenor | Heypster | Description |
|---|---|---|
results[] |
data[] |
Le tableau principal change de nom. |
next |
pagination.offset + pagination.count |
Il n’y a plus de curseur opaque : la page suivante se calcule. |
results[].media_formats |
data[].images |
Les variantes d’assets se lisent depuis `images`. |
results[].content_rating |
data[].rating |
Le niveau de contenu se lit dans `rating`. |
results[].title / content_description |
data[].title |
Commencez par lire `title` comme libellé principal. |
| Format Tenor | Format Heypster | Usage |
|---|---|---|
gif |
images.original.url |
Version GIF principale. |
tinygif |
images.fixed_width.url ou images.fixed_height.url |
Version légère pour un picker ou une grille. |
mediumgif |
images.downsized.url |
Version optimisée pour un affichage standard. |
preview |
images.preview_gif.url |
Prévisualisation rapide. |
Si votre intégration Tenor utilisait `/v2/registershare`, prévoyez une adaptation spécifique : la surface Heypster documentée ici se concentre sur les endpoints de recherche, de découverte et d’identification (`randomid`), pas sur un endpoint Tenor dédié au suivi de partage.
const API_HOST = 'https://heypster-gif.com/giphy';
const API_KEY = 'YOUR_HEYPSTER_API_KEY';
export async function searchTenorLike(query, page = 0, limit = 25) {
const offset = page * limit;
const url = new URL(`${API_HOST}/v1/gifs/search`);
url.searchParams.set('api_key', API_KEY);
url.searchParams.set('q', query);
url.searchParams.set('limit', String(limit));
url.searchParams.set('offset', String(offset));
url.searchParams.set('rating', 'g');
const response = await fetch(url.toString());
const payload = await response.json();
return {
items: payload.data,
pagination: payload.pagination,
nextOffset: (payload.pagination?.offset ?? 0) + (payload.pagination?.count ?? 0),
meta: payload.meta,
};
}