Contas conectadas

Conecte contas do Google, Facebook e Apple Business Connect, associe suas listagens a locais e desconecte-as com o SDK listingsapi-js.

Uma conta conectada é uma autorização OAuth concedida por um proprietário de Google Business Profile, Facebook Pages ou Apple Business Connect. Depois que a autorização é concedida, a plataforma pode ler as listagens pertencentes a essa conta e vincular cada uma a um local. Todos os métodos de contas conectadas estão na instância do cliente ListingsAPI.

A sequência usual é: criar um link de conexão, aguardar a autorização do proprietário, listar as contas para obter um connectedAccountId, iniciar a correspondência, analisar as sugestões e, então, confirmá-las ou vincular uma listagem manualmente. A promessa retornada por cada método é resolvida com o payload contido na chave de resposta específica desse método, indicada em cada seção abaixo.

connectGoogleAccount

Crie um link OAuth com escopo de toda a conta para o Google Business Profile. Direcione o proprietário para o url retornado; ele retorna ao seu successUrl ou errorUrl quando a tela de consentimento é fechada.

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âmetroTipoDescrição
successUrlstringURL absoluta à qual o proprietário retorna após autorizar.
errorUrlstringURL absoluta à qual o proprietário retorna se cancelar ou se a autorização falhar.

A promessa é resolvida com o payload de bulkConnectLinkForGoogle: url, success e errors. Verifique url, e não apenas success, porque um redirecionamento inválido pode ser retornado como sucesso com url nulo. O link tem validade curta, então crie um novo a cada tentativa.

connectFacebookAccount

O equivalente de connectGoogleAccount para Facebook Pages, com os mesmos dois argumentos de redirecionamento.

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âmetroTipoDescrição
successUrlstringURL absoluta à qual o proprietário retorna após autorizar.
errorUrlstringURL absoluta à qual o proprietário retorna se cancelar ou se a autorização falhar.

A promessa é resolvida com o payload de bulkConnectLinkForFacebook: url, success e errors.

getOauthConnectUrl

Crie um link OAuth com escopo de um único local, em vez de uma conta inteira. Use-o quando você já souber qual local o proprietário está conectando e quiser que ele retorne à tela desse local no seu próprio produto.

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âmetroTipoDescrição
locationIdstring | numberLocal ao qual a conexão é associada. Os IDs numéricos são codificados automaticamente para você.
sitestringPlataforma de publicação a conectar: 'GOOGLE', 'FACEBOOK' ou 'APPLE'.
successUrlstringURL absoluta à qual o proprietário retorna após autorizar.
errorUrlstringURL absoluta à qual o proprietário retorna se a autorização falhar.

A promessa é resolvida com o payload de createConnectUrl: url, success e errors. As duas URLs de redirecionamento são obrigatórias e devem ser absolutas. O link só pode ser usado uma vez e fica vinculado ao local que você informou.

fetchConnectedAccounts

Liste as contas do Google e do Facebook autorizadas na sua conta, com informações sobre o funcionamento da conexão e a quantidade de locais vinculados. É aqui que você obtém o connectedAccountId necessário para todos os métodos seguintes.

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);}

Opções

ParâmetroTipoDescrição
publisherstringTipo de conta, por exemplo, 'GoogleAccount' ou 'FacebookAccount'.
statusstringFiltro de status da conexão: 'Connected', 'NotConnected' ou 'ConnectionIssue'.
pagenumberNúmero da página (a partir de 1).
perPagenumberRegistros por página.

A promessa é resolvida com o payload de connectedAccountsInfo: um array records e pageInfo com hasNextPage, hasPreviousPage, totalPages e totalRecords. Cada registro contém connectedAccountId, email, connectedAccountType, connectedLocationsCount, connectivityIssue, status e requestMatchesStatus.

O filtro e o campo não usam o mesmo conjunto de valores. A opção status aceita 'Connected', 'NotConnected' ou 'ConnectionIssue', enquanto o próprio status de um registro contém CONNECTED, MATCH_IN_PROGRESS ou CONNECTIVITY_ISSUE. Usar o valor de um registro como filtro resulta em rejeição.

fetchConnectedAccountDetails

Consulte uma conta pelo ID. Essa consulta tem menor custo do que percorrer todas as páginas da lista quando você já tem o ID, e é o método a consultar periodicamente enquanto a correspondência é executada.

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âmetroTipoDescrição
connectedAccountIdstringID da conta conectada, obtido de fetchConnectedAccounts.

A promessa é resolvida com o payload de connectedAccountDetails, que contém o registro em details com os mesmos campos retornados pela lista. Monitore requestMatchesStatus para saber quando as sugestões estiverem prontas e consulte status e connectivityIssue para decidir se deve solicitar uma nova autorização.

fetchConnectedAccountFolders

Liste os grupos de contas (pastas) do Google aos quais a conta conectada tem acesso. Chame esse método antes de createGmbListing quando o proprietário quiser a nova listagem em um 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' },);

Opções

ParâmetroTipoDescrição
folderNamestringRestrinja o resultado às pastas que correspondam a esse nome.

A promessa é resolvida com o array getFoldersUnderGoogleAccount, cujo valor padrão é um array vazio. Cada pasta contém folderId (uma string accounts/<id> que você repassa sem alterações), folderName e locationCount, que pode ser nulo quando o Google não informa uma contagem. O caminho é válido apenas para contas do tipo Google.

fetchConnectedAccountListings

