Cuentas conectadas

Conecta cuentas de Google, Facebook y Apple Business Connect, vincula sus fichas a ubicaciones y desconéctalas con el SDK listingsapi-js.

Una cuenta conectada es una autorización OAuth otorgada por un propietario de Google Business Profile, Facebook Pages o Apple Business Connect. Una vez otorgada la autorización, la plataforma puede leer las fichas que pertenecen a esa cuenta y vincular cada una a una ubicación. Todos los métodos de cuentas conectadas están en la instancia del cliente ListingsAPI.

El orden habitual es: crear un enlace de conexión, esperar a que el propietario autorice el acceso, enumerar las cuentas para obtener un connectedAccountId, iniciar la búsqueda de coincidencias, revisar las sugerencias y, después, confirmarlas o vincular una ficha manualmente. Cada método se resuelve con los datos de su propia clave de respuesta, que se indica en cada sección siguiente.

connectGoogleAccount

Crea un enlace OAuth con alcance para toda la cuenta para Google Business Profile. Dirige al propietario al url devuelto; volverá a tu successUrl o errorUrl cuando se cierre la pantalla de consentimiento.

TypeScript
const link = await client.connectGoogleAccount('https://app.example.com/onboarding/google/done','https://app.example.com/onboarding/google/failed',); console.log(link.url);

Parámetros

ParámetroTipoDescripción
successUrlstringURL absoluta a la que vuelve el propietario después de autorizar el acceso.
errorUrlstringURL absoluta a la que vuelve el propietario si cancela o si falla la autorización.

Se resuelve con los datos de bulkConnectLinkForGoogle: url, success y errors. Comprueba url y no solo success, porque una redirección que no se puede utilizar puede devolverse como un resultado correcto con url en null. El enlace tiene una validez breve, así que crea uno nuevo para cada intento.

connectFacebookAccount

El equivalente de connectGoogleAccount para Facebook Pages, con los mismos dos argumentos de redirección.

TypeScript
const link = await client.connectFacebookAccount('https://app.example.com/onboarding/facebook/done','https://app.example.com/onboarding/facebook/failed',); console.log(link.url);

Parámetros

ParámetroTipoDescripción
successUrlstringURL absoluta a la que vuelve el propietario después de autorizar el acceso.
errorUrlstringURL absoluta a la que vuelve el propietario si cancela o si falla la autorización.

Se resuelve con los datos de bulkConnectLinkForFacebook: url, success y errors.

getOauthConnectUrl

Crea un enlace OAuth cuyo alcance se limita a una ubicación en lugar de a toda una cuenta. Úsalo cuando ya sepas qué ubicación está conectando el propietario y quieras que vuelva a la pantalla de esa ubicación en tu propio producto.

TypeScript
const link = await client.getOauthConnectUrl(1800289,'GOOGLE','https://app.example.com/locations/1800289/connected','https://app.example.com/locations/1800289/connect-failed',); console.log(link.url);

Parámetros

ParámetroTipoDescripción
locationIdstring | numberUbicación a la que se asocia la conexión. Los ID numéricos se codifican automáticamente.
sitestringPlataforma de publicación que se va a conectar: 'GOOGLE', 'FACEBOOK' o 'APPLE'.
successUrlstringURL absoluta a la que vuelve el propietario después de autorizar el acceso.
errorUrlstringURL absoluta a la que vuelve el propietario si falla la autorización.

Se resuelve con los datos de createConnectUrl: url, success y errors. Ambas URL de redirección son obligatorias y deben ser absolutas. El enlace es de un solo uso y está asociado a la ubicación que indicaste.

fetchConnectedAccounts

Enumera las cuentas de Google y Facebook autorizadas en tu cuenta, con el estado de la conexión y el número de ubicaciones vinculadas. Aquí obtienes el connectedAccountId que necesitan todos los métodos posteriores.

