@bdmarvin/mcp-server-gbp
Version:
MCP server for Google Business Profile Performance API.
58 lines (57 loc) • 2.6 kB
JavaScript
// Using the v4 endpoint which is known to be correct for these operations
const API_BASE_URL_V4 = 'https://mybusiness.googleapis.com/v4';
export class GbpMediaService {
async fetchWithAuth(url, method, accessToken, body = null) {
const headers = {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
};
const options = {
method,
headers,
};
if (body) {
options.body = JSON.stringify(body);
}
const response = await fetch(url, options);
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`API request failed with status ${response.status}: ${errorBody}`);
}
// A 204 No Content response is valid for DELETE
if (response.status === 204 || response.headers.get('content-length') === '0') {
return { success: true };
}
return response.json();
}
async listMedia(accessToken, params) {
const { parent, pageSize, pageToken } = params;
const [accountId, locationId] = parent.split('/');
const query = new URLSearchParams();
if (pageSize)
query.append('pageSize', pageSize.toString());
if (pageToken)
query.append('pageToken', pageToken);
const url = `${API_BASE_URL_V4}/accounts/${accountId}/locations/${locationId}/media?${query.toString()}`;
return this.fetchWithAuth(url, 'GET', accessToken);
}
async createMedia(accessToken, params) {
const { parent, ...mediaItem } = params;
const [accountId, locationId] = parent.split('/');
const url = `${API_BASE_URL_V4}/accounts/${accountId}/locations/${locationId}/media`;
return this.fetchWithAuth(url, 'POST', accessToken, mediaItem);
}
async updateMedia(accessToken, params) {
const { name, updateMask, data } = params;
const [accountId, locationId, mediaId] = name.split('/');
const query = new URLSearchParams({ updateMask });
const url = `${API_BASE_URL_V4}/accounts/${accountId}/locations/${locationId}/media/${mediaId}?${query.toString()}`;
return this.fetchWithAuth(url, 'PATCH', accessToken, data);
}
async deleteMedia(accessToken, params) {
const { name } = params;
const [accountId, locationId, mediaId] = name.split('/');
const url = `${API_BASE_URL_V4}/accounts/${accountId}/locations/${locationId}/media/${mediaId}`;
return this.fetchWithAuth(url, 'DELETE', accessToken);
}
}