Liste as listagens das plataformas de publicação às quais a conta conectada tem acesso. O id de cada registro é exatamente o connectedAccountListingId aceito por connectListing, portanto é assim que você cria um seletor de listagens.

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);}

Opções

ParâmetroTipoDescrição
locationInfostringBusca por texto livre no nome da empresa, endereço, localidade, código postal, código da loja e telefone.
pagenumberNúmero da página (a partir de 1).
perPagenumberRegistros por página. O padrão é 500, que também é o máximo.

A promessa é resolvida com o payload de connectedAccountListings: records e pageInfo. Cada registro contém id, locationName, address, phone, liveLink e accountTypeName. Embora a requisição subjacente tenha formato de escrita, esta é uma operação de leitura: o SDK coloca o ID da conta e os dados de paginação no corpo da requisição para você, conforme exigido pelo endpoint.

triggerConnectedAccountMatches

Coloque na fila a tarefa que busca todos os perfis aos quais as contas informadas têm acesso e procura correspondências com seus locais. Chame esse método assim que o proprietário concluir a etapa da tela de consentimento e novamente depois de criar locais em massa.

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

Parâmetros

ParâmetroTipoDescrição
connectedAccountIdsstring[]Contas para as quais executar a correspondência.

A promessa é resolvida com o payload de connectedAccountsTriggerMatches: success e failedIds. Um valor true em success significa que a tarefa foi colocada na fila, não que a correspondência foi concluída. Consulte fetchConnectedAccountDetails periodicamente até que requestMatchesStatus contenha MATCH_COMPLETED e, então, consulte as sugestões.

fetchConnectionSuggestions

Consulte os pares produzidos pela correspondência para que um operador possa comparar cada local com a listagem na plataforma de publicação antes que qualquer vínculo seja criado.

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);}

Opções

ParâmetroTipoDescrição
pagenumberNúmero da página (a partir de 1).
perPagenumberRegistros por página.

A promessa é resolvida com o payload de connectionSuggestionsForAccount: records e pageInfo. Um registro de sugestão não tem o campo id. Seu identificador é matchedDataDatabaseId, e accountType (GMB, FB ou APPLE) indica o tipo de registro de correspondência. Mantenha os dois juntos, porque confirmConnectedAccountMatches precisa de ambos para montar o ID que aceita. Uma conta que ainda não tem correspondências retorna um array records vazio.

confirmConnectedAccountMatches

Aceite os pares analisados. A confirmação vincula cada local à sua listagem na plataforma de publicação para que as atualizações posteriores do local sejam propagadas.

Monte cada ID a partir de um registro de sugestão: una o nome do tipo de registro de correspondência e o matchedDataDatabaseId do registro com dois-pontos e, em seguida, codifique o resultado em base64. GMB corresponde a GmbLocationMatchedData, FB a FbLocationMatchedData e 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âmetroTipoDescrição
matchRecordIdsstring[]IDs codificados dos registros de correspondência a confirmar. Pelo menos um é obrigatório.

A promessa é resolvida com o payload de confirmConnectMatches: success e failedIds. Verifique success em todas as chamadas: um ID que não é decodificado como um dos três tipos resulta em uma resposta com formato de sucesso, com success definido como false e sem failedIds. Quando alguns IDs falham, failedIds contém os IDs decodificados do banco de dados, não os valores codificados que você enviou, então compare-os com matchedDataDatabaseId para identificar as correspondências.

Vincular uma listagem a um local

Três métodos concluem o vínculo entre uma única listagem correspondente e um único local, e são documentados junto aos demais endpoints de listagens, em vez de serem documentados duas vezes:

Use esses métodos depois que confirmConnectedAccountMatches tiver processado a maior parte de uma conta, quando um estabelecimento ainda precisar ser associado manualmente.


oauthDisconnect

A mesma desconexão de um único local, acessada pelo fluxo OAuth por local. Ela recebe os mesmos argumentos e retorna o mesmo payload, então escolha o nome que ficar mais claro no seu código.

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

Parâmetros

ParâmetroTipoDescrição
locationIdstring | numberLocal a desconectar.
sitestringPlataforma de publicação da qual desconectar: 'GOOGLE', 'FACEBOOK' ou 'APPLE'.

Retorna o payload disconnectConnectedAccountsLocations, a mesma chave retornada por disconnectListing.

disconnectGoogleAccount

Desconecta uma conta Google inteira: todos os locais vinculados por meio dela deixam de receber atualizações. Use esse método quando um cliente cancelar o serviço ou transferir a propriedade.

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

Parâmetros

ParâmetroTipoDescrição
connectedAccountIdstringConta Google a desconectar.

Retorna o payload gmbBulkDisconnect, que contém success. A operação afeta todos os locais ou nenhum: para desvincular um único local e manter a conta, use disconnectListing. O valor true é retornado em success mesmo para um ID desconhecido, então consulte fetchConnectedAccounts depois se precisar ter certeza.

disconnectFacebookAccount

O equivalente para Facebook, com o mesmo argumento e o mesmo comportamento de afetar todos os locais ou nenhum.

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

Parâmetros

ParâmetroTipoDescrição
connectedAccountIdstringConta Facebook a desconectar.

Retorna o payload fbBulkDisconnect, que contém success. A mesma ressalva se aplica: mesmo um ID desconhecido resulta em uma indicação de sucesso, então verifique com fetchConnectedAccounts.

Fluxo típico de configuração 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');