TypeScript
const page1 = await client.fetchConnectedAccounts({publisher: 'GoogleAccount',status: 'Connected',page: 1,perPage: 20,}); for (const record of page1.records ?? []) {console.log(record.email, record.connectedAccountId, record.status);}

Opciones

ParámetroTipoDescripción
publisherstringTipo de cuenta, por ejemplo, 'GoogleAccount' o 'FacebookAccount'.
statusstringFiltro de estado de la conexión: 'Connected', 'NotConnected' o 'ConnectionIssue'.
pagenumberNúmero de página (a partir de 1).
perPagenumberRegistros por página.

Se resuelve con los datos de connectedAccountsInfo: un array records y pageInfo con hasNextPage, hasPreviousPage, totalPages y totalRecords. Cada registro contiene connectedAccountId, email, connectedAccountType, connectedLocationsCount, connectivityIssue, status y requestMatchesStatus.

El filtro y el campo no utilizan el mismo conjunto de valores. La opción status acepta 'Connected', 'NotConnected' o 'ConnectionIssue', mientras que el campo status del propio registro tiene el valor CONNECTED, MATCH_IN_PROGRESS o CONNECTIVITY_ISSUE. Si se utiliza el valor de un registro como filtro, la solicitud se rechaza.

fetchConnectedAccountDetails

Lee una cuenta por su ID. Consume menos recursos que recorrer todas las páginas de la lista cuando ya tienes el ID, y es el método que debes consultar periódicamente mientras se ejecuta la búsqueda de coincidencias.

TypeScript
const details = await client.fetchConnectedAccountDetails('4f712c17-4f95-42dd-90f4-97171a2e67b5',); console.log(details.details.requestMatchesStatus); // MATCH_IN_PROGRESS, then MATCH_COMPLETED

Parámetros

ParámetroTipoDescripción
connectedAccountIdstringID de la cuenta conectada, obtenido de fetchConnectedAccounts.

Se resuelve con los datos de connectedAccountDetails, que incluyen el registro anidado en details con los mismos campos que devuelve la lista. Comprueba requestMatchesStatus para saber cuándo están listas las sugerencias y lee status y connectivityIssue para decidir si debes solicitar una nueva autorización.

fetchConnectedAccountFolders

Enumera los grupos de cuentas de Google (carpetas) a los que puede acceder la cuenta conectada. Llámalo antes de createGmbListing cuando el propietario quiera que la nueva ficha esté en un grupo específico.

TypeScript
const folders = await client.fetchConnectedAccountFolders('4f712c17-4f95-42dd-90f4-97171a2e67b5',); for (const folder of folders) {console.log(folder.folderId, folder.folderName, folder.locationCount);} // Narrow by nameconst matching = await client.fetchConnectedAccountFolders('4f712c17-4f95-42dd-90f4-97171a2e67b5',{ folderName: 'West Region' },);

Opciones

ParámetroTipoDescripción
folderNamestringLimita el resultado a las carpetas que coincidan con este nombre.

Se resuelve con el array getFoldersUnderGoogleAccount, cuyo valor predeterminado es un array vacío. Cada carpeta contiene folderId (una cadena accounts/<id> que debes pasar sin cambios), folderName y locationCount, que puede ser null cuando Google no proporciona un recuento. La ruta solo es válida para cuentas de tipo Google.

fetchConnectedAccountListings

Enumera las fichas de las plataformas de publicación a las que tiene acceso la cuenta conectada. El campo id de cada registro es exactamente el connectedAccountListingId que acepta connectListing, por lo que puedes usarlo para crear un selector de fichas.

TypeScript
const listings = await client.fetchConnectedAccountListings('4f712c17-4f95-42dd-90f4-97171a2e67b5',{ locationInfo: 'William St', page: 1, perPage: 50 },); for (const record of listings.records ?? []) {console.log(record.id, record.locationName, record.address);}

Opciones

