L'API Google Business Reviews permet aux développeurs de gérer de manière programmatique les avis clients sur les établissements Google Business Profile. Que vous construisiez un tableau de bord de gestion de réputation, automatisiez les réponses aux avis ou agrégez les retours sur plusieurs établissements, cette API fournit la base pour une gestion évolutive des avis.
Ce guide couvre tout ce dont vous avez besoin pour intégrer l'API GBP dans votre application : de la configuration initiale à l'authentification OAuth, en passant par la récupération des avis, les réponses programmatiques et la gestion des cas particuliers inévitables lors des déploiements en production.

Introduction à l'API Google Business Profile
Les API business de Google ont considérablement évolué au fil des années. L'implémentation actuelle utilise une combinaison de endpoints API :
- My Business Account Management API (
mybusinessaccountmanagement.googleapis.com/v1) : Gère les comptes et les permissions - My Business Business Information API (
mybusinessbusinessinformation.googleapis.com/v1) : Gère les données d'établissement - My Business API v4 (
mybusiness.googleapis.com/v4) : Gère les avis et les publications locales (toujours active pour ces fonctionnalités)
La fonctionnalité Google My Business API reviews réside spécifiquement dans l'API v4. Bien que Google ait migré de nombreuses fonctionnalités vers les nouveaux endpoints v1, la gestion des avis reste sur la v4 sans date de dépréciation annoncée.
Note : Google met fréquemment à jour la structure de ses API. Les endpoints v4 pour les avis sont stables, mais vérifiez toujours la documentation officielle pour les dernières modifications.
Ce que vous pouvez faire avec l'API Reviews
L'API GBP prend en charge ces opérations principales sur les avis :
| Opération | Méthode HTTP | Endpoint |
|---|---|---|
| Lister les avis | GET | /accounts/{id}/locations/{id}/reviews |
| Obtenir un avis unique | GET | /accounts/{id}/locations/{id}/reviews/{reviewId} |
| Répondre à un avis | PUT | /accounts/{id}/locations/{id}/reviews/{reviewId}/reply |
| Mettre à jour une réponse | PUT | /accounts/{id}/locations/{id}/reviews/{reviewId}/reply |
| Supprimer une réponse | DELETE | /accounts/{id}/locations/{id}/reviews/{reviewId}/reply |
Vous ne pouvez pas supprimer les avis clients via l'API. Seul l'auteur de l'avis ou Google (en cas de violation des règles) peut supprimer des avis.
Configuration du Projet Google Cloud
Avant d'écrire du code, vous avez besoin d'un projet Google Cloud correctement configuré avec les API appropriées activées.
Étape 1 : Créer un Projet Google Cloud
- Accédez à Google Cloud Console
- Créez un nouveau projet ou sélectionnez-en un existant
- Notez l'ID de votre projet pour une utilisation ultérieure
Étape 2 : Activer les API Requises
Activez ces API dans votre projet :
# Utilisation de gcloud CLI
gcloud services enable mybusinessaccountmanagement.googleapis.com
gcloud services enable mybusinessbusinessinformation.googleapis.com
gcloud services enable mybusiness.googleapis.com
Ou activez-les via la Cloud Console :
- My Business Account Management API
- My Business Business Information API
- Google My Business API
Étape 3 : Configurer l'Écran de Consentement OAuth
- Allez dans APIs & Services > OAuth consent screen
- Sélectionnez le type d'utilisateur External (sauf si vous avez une organisation Google Workspace)
- Remplissez les champs requis :
- Nom de l'application
- Email de support utilisateur
- Email de contact du développeur
- Ajoutez le scope requis :
https://www.googleapis.com/auth/business.manage - Ajoutez des utilisateurs de test (requis en mode test)
Étape 4 : Créer les Identifiants OAuth
- Allez dans APIs & Services > Credentials
- Cliquez sur Create Credentials > OAuth client ID
- Sélectionnez Web application
- Ajoutez vos URI de redirection autorisées
- Sauvegardez votre Client ID et Client Secret
// Stockez ces valeurs dans des variables d'environnement
const config = {
clientId: process.env.GOOGLE_BUSINESS_CLIENT_ID,
clientSecret: process.env.GOOGLE_BUSINESS_CLIENT_SECRET,
redirectUri: process.env.GOOGLE_BUSINESS_REDIRECT_URI,
};
OAuth 2.0 pour Google Business
Google Business Profile nécessite OAuth 2.0 avec accès hors ligne pour obtenir des refresh tokens. Cela permet à votre application d'accéder à l'API sans nécessiter une ré-authentification des utilisateurs.
Génération de l'URL d'Autorisation
function getGoogleBusinessAuthUrl(state?: string): string {
const scopes = [
'https://www.googleapis.com/auth/business.manage',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'
];
const params = new URLSearchParams({
client_id: process.env.GOOGLE_BUSINESS_CLIENT_ID!,
redirect_uri: process.env.GOOGLE_BUSINESS_REDIRECT_URI!,
scope: scopes.join(' '),
response_type: 'code',
access_type: 'offline',
prompt: 'consent', // Force l'écran de consentement pour garantir le refresh token
});
if (state) {
params.append('state', state);
}
return `https://accounts.google.com/o/oauth2/auth?${params.toString()}`;
}
Le paramètre prompt: 'consent' est critique. Sans lui, Google peut ne pas retourner de refresh token lors des autorisations suivantes.
Échange du Code d'Autorisation
Après que l'utilisateur a autorisé votre application, Google le redirige avec un code d'autorisation :
interface TokenResponse {
access_token: string;
refresh_token?: string;
expires_in: number;
token_type: string;
scope: string;
}
async function exchangeCodeForToken(code: string): Promise<TokenResponse> {
const response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
code,
client_id: process.env.GOOGLE_BUSINESS_CLIENT_ID!,
client_secret: process.env.GOOGLE_BUSINESS_CLIENT_SECRET!,
redirect_uri: process.env.GOOGLE_BUSINESS_REDIRECT_URI!,
grant_type: 'authorization_code',
}),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Échec de l'échange de token : ${response.status} ${errorText}`);
}
return response.json();
}
Note : Stockez le refresh token de manière sécurisée. Il n'est retourné que lors de l'autorisation initiale (ou lors de l'utilisation de
prompt: 'consent').
Structure des Comptes et Établissements
L'API GBP utilise une structure hiérarchique : les Utilisateurs ont des Comptes, et les Comptes contiennent des Établissements. Vous avez besoin des deux ID pour accéder aux avis.
Récupération des Comptes Utilisateur
interface GBPAccount {
name: string; // Format: "accounts/123456789"
accountName: string;
type: string;
role: string;
state: { status: string };
}
async function getAccounts(accessToken: string): Promise<GBPAccount[]> {
const allAccounts: GBPAccount[] = [];
let pageToken: string | undefined;
do {
const url = new URL('https://mybusinessaccountmanagement.googleapis.com/v1/accounts');
url.searchParams.set('pageSize', '100');
if (pageToken) {
url.searchParams.set('pageToken', pageToken);
}
const response = await fetch(url.toString(), {
headers: { Authorization: `Bearer ${accessToken}` },
});
if (!response.ok) {
throw new Error(`Échec de la récupération des comptes : ${response.status}`);
}
const data = await response.json();
if (data.accounts) {
allAccounts.push(...data.accounts);
}
pageToken = data.nextPageToken;
} while (pageToken);
return allAccounts;
}
Récupération des Établissements d'un Compte
interface GBPLocation {
name: string; // Format: "locations/987654321"
title: string;
storefrontAddress?: {
addressLines: string[];
locality: string;
administrativeArea: string;
postalCode: string;
regionCode: string;
};
websiteUri?: string;
}
async function getLocations(
accessToken: string,
accountId: string
): Promise<GBPLocation[]> {
const allLocations: GBPLocation[] = [];
let pageToken: string | undefined;
do {
const url = new URL(
`https://mybusinessbusinessinformation.googleapis.com/v1/${accountId}/locations`
);
url.searchParams.set('readMask', 'name,title,storefrontAddress,websiteUri');
url.searchParams.set('pageSize', '100');
if (pageToken) {
url.searchParams.set('pageToken', pageToken);
}
const response = await fetch(url.toString(), {
headers: { Authorization: `Bearer ${accessToken}` },
});
if (!response.ok) {
throw new Error(`Échec de la récupération des établissements : ${response.status}`);
}
const data = await response.json();
if (data.locations) {
allLocations.push(...data.locations);
}
pageToken = data.nextPageToken;
} while (pageToken);
return allLocations;
}
Récupération des Avis avec l'API Google Business Reviews
Avec les ID de compte et d'établissement en main, vous pouvez récupérer les avis. L'API Google Business Reviews retourne les avis par ordre chronologique inverse par défaut.
Récupération Basique des Avis
interface ReviewReply {
comment: string;
updateTime: string;
}
interface Review {
id: string;
name: string;
reviewer: {
displayName: string;
profilePhotoUrl?: string;
isAnonymous: boolean;
};
rating: number;
starRating: 'ONE' | 'TWO' | 'THREE' | 'FOUR' | 'FIVE';
comment?: string;
createTime: string;
updateTime: string;
reviewReply?: ReviewReply;
}
interface ReviewsResponse {
reviews: Review[];
averageRating?: number;
totalReviewCount?: number;
nextPageToken?: string;
}
async function getReviews(
accessToken: string,
accountId: string,
locationId: string,
options?: { pageSize?: number; pageToken?: string }
): Promise<ReviewsResponse> {
// Extraire les ID numériques si des noms de ressources complets sont fournis
const accId = accountId.includes('/') ? accountId.split('/').pop() : accountId;
const locId = locationId.includes('/') ? locationId.split('/').pop() : locationId;
const pageSize = Math.min(options?.pageSize || 50, 50); // Max 50 par requête
const url = new URL(
`https://mybusiness.googleapis.com/v4/accounts/${accId}/locations/${locId}/reviews`
);
url.searchParams.set('pageSize', String(pageSize));
if (options?.pageToken) {
url.searchParams.set('pageToken', options.pageToken);
}
const response = await fetch(url.toString(), {
headers: { Authorization: `Bearer ${accessToken}` },
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`Échec de la récupération des avis : ${response.status} ${errorBody}`);
}
const data = await response.json();
// Mapper les chaînes de notation en étoiles vers des valeurs numériques
const starRatingMap: Record<string, number> = {
ONE: 1,
TWO: 2,
THREE: 3,
FOUR: 4,
FIVE: 5,
};
const reviews = (data.reviews || []).map((review: any) => ({
id: review.reviewId || review.name?.split('/').pop(),
name: review.name,
reviewer: {
displayName: review.reviewer?.displayName || 'Anonyme',
profilePhotoUrl: review.reviewer?.profilePhotoUrl || null,
isAnonymous: review.reviewer?.isAnonymous || false,
},
rating: starRatingMap[review.starRating] || 0,
starRating: review.starRating,
comment: review.comment || '',
createTime: review.createTime,
updateTime: review.updateTime,
reviewReply: review.reviewReply
? {
comment: review.reviewReply.comment,
updateTime: review.reviewReply.updateTime,
}
: null,
}));
return {
reviews,
averageRating: data.averageRating,
totalReviewCount: data.totalReviewCount,
nextPageToken: data.nextPageToken,
};
}
Récupération de Tous les Avis avec Pagination
Pour les établissements avec de nombreux avis, vous devrez gérer la pagination :
async function getAllReviews(
accessToken: string,
accountId: string,
locationId: string
): Promise<Review[]> {
const allReviews: Review[] = [];
let pageToken: string | undefined;
do {
const response = await getReviews(accessToken, accountId, locationId, {
pageSize: 50,
pageToken,
});
allReviews.push(...response.reviews);
pageToken = response.nextPageToken;
// Ajouter un petit délai pour éviter le rate limiting
if (pageToken) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
} while (pageToken);
return allReviews;
}
Répondre aux Avis de Manière Programmatique
La capacité de répondre aux avis Google via l'API de manière programmatique est essentielle pour les entreprises gérant plusieurs établissements. Des réponses rapides aux avis améliorent la perception client et peuvent avoir un impact positif sur le SEO local.
Création d'une Réponse à un Avis
async function replyToReview(
accessToken: string,
reviewName: string,
replyText: string
): Promise<{ success: boolean }> {
// Format de reviewName : accounts/{accountId}/locations/{locationId}/reviews/{reviewId}
const response = await fetch(
`https://mybusiness.googleapis.com/v4/${reviewName}/reply`,
{
method: 'PUT',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
comment: replyText,
}),
}
);
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`Échec de la réponse à l'avis : ${response.status} ${errorBody}`);
}
return { success: true };
}