# AI People Also Ask — Complete documentation (dfaipaa)

> Overview AI People Also Ask (technical slug: dfaipaa) captures the questions your customers actually ask Google — the "People Also Ask" blocks — generates the answers with the AI of…

- Page: <https://www.datafirefly.com/en/documentation/dfaipaa/>
- Language: en
- Last updated: 2026-10-10
- Other languages: [fr](https://www.datafirefly.com/documentation/dfaipaa/index.md), [es](https://www.datafirefly.com/es/documentation/dfaipaa/index.md), [de](https://www.datafirefly.com/de/documentation/dfaipaa/index.md), [it](https://www.datafirefly.com/it/documentation/dfaipaa/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfaipaa/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfaipaa/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfaipaa/index.md)
- Index: <https://www.datafirefly.com/en/documentation/llms.txt>

## Overview

**AI People Also Ask** (technical slug: `dfaipaa`) captures the questions your customers actually ask Google — the "People Also Ask" blocks — generates the answers with the AI of your choice, and publishes a schema.org-marked FAQ on your product and category pages.

The module industrialises a complete four-step pipeline:

- **Scraping** — capture PAA questions on your target keywords via SerpApi, DataForSEO or manual entry.
- **AI generation** — write answers via Mistral, OpenAI or Anthropic, with configurable tone and brand voice.
- **Editorial workflow** — review, assign to products and categories, publish (manually or automatically).
- **Publishing** — accessible FAQ accordion on the storefront plus FAQPage JSON-LD for Google and generative engines.

**Note** — No `composer install` is required. A minimal PSR-4 autoloader is bundled with the module under the DataFirefly Dfaipaa namespace.

## Requirements

- PrestaShop 8.0.0 → 9.99.99
- PHP 8.1, 8.2 or 8.3
- MySQL 5.7 / MariaDB 10.4 or above
- An API key for at least one AI provider (Mistral, OpenAI or Anthropic)
- Optional: a SerpApi key or DataForSEO account to automate scraping
- Outbound HTTPS connections (cURL) allowed by your host

**Tip** — Manual entry mode lets you use the module without any scraping subscription: you enter the questions yourself and the AI handles the answers.

## Installation

1. Download the `dfaipaa.zip` archive from your DataFirefly account.
2. In the PrestaShop back-office, go to **Modules › Module Manager › Upload a module**.
3. Drag and drop the ZIP, wait for confirmation, then click **Install**.
4. A new **AI People Also Ask** menu appears in the left column, with three tabs: Configuration, Keywords, Questions.

Installation creates 4 tables (prefix `ps_dfaipaa_`), sets the default configuration values and installs 4 admin tabs (one parent plus three children) with labels localised in FR, EN, ES, DE, IT and NL.

**Important** — If your extraction tool skips `vendor/` folders, the autoloader will be missing and the module will throw a "Class not found" error. Extract with `unzip` or upload the ZIP directly through the back-office, which handles the tree correctly.

## Configuration — Scraping

**AI People Also Ask › Configuration** tab, first section.

| Field | Description | Default |
| --- | --- | --- |
| Provider | `serpapi`, `dataforseo` or `manual` | `serpapi` |
| API key | SerpApi key, or DataForSEO credentials as `login:password` | empty |
| Language | Two-letter ISO code used in the Google query | `fr` |
| Country | Two-letter ISO code of the target market | `FR` |
| Max questions per keyword | Limit per scraping operation | `8` |
| Refresh interval | In days, after which a keyword is considered stale | `30` |

### Getting a SerpApi key

Create an account on **serpapi.com**. The free plan gives 100 requests per month, roughly 100 scraped keywords. The key is in your dashboard under "Your Account". The module queries the Google search endpoint and reads the `related_questions` block from the response.

### Getting a DataForSEO account

Create an account on **dataforseo.com**. You receive a login / password pair to paste into the API key field as `login:password` (the module handles HTTP Basic authentication). DataForSEO bills per use, which suits larger volumes better. The module uses the SERP Google organic live advanced endpoint and extracts `people_also_ask` elements.

Location code mapping is built in for the following markets: FR, BE, CH, LU, CA, US, UK, IE, ES, PT, IT, DE, AT, NL, PL, BR and MX.

### Manual entry mode

Select `manual` to disable all external calls. You then add questions yourself from the Questions tab; AI generation remains fully functional.

## Configuration — Artificial intelligence

Second section of the Configuration tab.

| Field | Description | Default |
| --- | --- | --- |
| Provider | `mistral`, `openai` or `anthropic` | `mistral` |
| Model | Model identifier at the provider | `mistral-large-latest` |
| API key | Key for the selected provider | empty |
| Temperature | 0.0 to 1.0 — lower means more factual | `0.3` |
| Max tokens | Maximum length of the generated answer | `500` |
| Tone | Free text: expert, educational, sales-oriented, warm… | empty |
| Brand voice | Additional instructions to align the editorial style | empty |
| Auto-publish | Automatically publishes every generated answer | disabled |

### Recommended models

- **Mistral** — `mistral-large-latest` for quality, `mistral-small-latest` to cut costs at high volume.
- **OpenAI** — `gpt-4o-mini` offers excellent value; `gpt-4o` for demanding technical catalogues.
- **Anthropic** — `claude-sonnet-4-6` for nuanced, well-structured answers.

### Constraints enforced on the model

The module builds a strict system prompt, independent of the provider: 60 to 120-word answers, simple HTML only (paragraphs, bold, italic, lists), no markdown, no heading tags, no scripts. The entity context (product or category name and description, truncated to 1200 characters) and the source keyword are injected to anchor the answer. The original Google snippet is supplied as reference with an explicit instruction to rephrase — never to copy.

**Tip** — If a smaller model still returns markdown, lower the temperature to 0.2 and add "HTML only, no markdown" to the Brand voice field.

## Configuration — Display

Third section of the Configuration tab.

| Field | Description | Default |
| --- | --- | --- |
| Product mode | `tab` or `footer` (block at the bottom of the product page) | `tab` |
| Enable on products | Shows the FAQ on product pages | enabled |
| Enable on categories | Shows the FAQ at the bottom of category pages | enabled |
| Tab title | Localised label of the product tab | "Frequently asked questions" |
| Product title | Block title in footer mode | localised |
| Category title | Category block title | localised |
| Emit JSON-LD | Injects the FAQPage markup | enabled |

In `tab` mode, the module relies on PrestaShop's native `ProductExtraContent` mechanism: the FAQ appears as a tab alongside "Description" and "Product details", with no template override.

## Editorial workflow

### Step 1 — Add keywords

**Keywords** tab. Paste your list into the text area, one keyword per line, then submit. Duplicates are ignored automatically (adding is idempotent per keyword, language and shop).

Choose keywords that match purchase intent: "automatic coffee machine", "best coffee beans", "coffee maker maintenance". Avoid pure brand queries, which rarely trigger PAA blocks.

### Step 2 — Scrape

Two options:

- **Scrape** — individual button on each keyword row, handy for testing the configuration.
- **Scrape all stale** — processes in batches of 20 the keywords whose last capture exceeds the refresh interval.

Every captured question is stored with a uniqueness hash (question + language + shop): re-scraping a keyword never creates duplicates, it simply updates the last-capture date.

### Step 3 — Generate answers

**Questions** tab. Filter by `pending` status, select questions with the checkboxes, then run the **Generate** bulk action. An individual button is also available on each row.

The entity context is built from the question's first assignment. For better answers, assign the question to a product or category _before_ generating: the AI will then have the entity's name and description.

### Step 4 — Review and assign

Click a question to open the edit form. You can:

- fix the HTML answer in the rich editor;
- assign the question to one or more products and categories (N-to-N relation);
- reorder assignments to control the accordion display order;
- reject an off-topic question (status `rejected`, kept in the database but never displayed).

### Step 5 — Publish

Switch the status to `published`. The FAQ appears immediately on the storefront, along with its JSON-LD.

If **Auto-publish** is enabled in the configuration, steps 4 and 5 are merged: generation publishes directly. Convenient for a fully automated pipeline, best reserved for catalogues where human review is not critical.

## Question statuses

| Status | Meaning | Shown on storefront |
| --- | --- | --- |
| `pending` | Question captured, no AI answer yet | No |
| `generated` | Answer generated, awaiting validation | No |
| `published` | Validated and published | Yes |
| `rejected` | Manually discarded | No |

## Storefront display

The accordion is built on the native HTML `details` and `summary` elements, which guarantees:

- working keyboard navigation without JavaScript;
- content indexable by search engines even when collapsed;
- compatibility with every modern browser.

The first item is open by default. A lightweight CSS file is loaded and can be fully overridden from your child theme. All classes use the `dfaipaa-faq` prefix to avoid collisions.

### JavaScript events

The front-end script emits two custom events you can wire into your analytics tool:

```
document.addEventListener('dfaipaa:open', function (e) {
  // e.detail.question, e.detail.index, e.detail.type, e.detail.entityId
  gtag('event', 'faq_open', { question: e.detail.question });
});

document.addEventListener('dfaipaa:close', function (e) {
  console.log('FAQ closed:', e.detail.question);
});
```

The `views/js/front.js` file also contains a `SINGLE_OPEN` constant (`false` by default): set it to `true` to allow only one panel open at a time.

### Deep-linking

An anchor of the form `#dfaipaa-q-123` automatically opens the matching question and scrolls the page to it. Handy for sharing a specific answer from an email or a support ticket.

## FAQPage JSON-LD markup

On every product or category page load that has at least one published question, the module injects a JSON-LD block just before the document body closes (hook `displayBeforeBodyClosingTag`).

Emitted structure: a `FAQPage` node, a `mainEntity` array, and for each entry a `Question` node containing an `acceptedAnswer` of type `Answer`. The HTML content of answers is sanitised before emission: script and style tags along with event attributes are stripped.

**Tip** — Validate your markup with Google's Rich Results Test. Note that Google has restricted FAQ rich snippet display to government and health sites, but the markup remains valuable for generative engines (ChatGPT, Perplexity, Gemini) which actively consume it.

## Cron automation

A CLI script is provided to run the pipeline without manual intervention.

```
# Scrape stale keywords (20 max by default)
php modules/dfaipaa/cli/cron.php scrape --limit=20

# Generate AI answers for pending questions
php modules/dfaipaa/cli/cron.php generate --limit=10

# Chain scraping then generation
php modules/dfaipaa/cli/cron.php all --limit=20
```

Example crontab, nightly run at 3 am:

```
0 3 * * * cd /var/www/prestashop && php modules/dfaipaa/cli/cron.php all --limit=30 >> /var/log/dfaipaa.log 2>&1
```

**Important** — Size the `--limit` parameter against your API quotas. A batch of 30 keywords consumes 30 SerpApi requests; with the free plan (100 per month), a weekly run fits better than a daily one.

## Multilingual and multistore

Questions are indexed by `id_lang` and `id_shop`. In practice:

- the same keyword scraped in French and English produces two distinct sets of questions;
- answers are generated in the question's language, the prompt applying an explicit language directive (fr, en, es, de, it, nl, pt, pl);
- in multistore, one shop's questions and assignments never appear on another;
- display titles (tab, product, category) are stored as localised configuration.

## Troubleshooting

### Scraping returns no questions

- Check your quota at the provider: SerpApi silently cuts off beyond the free plan.
- Check language / country consistency: "fr" with "US" gives erratic results.
- Some keywords simply do not trigger a PAA block on Google. Test the query manually in a private browsing window.
- For DataForSEO, verify the `login:password` format of the API key field.

### The AI returns markdown instead of HTML

Lower the temperature to 0.2, or switch to a more capable model. The prompt already enforces strict HTML rules, but the lightest models may partially ignore them.

### The FAQ does not appear on the storefront

- Check that at least one question has the `published` status.
- Check that it is assigned to the entity being viewed (product or category).
- Check that display is enabled for that entity type in the configuration.
- Clear the Smarty cache from **Advanced parameters › Performance**.

### JSON-LD does not appear in the source code

Make sure the "Emit JSON-LD" option is enabled and that your theme actually calls the `displayBeforeBodyClosingTag` hook. Some third-party themes omit it: in that case add `{hook h='displayBeforeBodyClosingTag'}` before the body closes in your `layouts/layout-both-columns.tpl`.

### "Class not found" error after installation

The `vendor/` folder was not extracted. Reinstall the module by uploading the ZIP through the back-office rather than extracting it manually.

### Reading the operation logs

All operations (scraping, generation, publishing) are logged. To investigate:

```
SELECT * FROM ps_dfaipaa_log ORDER BY date_add DESC LIMIT 50;
```

## Uninstallation

From **Modules › Module Manager**, click **Uninstall**. The operation drops the 4 `ps_dfaipaa_*` tables, the 4 admin tabs and all `DFAIPAA_` configuration keys. Generated content is permanently lost: export your questions beforehand if you want to keep them.

## Technical reference

- **Technical slug**: `dfaipaa`
- **Namespace**: DataFirefly Dfaipaa (PSR-4, bundled autoloader)
- **Tables created**: `ps_dfaipaa_keyword`, `ps_dfaipaa_question`, `ps_dfaipaa_assignment`, `ps_dfaipaa_log`
- **Hooks used**: `displayHeader`, `displayProductExtraContent`, `displayFooterProduct`, `displayCategoryFooter`, `displayBeforeBodyClosingTag`, `actionFrontControllerSetMedia`, `actionAdminControllerSetMedia`, `actionProductUpdate`, `actionProductSave`, `actionCategoryUpdate`, `actionObjectProductDeleteAfter`, `actionObjectCategoryDeleteAfter`
- **Back-office tabs**: AdminDfaipaa (parent), AdminDfaipaaConfig, AdminDfaipaaKeywords, AdminDfaipaaQuestions
- **Configuration keys**: `DFAIPAA_SCRAPER_PROVIDER`, `DFAIPAA_SCRAPER_API_KEY`, `DFAIPAA_SCRAPER_LANG`, `DFAIPAA_SCRAPER_COUNTRY`, `DFAIPAA_SCRAPER_MAX_PER_KEYWORD`, `DFAIPAA_AI_PROVIDER`, `DFAIPAA_AI_MODEL`, `DFAIPAA_AI_API_KEY`, `DFAIPAA_AI_TEMPERATURE`, `DFAIPAA_AI_MAX_TOKENS`, `DFAIPAA_AI_TONE`, `DFAIPAA_AI_BRAND_VOICE`, `DFAIPAA_AUTO_PUBLISH`, `DFAIPAA_REFRESH_INTERVAL`, `DFAIPAA_PRODUCT_MODE`, `DFAIPAA_EMIT_JSONLD`, `DFAIPAA_TAB_TITLE`, `DFAIPAA_PRODUCT_TITLE`, `DFAIPAA_CATEGORY_TITLE`
- **CLI**: `modules/dfaipaa/cli/cron.php` (commands `scrape`, `generate`, `all`)
- **Front template**: `views/templates/hook/faq.tpl`

## GDPR compliance

The module neither collects nor stores any personal data: only keywords, questions, generated answers and technical operation logs are recorded. No cookie is set on the storefront. Calls to external APIs (scraping, AI) transmit only the keyword, the question and the product context — never customer data.

## Support

For any technical question, contact the DataFirefly team at **contact@datafirefly.com** or visit your customer area on [datafirefly.com](https://www.datafirefly.com/en/).