ParámetroTipoDescripción
locationInfostringBúsqueda de texto libre por nombre del negocio, dirección, localidad, código postal, código de tienda y teléfono.
pagenumberNúmero de página (a partir de 1).
perPagenumberRegistros por página. El valor predeterminado es 500, que también es el máximo.

Se resuelve con los datos de connectedAccountListings: records y pageInfo. Cada registro contiene id, locationName, address, phone, liveLink y accountTypeName. Aunque internamente utiliza una solicitud con formato de escritura, esta es una operación de lectura: el SDK coloca automáticamente el ID de la cuenta y los datos de paginación en el cuerpo de la solicitud, tal como exige el endpoint.

triggerConnectedAccountMatches

Añade a la cola la tarea que obtiene todos los perfiles a los que pueden acceder las cuentas indicadas y busca coincidencias con tus ubicaciones. Llámalo justo después de que un propietario complete la pantalla de consentimiento y de nuevo después de crear ubicaciones en bloque.

TypeScript
const result = await client.triggerConnectedAccountMatches(['4f712c17-4f95-42dd-90f4-97171a2e67b5',]); console.log(result.success, result.failedIds);

Parámetros

ParámetroTipoDescripción
connectedAccountIdsstring[]Cuentas para las que se ejecutará la búsqueda de coincidencias.

Se resuelve con los datos de connectedAccountsTriggerMatches: success y failedIds. Un valor true en success significa que la tarea se añadió a la cola, no que la búsqueda de coincidencias haya terminado. Consulta fetchConnectedAccountDetails periódicamente hasta que requestMatchesStatus tenga el valor MATCH_COMPLETED y, después, lee las sugerencias.

fetchConnectionSuggestions

Lee los emparejamientos generados por la búsqueda de coincidencias para que un operador pueda comparar cada ubicación con la ficha de la plataforma de publicación antes de que se vincule nada.

TypeScript
const suggestions = await client.fetchConnectionSuggestions('4f712c17-4f95-42dd-90f4-97171a2e67b5',{ page: 1, perPage: 50 },); for (const record of suggestions.records ?? []) {console.log(record.accountType, record.matchedDataDatabaseId, record.locationInfo.name);}

Opciones

ParámetroTipoDescripción
pagenumberNúmero de página (a partir de 1).
perPagenumberRegistros por página.

Se resuelve con los datos de connectionSuggestionsForAccount: records y pageInfo. Un registro de sugerencia no tiene un campo id. Su identificador es matchedDataDatabaseId, y accountType (GMB, FB o APPLE) indica de qué tipo de registro de coincidencia se trata. Conserva ambos valores juntos, porque confirmConnectedAccountMatches necesita los dos para construir el ID que acepta. Una cuenta que aún no tiene coincidencias devuelve un array records vacío.

confirmConnectedAccountMatches

Acepta los emparejamientos revisados. La confirmación vincula cada ubicación a su ficha en la plataforma de publicación para que se transmitan las actualizaciones posteriores de la ubicación.

Construye cada ID a partir de un registro de sugerencia: une el nombre del tipo de registro de coincidencia y el matchedDataDatabaseId del registro con dos puntos y, después, codifica el resultado en base64. GMB corresponde a GmbLocationMatchedData, FB a FbLocationMatchedData y APPLE a AppleLocationMatchedData.

TypeScript
const TYPES: Record<string, string> = {GMB: 'GmbLocationMatchedData',FB: 'FbLocationMatchedData',APPLE: 'AppleLocationMatchedData',}; const matchRecordId = (record: any) =>Buffer.from(TYPES[record.accountType] + ':' + record.matchedDataDatabaseId).toString('base64'); const approved = (suggestions.records ?? []).map(matchRecordId);const result = await client.confirmConnectedAccountMatches(approved); console.log(result.success, result.failedIds);

Parámetros

ParámetroTipoDescripción
matchRecordIdsstring[]ID codificados de los registros de coincidencia que se van a confirmar. Se requiere al menos uno.

