Conecte o Google Business Profile e importe seus locais
Crie um link de conexão do Google, associe as listagens do Google do proprietário aos seus locais, confirme e importe as que ainda não têm local.
Uma conta Google conectada permite publicar e gerar relatórios para um local no Google. Até que uma conta seja conectada, a linha do Google Maps nas listagens premium de um local permanece REQUIRING_ACTION, as avaliações do Google não são importadas, as postagens não podem ser publicadas em GOOGLE e os dados de análise do Google retornam null. Conectar a conta resolve os quatro problemas.
O fluxo em lote (etapas 1 a 6) conecta uma conta Google inteira uma única vez e associa cada listagem pertencente a ela aos seus locais. O fluxo para um único local (etapa 7) conecta um local por vez: o link está vinculado àquele local, portanto não há uma etapa de associação depois.
1. Crie o link de conexão e redirecione o proprietário
O link tem como escopo a conta à qual pertence a chave de API, portanto o corpo contém apenas suas duas URLs de redirecionamento. Encaminhe o proprietário para o url retornado; o Google o redireciona para successUrl ou errorUrl quando ele conclui o processo.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-google \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "successUrl": "https://app.example.com/connect/google/success", "errorUrl": "https://app.example.com/connect/google/error" }}'{ "data": { "bulkConnectLinkForGoogle": { "success": true, "url": "https://connect.example.com/oauth?token=8f3c1d92-...", "errors": null } }}O url acima é um valor de exemplo. Encaminhe o proprietário para o url retornado na sua própria resposta.
O link é válido por 24 horas. Verifique se url não é nulo em vez de confiar apenas em success. Se as credenciais do proprietário expirarem posteriormente, crie um novo link da mesma forma: a conexão existente é renovada, não duplicada.
2. Liste as contas conectadas após o retorno do OAuth
Quando o proprietário chegar ao seu successUrl, liste as contas Google. Esta é uma página com paginação por deslocamento: records[] mais pageInfo.totalRecords, paginada com page e perPage.
curl "https://listingsapi.com/api/v4/connected-accounts?publisher=GoogleAccount&page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectedAccountsInfo": { "pageInfo": { "hasNextPage": false, "totalRecords": 1 }, "records": [ { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "email": "owner@brightsmile-dental.com", "status": "CONNECTED", "requestMatchesStatus": "MATCH_COMPLETED", "connectedLocationsCount": 0 } ] } }}Selecione o registro cujo email corresponde ao proprietário que acabou de dar consentimento e guarde seu connectedAccountId. Todas as chamadas posteriores recebem esse UUID.
O filtro de consulta opcional status usa palavras diferentes (Connected, NotConnected, ConnectionIssue); passar o próprio status de um registro como valor do filtro retorna um 400.
3. Inicie a associação
O processo de associação busca todos os perfis que a conta pode acessar e associa cada um a um dos seus locais. Ele apenas gera sugestões; nada é vinculado ainda.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/trigger-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountIds": ["4f712c17-4f95-42dd-90f4-97171a2e67b5"] } }'A resposta é data.connectedAccountsTriggerMatches com success e failedIds. success: true significa que a tarefa foi colocada na fila; qualquer conta que não pôde ser colocada na fila é listada em failedIds.
4. Consulte periodicamente até MATCH_COMPLETED
Consulte os detalhes da conta a cada 15 segundos em um laço com limite de execução. Esse intervalo também mantém o plano Launch dentro do limite de 10 requisições por minuto.
curl https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/details \-H "Authorization: API $LISTINGSAPI_KEY"O registro é retornado em data.connectedAccountDetails.details e tem os mesmos campos de um registro da lista. requestMatchesStatus é MATCH_IN_PROGRESS enquanto a tarefa está em execução e MATCH_COMPLETED quando as sugestões estão prontas. Completed significa que o processo de associação terminou, não que algo foi vinculado: connectedLocationsCount permanece 0 até você confirmar.
5. Avalie e confirme as sugestões
Cada sugestão associa um dos seus locais (locationInfo, com locationId como seu databaseId) a uma listagem do Google (suggestedLocationInfo). Mostre os dois lados a um operador ou aceite automaticamente quando o nome e a cidade coincidirem.
curl "https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/connection-suggestions?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectionSuggestionsForAccount": { "pageInfo": { "hasNextPage": false, "totalRecords": 2 }, "records": [ { "accountType": "GMB", "matchedDataDatabaseId": "0d5e306f-0da0-46e3-929f-fd3c67ccd8cc", "locationId": "73415", "locationInfo": { "name": "My Business", "city": "Lincoln", "stateIso": "NE" }, "suggestedLocationInfo": { "locationInfo": { "name": "My Business", "city": "Lincoln" } } } ] } }}Uma sugestão não tem id. Para confirmá-la, você monta um id de registro de associação: o base64 de <MatchRecordType>:<matchedDataDatabaseId>, com o tipo escolhido entre os valores de accountType. Para o Google (GMB), o tipo é GmbLocationMatchedData, portanto o registro acima é codificado como R21iTG9jYXRpb25NYXRjaGVkRGF0YTowZDVlMzA2Zi0wZGEwLTQ2ZTMtOTI5Zi1mZDNjNjdjY2Q4Y2M=. O Facebook (FB) usa FbLocationMatchedData e a Apple (APPLE) usa AppleLocationMatchedData.
# base64 of GmbLocationMatchedData:0d5e306f-0da0-46e3-929f-fd3c67ccd8cccurl -X POST https://listingsapi.com/api/v4/connected-accounts/confirm-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "matchRecordIds": ["R21iTG9jYXRpb25NYXRjaGVkRGF0YTowZDVlMzA2Zi0wZGEwLTQ2ZTMtOTI5Zi1mZDNjNjdjY2Q4Y2M="] } }'A resposta é data.confirmConnectMatches com success e failedIds. failedIds contém os valores decodificados de matchedDataDatabaseId que não puderam ser confirmados, como um registro já consumido ou um local arquivado após a associação. Um id montado com o tipo errado não retorna um 400: a chamada retorna 200 com success: false e sem failedIds, portanto verifique success sempre. As sugestões não enviadas permanecem inalteradas.
6. Importe listagens que ainda não têm um local
A correspondência apenas associa listagens a locais que você já tem. Para importar as demais, liste tudo o que a conta pode acessar e crie um local a partir de cada listagem desejada.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connected-account-listings \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "perPage": 50 }'{ "data": { "connectedAccountListings": { "pageInfo": { "hasNextPage": false, "totalRecords": 60 }, "records": [ { "id": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==", "locationName": "Trial", "address": "123 William St, NY 10038, Manhattan, US", "liveLink": null } ] } }}Envie locationInfo com um termo de busca para filtrar os resultados de uma conta grande por nome, endereço, telefone, código postal ou código da loja. O valor de id em cada registro é o connectedAccountListingId que as próximas duas chamadas recebem. Nenhum dos SDKs oferece suporte a create-location-from-listing ainda, então os exemplos em Python e Node chamam REST diretamente com o mesmo cabeçalho.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/create-location-from-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountListingId": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==" }}'{ "data": { "createLocationFromConnectedAccountListing": { "success": true, "locationId": 88277, "errors": null } }}O local é criado a partir dos dados do Google (nome, endereço, horários, categorias, telefone, atributos) e vinculado à listagem imediatamente. A listagem do Google permanece em IN_PROGRESS até que sua primeira atualização do local seja publicada nela. locationId é simplesmente o databaseId. Em caso de falha, success é false e errors contém um código como SY81067 (o id da listagem não foi encontrado). O campo é connectedAccountListingId; listingId é rejeitado pelo esquema.
Se a listagem pertencer a um local que você já tem, vincule-a em vez de criar uma duplicata.
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountListingId": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==" }}'Uma tentativa de vinculação malsucedida retorna success: false com um message, por exemplo, Listing record not found, ou uma observação de que a listagem já está conectada a outro local.
7. Como alternativa, conecte um único local
Quando você já sabe qual local o proprietário está conectando, pule a etapa de correspondência e crie um link vinculado a esse local. Em caso de sucesso, o proprietário retorna ao seu successUrl, e as credenciais são associadas somente a esse local.
curl -X POST https://listingsapi.com/api/v4/locations/oauth_connect_url \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "site": "GOOGLE", "successUrl": "https://app.example.com/locations/1800289/connected", "errorUrl": "https://app.example.com/locations/1800289/connect-failed" }}'A resposta é data.createConnectUrl com success, url e errors. O link é de uso único, então crie um novo a cada tentativa. Uma URL de redirecionamento relativa ou que não pode ser interpretada resulta em uma resposta success: true com um null url, então verifique url. Uma chave sem permissão para acessar esse local recebe uma resposta 403 com SY90003.
8. O que acontece em seguida
Depois que uma listagem é vinculada, a linha do Google Maps nas listagens premium do local sai de REQUIRING_ACTION, passa por IN_PROGRESS e chega a SYNCED com um listingUrl. O Google é adicionado automaticamente como fonte de avaliações, então as avaliações começam a chegar à lista de interações, e as atualizações que você faz no local são enviadas ao perfil.
Com uma URL de webhook configurada no painel, você não precisa fazer consultas periódicas. Cada payload contém location_id e data.connected_account_id.
Próximas etapas
- Crie um Google Business Profile: para um local que não tem uma listagem do Google com a qual estabelecer uma correspondência.
- Conecte páginas do Facebook: o mesmo fluxo para a outra plataforma de publicação que usa OAuth.
- Verifique o status das listagens e os links publicados e Busque avaliações: acompanhe a chegada dos resultados.
- Referências dos SDKs: Contas conectadas em Python e Contas conectadas em Node.
- Referência: Conecte uma conta do Google, Inicie a busca de correspondências de locais, Confirme as correspondências de conexão, Busque listagens de uma conta conectada, Crie um local a partir de uma listagem e o índice de Contas conectadas.