# DataFirefly Indexing API: documentação

> Apresentação O DataFirefly Indexing API submete automaticamente os produtos, categorias e páginas CMS da sua loja PrestaShop aos dois canais de submissão direta existentes: IndexNow através do relé api.indexnow.org, que…

- Página: <https://www.datafirefly.com/pt/documentation/datafirefly-indexing-api-prestashop/>
- Idioma: pt
- Atualizado em: 2026-09-02
- Outros idiomas: [fr](https://www.datafirefly.com/documentation/datafirefly-indexing-api-prestashop/index.md), [en](https://www.datafirefly.com/en/documentation/datafirefly-indexing-api-prestashop/index.md), [es](https://www.datafirefly.com/es/documentation/datafirefly-indexing-api-prestashop/index.md), [de](https://www.datafirefly.com/de/documentation/datafirefly-indexing-api-prestashop/index.md), [it](https://www.datafirefly.com/it/documentation/datafirefly-indexing-api-prestashop/index.md), [pl](https://www.datafirefly.com/pl/documentation/datafirefly-indexing-api-prestashop/index.md), [nl](https://www.datafirefly.com/nl/documentation/datafirefly-indexing-api-prestashop/index.md)
- Índice: <https://www.datafirefly.com/pt/documentation/llms.txt>

## Apresentação

O DataFirefly Indexing API submete automaticamente os produtos, categorias e páginas CMS da sua loja PrestaShop aos dois canais de submissão direta existentes: **IndexNow** através do relé `api.indexnow.org`, que propaga para Bing, Yandex, Naver e Seznam numa única chamada, e **Google Indexing API** (autenticação por Service Account OAuth2, assinatura JWT RS256 nativa). O módulo liga-se aos hooks nativos do PrestaShop, coloca cada alteração numa fila de espera sem duplicados, e um CRON trata o lote de poucos em poucos minutos. Mantém um registo completo das submissões e um painel da taxa de aceitação.

**A ler antes de configurar o Google:** o Google restringe oficialmente a sua Indexing API às páginas com dados estruturados `JobPosting`, ou `BroadcastEvent` integrado num `VideoObject`. Uma página de produto ou de categoria não se enquadra em nenhum dos dois casos. A API aceita na mesma a submissão e responde 200, mas esse código significa apenas que a notificação foi recebida, não que o URL será rastreado ou indexado. Para um catálogo de e-commerce, **o IndexNow é o canal que produz um efeito mensurável**: configure-o em primeiro lugar e trate o Google como um canal secundário registado.

**Em resumo:** os seus novos produtos e alterações de páginas são enviados para Bing, Yandex, Naver e Seznam nos minutos seguintes, sem subscrição de terceiros nem comissão por URL. Do lado do Google, a submissão acelera a descoberta sem garantia de indexação.

## Pré-requisitos

- PrestaShop 8.0 a 8.99, ou PrestaShop 9.x
- PHP 7.4 a 8.3
- Extensões PHP `openssl` (para a assinatura JWT RS256 do Google) e `curl` (para os pedidos HTTP)
- Um CRON de sistema ou um serviço de CRON externo para chamar o tratamento da fila de espera a cada 5 a 15 minutos
- **Opcional, para o Google:** uma conta Google Cloud com um projeto onde ativar a Indexing API e criar um Service Account, e uma propriedade Search Console verificada para o seu domínio

## Instalação

### Passo 1: transferência

Transfira o ZIP `dfindexingapi-1.0.0.zip` a partir da sua conta DataFirefly após a compra.

### Passo 2: instalação através do back-office

1. Inicie sessão no back-office do PrestaShop
2. Aceda a **Módulos › Gestor de módulos › Instalar um módulo**
3. Clique em **Selecionar um ficheiro** e escolha o ZIP transferido
4. Confirme. O PrestaShop descomprime e instala o módulo
5. Uma vez instalado, clique em **Configurar**

### Passo 3: verificações pós-instalação

Na instalação, o módulo cria automaticamente:

- As duas tabelas SQL `ps_df_indexapi_queue` (fila de espera) e `ps_df_indexapi_log` (registo)
- Uma chave IndexNow alfanumérica de 32 caracteres
- Um token CRON aleatório de 32 caracteres
- 5 separadores no menu de administração: pai **DataFirefly Indexing API**, depois **Painel**, **Fila de espera**, **Registo**, **Configuração**

Abra o separador **Configuração** para passar ao passo seguinte.

## Configuração do IndexNow

O IndexNow é o canal a configurar em primeiro lugar: sem Service Account, sem OAuth, sem quota e sem nenhuma restrição quanto ao tipo de página. Apenas uma chave a publicar na raiz do seu domínio.

### Compreender o IndexNow

O IndexNow é um protocolo aberto impulsionado pelo Microsoft Bing e pelo Yandex em 2021, ao qual se juntaram desde então o Naver e o Seznam. Gera uma chave alfanumérica, publica-a na raiz do seu domínio sob a forma de um ficheiro acessível publicamente, e chama `api.indexnow.org` com uma lista de URLs. O servidor verifica a chave lendo o ficheiro do seu domínio e propaga depois os URLs aos motores participantes. Páginas de produto, categorias e páginas CMS estão no seu âmbito normal.

### Método 1: reescrita .htaccess (recomendado)

É o método mais simples: o próprio módulo serve o conteúdo do ficheiro de chave através de um controlador front-office, e uma regra `.htaccess` na raiz da sua loja reescreve o pedido para esse controlador.

1. Na configuração do módulo, abra o separador **IndexNow**
2. Assinale **Ativar IndexNow**
3. Verifique o campo **Anfitrião**, que deve corresponder ao domínio da sua loja sem o protocolo (por exemplo `a-minha-loja.pt`)
4. Guarde
5. Copie o excerto `.htaccess` apresentado na página de configuração, gerado dinamicamente com a sua chave atual
6. Cole esse excerto no topo do ficheiro `.htaccess` na raiz do PrestaShop, logo a seguir ao bloco `RewriteEngine on`
7. Clique em **Testar IndexNow** na configuração: o módulo chama o URL do ficheiro de chave no seu domínio e verifica que devolve o conteúdo esperado em `text/plain`

### Método 2: ficheiro físico

Se não puder modificar o `.htaccess`, crie manualmente um ficheiro físico na raiz do domínio.

1. Obtenha a sua chave IndexNow na configuração do módulo (campo **Chave IndexNow**)
2. Crie um ficheiro cujo nome seja exatamente **a chave + .txt** (por exemplo `a1b2c3d4e5f6.txt`) na raiz do seu domínio
3. O conteúdo do ficheiro deve ser apenas a própria chave, sem quebra de linha
4. Verifique que `https://o-seu-dominio.pt/a1b2c3d4e5f6.txt` devolve a chave em `text/plain`
5. Clique em **Testar IndexNow**

Pode regenerar a chave IndexNow a qualquer momento a partir da configuração (botão **Regenerar a chave**). Nesse caso, não se esqueça de atualizar o excerto `.htaccess` ou o ficheiro físico em conformidade.

## Configuração da Google Indexing API

**Âmbito oficial:** esta API é reservada pelo Google às páginas `JobPosting` ou `BroadcastEvent` num `VideoObject`. Num catálogo de produtos, continua a ser utilizável tecnicamente (a API responde 200 e o módulo regista a resposta), mas o Google decide sozinho o rastreio e a indexação. Esta secção é facultativa: o módulo funciona perfeitamente apenas com o IndexNow.

A API Google Indexing exige um Service Account Google Cloud. O procedimento demora cerca de 5 minutos.

### Passo 1: criar um projeto Google Cloud

1. Aceda a [console.cloud.google.com](https://console.cloud.google.com) e inicie sessão
2. No topo, clique no seletor de projeto e depois em **Novo projeto**
3. Dê-lhe um nome (por exemplo _Indexing API Loja_) e crie-o
4. Selecione o projeto acabado de criar

### Passo 2: ativar a Indexing API

1. No menu da esquerda, aceda a **APIs e serviços › Biblioteca**
2. Pesquise _Indexing API_
3. Clique em **Ativar**

### Passo 3: criar um Service Account

1. Aceda a **APIs e serviços › Credenciais**
2. Clique em **Criar credenciais › Conta de serviço**
3. Dê-lhe um nome (por exemplo _indexing-api-prestashop_)
4. Não é necessário nenhum papel IAM: passe ao passo seguinte e finalize a criação
5. Na lista de contas de serviço, clique na conta criada
6. Separador **Chaves › Adicionar uma chave › Criar uma nova chave**
7. Formato **JSON**. Transfira e guarde o ficheiro, não poderá ser recuperado depois

**Segurança:** o ficheiro JSON contém a chave privada do Service Account. Nunca o partilhe publicamente nem o inclua num repositório Git.

### Passo 4: adicionar o Service Account à Search Console

1. Copie o e-mail do Service Account (formato `nome@projeto.iam.gserviceaccount.com`) a partir do Google Cloud
2. Aceda à [Google Search Console](https://search.google.com/search-console)
3. Selecione a sua propriedade (o domínio da sua loja)
4. Aceda a **Definições › Utilizadores e permissões**
5. Clique em **Adicionar utilizador**, cole o e-mail do Service Account e selecione o papel **Proprietário**
6. Confirme

O papel **Proprietário** é exigido pela Google Indexing API. O papel **Leitor** ou **Permissão total** não é suficiente: a API devolverá `403 Permission denied`.

### Passo 5: colar o JSON no módulo

1. Abra o ficheiro JSON transferido num editor de texto
2. Copie todo o seu conteúdo
3. Na configuração do módulo, secção **Google Indexing API**, assinale **Ativar Google Indexing API**
4. Cole o JSON completo no campo **Service Account JSON**
5. Guarde

### Passo 6: testar a ligação

Clique no botão **Testar Google** na página de configuração. O módulo assina um JWT RS256, troca-o por um token OAuth2 e apresenta o resultado. Se tudo estiver correto, verá uma mensagem verde _Autenticação OK_. Este teste valida a autenticação, não a consideração dos seus URLs pelo Google.

## Configuração do CRON

O CRON é o elemento que faz correr o tratamento da fila de espera. Sem um CRON chamado regularmente, as submissões acumulam-se mas nunca partem.

### Ação process: tratamento da fila de espera

A chamar **a cada 5 a 15 minutos**. O módulo trata um lote configurável (por defeito 50 jobs) respeitando a desduplicação e os filtros de indexação, e atualiza depois o registo e a fila.

O URL exato é apresentado na configuração. Tem este aspeto:

```
https://o-seu-dominio.pt/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=process&token=O_SEU_TOKEN
```

### Ação purge: limpeza do registo

A chamar **uma vez por dia**. O módulo elimina os jobs e registos tratados para além da retenção configurada (por defeito 30 dias).

```
https://o-seu-dominio.pt/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=purge&token=O_SEU_TOKEN
```

### Ação key: ficheiro de chave IndexNow

Utilizada apenas pela reescrita `.htaccess`. Nunca chama este URL manualmente.

### Configurar o seu CRON de sistema

Em Linux/cPanel, adicione duas linhas ao crontab:

```
# A cada 10 minutos: tratamento da fila de espera
*/10 * * * * curl -s "https://o-seu-dominio.pt/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=process&token=O_SEU_TOKEN" > /dev/null

# Uma vez por dia às 3h: limpeza do registo
0 3 * * * curl -s "https://o-seu-dominio.pt/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=purge&token=O_SEU_TOKEN" > /dev/null
```

### Segurança do token CRON

O token é um segredo de 32 caracteres gerado na instalação. Sem o token correto no parâmetro `token=`, o controlador devolve HTTP 403. Pode regenerar o token a qualquer momento a partir da configuração (botão **Regenerar o token CRON**), lembrando-se nesse caso de atualizar as suas linhas de crontab com o novo token.

## O Painel

O separador **Painel** é a sua vista geral em tempo real. Mede a saúde técnica das chamadas à API, não a indexação efetiva das suas páginas.

### Contadores da fila de espera

Cinco cartões no topo da página:

- **Pendentes**: jobs criados mas ainda não tratados
- **Em curso**: jobs bloqueados em tratamento por um CRON ativo
- **Submetidos**: jobs tratados com sucesso (acumulado histórico não limpo)
- **Erro**: jobs que falharam após N tentativas máximas
- **Ignorados**: jobs criados mas ignorados por um filtro (por exemplo URL_DELETED no IndexNow)

### Diagnóstico dos fornecedores

Dois cartões mostram o estado de configuração:

- **Google Indexing API**: ativo, mal configurado ou desativado. Indica se o JSON do Service Account está presente e é válido
- **IndexNow**: ativo, mal configurado ou desativado. Indica se a chave e o anfitrião estão configurados

### Taxa de aceitação a 30 dias

Tabela cruzada fornecedor × estado nos últimos 30 dias, com coloração semântica: verde acima de 90%, laranja entre 60 e 90%, vermelho abaixo. Se o Google cair abaixo de 90%, é geralmente sinal de que excedeu a quota ou de que há URLs que deixaram de estar acessíveis. Uma taxa de aceitação de 100% significa que as suas notificações foram recebidas, não que os URLs foram indexados.

### Gráfico das submissões diárias

Gráfico Chart.js sobrepondo duas curvas por dia: total submetido e total aceite. Útil para detetar rapidamente quedas ou picos anormais.

## A Fila de espera

O separador **Fila de espera** lista todos os jobs (pending, processing, submitted, error, skipped) com filtros nativos do PrestaShop por loja, tipo de objeto, ID, fornecedor, estado, data.

### Estados dos jobs

- **pending**: criado, à espera de tratamento pelo próximo CRON
- **processing**: bloqueado por um CRON ativo (transição lógica para evitar o tratamento duplo em paralelo)
- **submitted**: submissão à API bem-sucedida. O contador de tentativas é congelado
- **error**: todas as tentativas falharam. Continua consultável com a mensagem de erro exata devolvida pela API
- **skipped**: criado e depois ignorado (por exemplo URL_DELETED no IndexNow, ou filtro desativado)

### Ações individuais

Cada linha propõe:

- **Relançar**: volta a colocar o job em pending e reinicia o contador de tentativas
- **Eliminar**: apaga o job da fila

### Ações em massa

Botões no topo da lista:

- **Relançar todos os jobs em erro**: volta a colocar em pending todos os jobs com estado error
- **Limpar os jobs tratados**: elimina todos os submitted/skipped, qualquer que seja a sua idade

## O Registo

O separador **Registo** lista cada submissão individual realizada: fornecedor, tipo, ID do objeto, URL submetido, ação (URL_UPDATED ou URL_DELETED), código HTTP devolvido, indicador aceite/recusado, mensagem completa da resposta e data. Filtrável, ordenável, exportável em CSV através do HelperList padrão do PrestaShop.

Se o Google recusar um URL com um código HTTP 400 e uma mensagem _Unable to fetch URL_, é geralmente porque o URL não está acessível publicamente (modo de manutenção ativo, robots.txt que bloqueia, redirecionamento em ciclo, etc.). Verifique o URL num navegador em modo de navegação privada.

## Filtros de indexação

Na configuração, pode ativar ou desativar de forma independente três tipos de objetos:

- **Produtos**: submissão na criação, modificação, eliminação, desativação
- **Categorias**: submissão na criação, modificação, eliminação. A raiz das categorias (ID 1 e 2) é ignorada por segurança
- **Páginas CMS**: submissão na criação, modificação, eliminação

Desativar um filtro interrompe imediatamente o enfileiramento para esse tipo, mas não limpa a fila existente. Num catálogo grande, restringir os filtros do lado do Google é o reflexo certo para não esgotar a quota de 200 URLs por dia.

## Multiloja

O módulo é nativamente multiloja. A configuração (chaves Google, chave IndexNow, anfitrião, ativações) é independente por subloja. Os jobs e os registos são delimitados por `id_shop`: um mesmo produto em duas sublojas gera dois jobs distintos com os seus próprios URLs canónicos.

Para configurar cada subloja de forma independente, use o seletor multiloja no topo da administração antes de abrir a configuração.

## Hooks PrestaShop escutados

O módulo regista os seguintes hooks na instalação:

- `actionProductSave`: criação ou modificação de um produto. Se ativo, enfileira URL_UPDATED; caso contrário URL_DELETED
- `actionProductDelete`: eliminação definitiva de um produto. Enfileira URL_DELETED
- `actionObjectCmsAddAfter`: criação de uma página CMS
- `actionObjectCmsUpdateAfter`: modificação de uma página CMS
- `actionObjectCmsDeleteAfter`: eliminação de uma página CMS
- `actionCategoryAdd`: criação de uma categoria
- `actionCategoryUpdate`: modificação de uma categoria
- `actionCategoryDelete`: eliminação de uma categoria
- `displayBackOfficeHeader`: injeção de um fragmento CSS para o estilo do painel

Cada hook constrói o URL canónico através do objeto `Link` oficial do PrestaShop, o que respeita as suas preferências de **URL amigáveis** e os prefixos de idioma multilingue.

## Resolução de problemas

### O teste Google falha com um código 401

A autenticação falhou. Verifique que:

- O JSON do Service Account colado está completo e bem formado
- A Indexing API está ativada no Google Cloud (biblioteca)
- O relógio de sistema do servidor está correto: um desvio superior a 5 minutos invalida o JWT

### O teste Google falha com um código 403

A autenticação é bem-sucedida mas o Google recusa o pedido. Causa habitual: o Service Account não foi adicionado como **Proprietário** da propriedade Search Console. Volte a verificar o passo 4 da configuração Google.

### O teste IndexNow falha

O servidor api.indexnow.org não conseguiu ler o ficheiro de chave no seu domínio. Causas possíveis:

- O excerto `.htaccess` não foi colado, ou foi colado no sítio errado (deve estar depois de `RewriteEngine on`)
- O ficheiro físico não foi criado, ou não tem o nome correto (deve ser exatamente _a chave + .txt_)
- O conteúdo do ficheiro não corresponde à chave (erro de digitação, quebra de linha adicional)
- O servidor web serve o ficheiro com o Content-Type errado (deve ser `text/plain`)
- A firewall ou o CDN bloqueia os pedidos do robô IndexNow

Abra `https://o-seu-dominio.pt/A_SUA_CHAVE.txt` num navegador em modo de navegação privada: deve ver apenas a chave em texto simples.

### Há jobs que ficam bloqueados no estado processing

Isso significa que um CRON bloqueou os jobs mas nunca libertou o lock (por exemplo, o processo foi terminado por um timeout PHP). Pode desbloqueá-los manualmente através do phpMyAdmin:

```
UPDATE ps_df_indexapi_queue SET status = 'pending', attempts = 0 WHERE status = 'processing';
```

Se o problema se repetir regularmente, aumente o `max_execution_time` PHP do seu alojamento, ou reduza o tamanho do lote na configuração do módulo.

### A quota Google foi excedida

O Google responde com um código 429 ou uma mensagem _Quota exceeded_. A quota por defeito é de 200 URLs por dia por Service Account.

**Não conte com um aumento de quota.** O Google propõe de facto um formulário de pedido, mas a aprovação está condicionada ao uso efetivo da marcação `JobPosting` ou `BroadcastEvent` no site. Um catálogo de e-commerce não cumpre esse critério: o pedido será recusado. Trate os 200 URLs por dia como um teto fixo.

Três opções realistas:

- Esperar 24h, uma vez que a quota é reposta diariamente
- Restringir os filtros de indexação do lado do Google aos tipos que contam realmente para si (por exemplo apenas produtos, desativando categorias e CMS)
- Criar um segundo Service Account e alternar, tendo cada Service Account a sua própria quota de 200 URLs por dia

Lembrete: o IndexNow não tem quota. Se o volume for a sua principal restrição, é o canal em que se deve apoiar.

### Reinicialização completa

Para recomeçar do zero (útil em caso de migração ou de problema complexo):

1. Desinstalar o módulo em Módulos › Gestor de módulos
2. Reinstalar: as tabelas são recriadas, a chave IndexNow e o token CRON são regenerados
3. Reconfigurar o Google e o IndexNow
4. Atualizar o excerto `.htaccess` com a nova chave
5. Atualizar as linhas de crontab com o novo token

A desinstalação elimina a fila de espera e o registo, mas não elimina as submissões já efetuadas do lado do Google ou do IndexNow: permanecem nos respetivos históricos.

## Limitações conhecidas

- **Google Indexing API oficialmente limitada** às páginas `JobPosting` ou `BroadcastEvent` num `VideoObject`. A API aceita os outros tipos e responde 200, mas esse código atesta apenas a receção da notificação. Para um catálogo de produtos, o IndexNow é o canal principal e o Google um complemento registado
- **Quota Google limitada** a 200 URLs por dia por Service Account, sem aumento possível na prática para um e-commerce (ver a secção Resolução de problemas)
- **O IndexNow não gere URL_DELETED**: o protocolo considera que um 404 ou 410 no URL é a forma correta de sinalizar uma eliminação. O módulo ignora portanto os jobs IndexNow em URL_DELETED (o Google, esse, submete-os)
- **Variantes de produto não submetidas individualmente**: o URL canónico do produto principal é suficiente, o Google consolida naturalmente as variantes
- **Raiz das categorias ignorada** (ID 1 e 2) para evitar submeter URLs não relevantes
- **O módulo não substitui um sitemap XML**: o sitemap continua a ser o canal de descoberta oficial e deve manter-se limpo e atualizado. A submissão direta acrescenta-se por cima, não o substitui

## Suporte

Para qualquer questão técnica: [support@datafirefly.com](mailto:support@datafirefly.com), resposta em 24h úteis em francês ou inglês. Incluído durante 12 meses após a compra.