Se resuelve con los datos de confirmConnectMatches: success y failedIds. Comprueba success en cada llamada: un ID que no se decodifica como uno de los tres tipos devuelve una respuesta con formato de éxito, con success en false y sin failedIds. Cuando algunos ID fallan, failedIds contiene los ID decodificados de la base de datos, no los valores codificados que enviaste, así que compáralos con matchedDataDatabaseId para identificar a cuáles corresponden.

Vincular una ficha a una ubicación

Tres métodos completan la vinculación entre una única ficha coincidente y una única ubicación, y se documentan junto con los demás endpoints de fichas para evitar duplicar su documentación:

Usa estos métodos después de que confirmConnectedAccountMatches haya procesado la mayor parte de una cuenta, cuando aún quede un establecimiento por vincular manualmente.


oauthDisconnect

La misma desconexión de una única ubicación, disponible a través de la ruta de OAuth por ubicación. Acepta los mismos argumentos y devuelve los mismos datos al resolverse, así que elige el nombre que resulte más claro en tu código.

TypeScript
await client.oauthDisconnect(1800289, 'GOOGLE');

Parámetros

ParámetroTipoDescripción
locationIdstring | numberUbicación que se va a desconectar.
sitestringPlataforma de publicación de la que se va a desconectar: 'GOOGLE', 'FACEBOOK' o 'APPLE'.

Al resolverse, devuelve los datos de disconnectConnectedAccountsLocations, la misma clave que devuelve disconnectListing.

disconnectGoogleAccount

Desconecta una cuenta de Google completa: todas las ubicaciones vinculadas a través de ella dejan de recibir actualizaciones. Úsalo cuando un cliente se da de baja o transfiere la propiedad.

TypeScript
await client.disconnectGoogleAccount('4f712c17-4f95-42dd-90f4-97171a2e67b5');

Parámetros

ParámetroTipoDescripción
connectedAccountIdstringCuenta de Google que se va a desconectar.

Al resolverse, devuelve los datos de gmbBulkDisconnect, que incluyen success. La operación se aplica a toda la cuenta: para desvincular una única ubicación y conservar la cuenta, usa disconnectListing. Se devuelve success con el valor true incluso para un ID desconocido, así que consulta fetchConnectedAccounts después si necesitas confirmarlo.

disconnectFacebookAccount

El equivalente para Facebook, con el mismo argumento y el mismo comportamiento que se aplica a toda la cuenta.

TypeScript
await client.disconnectFacebookAccount('9d2b5a41-0c7e-4f83-bb16-2ac43e70d915');

Parámetros

ParámetroTipoDescripción
connectedAccountIdstringCuenta de Facebook que se va a desconectar.

Al resolverse, devuelve los datos de fbBulkDisconnect, que incluyen success. Se aplica la misma salvedad: un ID desconocido también da lugar a una respuesta de éxito, así que comprueba el resultado con fetchConnectedAccounts.

Flujo habitual de configuración inicial

connect_google.ts
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); // reads LISTINGSAPI_KEY from env // 1. Send the owner through the consent screenconst link = await client.connectGoogleAccount('https://app.example.com/onboarding/google/done','https://app.example.com/onboarding/google/failed',);console.log('open:', link.url); // 2. After they return, pick up the account IDconst accounts = await client.fetchConnectedAccounts({ publisher: 'GoogleAccount' });const accountId = accounts.records[0].connectedAccountId; // 3. Match its listings against your locationsawait client.triggerConnectedAccountMatches([accountId]); // 4. Poll until matching finisheslet details = await client.fetchConnectedAccountDetails(accountId);while (details.details.requestMatchesStatus !== 'MATCH_COMPLETED') {await new Promise((resolve) => setTimeout(resolve, 5000));details = await client.fetchConnectedAccountDetails(accountId);} // 5. Read the suggestions and confirm the approved onesconst suggestions = await client.fetchConnectionSuggestions(accountId, { perPage: 100 });console.log('found ' + (suggestions.records ?? []).length + ' suggested matches');