# Review Insights: AI Sentiment, Themes & Replies (GDPR) (`ifritdmc/review-insights-own-reviews-gdpr`) Actor

Analyze YOUR OWN reviews from a CSV export or official APIs (Google Business Profile, Google Play, App Store Connect, Trustpilot). Sentiment, themes, top complaints, draft replies and a PDF report. GDPR-first, no scraping.

- **URL**: https://apify.com/ifritdmc/review-insights-own-reviews-gdpr.md
- **Developed by:** [Alexis Hernández](https://apify.com/ifritdmc) (community)
- **Categories:** AI, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 review analyzeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Review Insights: AI Sentiment Analysis, Themes, Top Complaints & Reply Drafts for YOUR Reviews (GDPR)

**Analyze your own customer reviews from Google Business Profile, Google Play, the App Store, Trustpilot or any CSV export. Get sentiment per review, recurring themes, your top complaints, ready-to-edit reply drafts and a PDF report. Built for GDPR from day one, with no scraping.**

[🇪🇸 Versión en español más abajo](#-análisis-de-reseñas-propias-con-ia-sentimiento-temas-quejas-y-respuestas-rgpd)

### What does Review Insights do?

- 📥 **Imports your reviews** from:
  - a **CSV export** from any platform, CRM, survey tool or Excel. Columns are auto-detected (EN/ES headers, `,` `;` tab separators, UTF-8/Windows-1252), and you can map them yourself.
  - the **Google Business Profile API**, for your Google Maps reviews
  - the **Google Play Developer API**, for your Android app reviews
  - the **App Store Connect API**, for your iOS app customer reviews
  - the **Trustpilot Business API**, private or public
- 🧠 **Analyzes each review**: sentiment (positive / neutral / mixed / negative, plus a −1…1 score), themes (service, waiting time, price, quality, delivery, bugs, UX, support…), the main complaint and a **draft owner reply** in the review's language.
- 📊 **Aggregates**: average rating, net sentiment, theme breakdown, **top complaints with example quotes**.
- 📄 **PDF report** (English or Spanish) to share with your team or client.
- 🤖 **AI or no AI**: use Apify's built-in OpenRouter (no key needed, billed to your Apify account), your own OpenRouter/OpenAI key, or any OpenAI-compatible endpoint. With no AI, a free deterministic engine handles it (a bilingual sentiment lexicon plus keyword theme clustering), and the run also falls back to it if the AI call fails.

> ℹ️ **Note:** the official API connectors (Google Business Profile, Google Play, App Store Connect, Trustpilot) are new. **CSV import is the most tested path**: if a connector gives you trouble, export your reviews to CSV and open an issue.

### Who is it for?

Restaurants, hotels, clinics, shops, franchises, SaaS and mobile app teams, and the **marketing agencies** that manage reviews and reputation for them. It's useful for weekly review monitoring, customer feedback analysis, VoC (voice of customer) and app store review analysis.

### GDPR & privacy by design

- **Your own data only**: it works with your exports or official APIs using credentials you control. **No scraping.**
- **Pseudonymization**: author names, emails, phone numbers, IBANs and URLs are replaced by tokens (`[PERSON_1]`) **before** any text goes to an AI model. The mapping exists only in memory during the run.
- **Re-identification is opt-in** and happens locally, in your dataset and report only.
- **Not used for training**: OpenRouter requests are sent with `data_collection: deny`. Choose a provider whose terms also exclude training.
- **Secrets never persist**: all credentials are Apify secret inputs (encrypted). At run end the Actor **deletes the INPUT record and all intermediate data**, drops the request queue and deletes the uploaded CSV. Only the dataset, the `OUTPUT` summary and (optionally) `REPORT.pdf` remain.
- A template **Data Processing Agreement (GDPR art. 28)** in English and Spanish is included in `docs/DPA-template.md`.

### How much does it cost?

Pay per event, with no subscription:

| Event | Price |
|---|---|
| Review analyzed | **$0.003** ($3 per 1,000 reviews) |
| PDF report | **$0.10** per run |
| Actor start | $0.00005 |

Example: 500 reviews + PDF = **$1.60**. Reviews with only a star rating are skipped and not charged. If you use your own AI key, the AI usage is billed by your provider.

### How to use it

1. **CSV**: upload your export (or paste it) and click Start. Optional: set the *Column mapping*, e.g. `{"text": "Comentario", "rating": "Nota"}`.
2. **Google Business Profile**: add `accounts/{id}/locations/{id}` plus an OAuth access token, or client ID, secret and refresh token, with the `business.manage` scope. Your Google Cloud project must have Business Profile API access.
3. **Google Play**: add the package name and a service account JSON key invited in Play Console. *The API only returns reviews from the last 7 days*, so export older ones to CSV.
4. **App Store Connect**: add the app ID, issuer ID, key ID and `.p8` private key.
5. **Trustpilot**: add the business unit ID plus API key, secret and business user login (private API), or only the API key (public endpoint).
6. Pick an AI provider (or *None*), the report language and Start.

### Output

**Dataset** (one item per review):

```json
{"source":"google_business","rating":2,"sentiment":"negative","sentimentScore":-0.62,
 "themes":["wait_speed","service_staff"],"complaint":"Waited 45 minutes and the food was cold.",
 "draftReply":"Hi there, we're sorry to hear about your experience with waiting time & speed...","alreadyReplied":false}
```

**OUTPUT** (summary JSON): average rating, net sentiment, sentiment distribution, themes, top complaints and per-source errors. **REPORT.pdf**: the PDF report.

### FAQ

- **Can I analyze a competitor's reviews?** No. This Actor is for reviews of businesses you own or manage, through official APIs or your exports.
- **Does it post replies?** No, it only drafts them. Review them before posting.
- **Languages?** AI mode handles any language. The free lexicon engine supports English and Spanish.

***

## 🇪🇸 Análisis de reseñas propias con IA: sentimiento, temas, quejas y respuestas (RGPD)

**Analiza las reseñas de tu negocio desde Google Business Profile, Google Play, App Store, Trustpilot o un CSV exportado. Obtén el sentimiento de cada reseña, los temas recurrentes, tus principales quejas, borradores de respuesta y un informe PDF. Cumple el RGPD desde el diseño y no usa scraping.**

### ¿Qué hace?

- Importa tus reseñas desde un **CSV** (con detección automática de columnas en español e inglés y separador `;` o `,`) o desde las **APIs oficiales**: Google Business Profile (reseñas de Google Maps), Google Play Developer API, App Store Connect API y Trustpilot Business API.
- Para cada reseña calcula el **sentimiento**, los **temas** (atención, esperas, precio, calidad, envíos, errores de la app…), la **queja principal** y un **borrador de respuesta** en el idioma de la reseña.
- Agrega los resultados: valoración media, sentimiento neto, temas y **principales quejas con ejemplos**.
- Genera un **informe PDF** en español o inglés, listo para tu equipo o tu cliente.
- Puedes usar IA (OpenRouter de Apify sin clave, tu clave de OpenRouter u OpenAI, o un endpoint compatible) o el **motor gratuito sin IA** (léxico de sentimiento ES/EN y agrupación por palabras clave).

> ℹ️ **Nota:** los conectores de API oficiales son nuevos. **La importación por CSV es la vía más probada**: si un conector te da problemas, exporta las reseñas a CSV y abre una incidencia.

### Ideal para

Restaurantes, hoteles, clínicas, tiendas, franquicias, apps y SaaS, y **agencias de marketing** que gestionan la reputación online de sus clientes.

### Privacidad y RGPD

- Solo trabaja con **datos propios**, mediante exportaciones o APIs oficiales con tus credenciales. **Sin scraping.**
- **Seudonimización**: nombres, correos, teléfonos, IBAN y URL se sustituyen por códigos **antes** de enviar el texto a la IA.
- La **reidentificación es opcional** y se hace solo en local, en tus resultados.
- **Tus datos no se usan para entrenar modelos** (en OpenRouter se envía `data_collection: deny`).
- Las **claves no se guardan**: son entradas secretas cifradas y, al terminar, el Actor **borra el INPUT y todos los datos intermedios**, además del CSV subido.
- Incluye una **plantilla de contrato de encargo del tratamiento (art. 28 RGPD)** en español e inglés: `docs/DPA-template.md`.

### Precio

Pago por uso: **0,003 $ por reseña analizada** (3 $ por cada 1.000), **0,10 $ por informe PDF** y 0,00005 $ por arranque. Por ejemplo, 500 reseñas con PDF salen por 1,60 $. Las reseñas que solo tienen estrellas no se cobran.

### Uso rápido

1. Sube tu CSV o pégalo, y pulsa Start. Si hace falta, indica el *Column mapping*, por ejemplo `{"text": "Comentario", "rating": "Nota"}`.
2. Para usar las APIs, rellena la sección de cada plataforma. Ten en cuenta que Google Play solo devuelve las reseñas de los últimos 7 días.
3. Elige el proveedor de IA (o *Ninguno*) y el idioma del informe.

### Preguntas frecuentes

- **¿Sirve para reseñas de la competencia?** No. Es solo para reseñas de negocios propios o gestionados.
- **¿Publica las respuestas?** No, solo las redacta para que las revises.

# Actor input Schema

## `businessName` (type: `string`):

Shown on the PDF report title. Also used as default location for CSV rows.

## `csvFile` (type: `string`):

Upload the CSV you exported from your review platform or CRM (Google, Trustpilot, App Store, Play Console, Excel...). Columns are auto-detected; override with Column mapping. Deleted from Apify storage at run end by default.

## `csvText` (type: `string`):

Alternative to upload: paste CSV text directly. Comma, semicolon, tab or pipe separated; UTF-8 or Windows-1252.

## `columnMapping` (type: `object`):

Optional. Map canonical fields to your CSV headers, e.g. {"text": "Comentario", "rating": "Nota", "author": "Cliente", "date": "Fecha"}. Fields: text, rating, title, author, author_email, date, id, language, location, existing_reply.

## `ratingScale` (type: `integer`):

Maximum value of the CSV rating column if it is not out of 5 (e.g. 10 for NPS-style 0-10 scores). Values like '8/10' are detected automatically.

## `gbpLocations` (type: `array`):

Your location resource names: accounts/{accountId}/locations/{locationId}. Requires a Google Cloud project with Business Profile API access approved by Google.

## `gbpAccessToken` (type: `string`):

OAuth 2.0 access token with scope https://www.googleapis.com/auth/business.manage. Short-lived; or use client ID/secret + refresh token below. Secret: encrypted, used only during this run and deleted at the end.

## `googleClientId` (type: `string`):

OAuth client ID from your Google Cloud project (used with client secret + refresh token for Business Profile).

## `googleClientSecret` (type: `string`):

OAuth client secret. Secret: encrypted, used only during this run.

## `googleRefreshToken` (type: `string`):

Refresh token for the Google account that manages the locations. Secret: encrypted, used only during this run.

## `playPackageNames` (type: `array`):

Your app package names, e.g. com.example.app. Note: the Play Developer API only returns reviews from the last 7 days (export older ones to CSV from Play Console).

## `playServiceAccountJson` (type: `string`):

Full JSON key of a service account invited in Play Console with 'Reply to reviews' (view) permission. Secret: encrypted, used only during this run.

## `playAccessToken` (type: `string`):

Alternative to the service account: an OAuth token with scope androidpublisher. Secret.

## `ascAppIds` (type: `array`):

Numeric Apple app IDs (App Store Connect > App Information > Apple ID).

## `ascIssuerId` (type: `string`):

Issuer ID from App Store Connect > Users and Access > Integrations > App Store Connect API.

## `ascKeyId` (type: `string`):

Key ID of your API key (role Customer Support or higher).

## `ascPrivateKey` (type: `string`):

Contents of the AuthKey_XXXX.p8 file, including BEGIN/END lines. Secret: encrypted, used only during this run.

## `tpBusinessUnitId` (type: `string`):

Your business unit ID (Trustpilot Business > Integrations > API).

## `tpApiKey` (type: `string`):

API key of your Trustpilot application. With only the key, the public reviews endpoint is used. Secret: never stored beyond the run.

## `tpApiSecret` (type: `string`):

API secret (needed for the private Business API with OAuth). Secret.

## `tpUsername` (type: `string`):

Trustpilot Business login used for the OAuth password grant (private API). Secret.

## `tpPassword` (type: `string`):

Password for the OAuth password grant. Secret: encrypted, used only during this run and deleted at the end.

## `tpAccessToken` (type: `string`):

Alternative: an existing OAuth access token for the private Business API. Secret.

## `maxReviews` (type: `integer`):

Maximum number of reviews to analyze in total (you pay per review analyzed).

## `sinceDate` (type: `string`):

Only analyze reviews created on/after this date (YYYY-MM-DD). API sources only.

## `lastDays` (type: `integer`):

Alternative to 'Only reviews since': analyze reviews from the last N days (API sources).

## `llmProvider` (type: `string`):

Which AI model analyzes the text. Only pseudonymized text is sent. 'None' uses a built-in EN/ES lexicon + keyword clustering. If the AI call fails, the run falls back to the lexicon automatically.

## `llmApiKey` (type: `string`):

Your API key for OpenRouter/OpenAI/custom provider. Secret: encrypted, used only during this run. Not needed for 'Apify OpenRouter'.

## `llmModel` (type: `string`):

Model name, e.g. openai/gpt-4o-mini (OpenRouter) or gpt-4o-mini (OpenAI). Leave empty for a cheap default.

## `llmBaseUrl` (type: `string`):

Only for 'Custom': base URL of an OpenAI-compatible API (e.g. https://my-llm.example.com/v1).

## `businessContext` (type: `string`):

Optional one-liner to tailor replies, e.g. 'Family Italian restaurant in Madrid' or 'Budgeting app for freelancers'. Do not include personal data.

## `replyTone` (type: `string`):

Tone for draft replies (AI mode), e.g. 'warm, professional' or 'cercano y breve'.

## `reportLanguage` (type: `string`):

Language of the PDF report headings.

## `generatePdf` (type: `boolean`):

Create REPORT.pdf in the key-value store (charged once per run).

## `includeReviewText` (type: `boolean`):

Include the review title/text in each dataset item. Emails and phone numbers inside the text are masked unless names are re-identified.

## `includeAuthorNames` (type: `boolean`):

GDPR opt-in. When on, author names are restored LOCALLY in the dataset/report and replies greet the author by name. They are never sent to the AI model either way.

## `keepReport` (type: `boolean`):

At run end, all input and intermediate records (including INPUT with your secrets) are deleted. Turn off to also delete the PDF report (only the dataset and OUTPUT summary remain).

## `deleteUploadedCsv` (type: `boolean`):

Delete the uploaded CSV file from Apify storage when the run ends.

## `skipEmpty` (type: `boolean`):

Skip reviews without any text (star rating only); they are not analyzed or charged.

## Actor input object example

```json
{
  "csvText": "author,rating,date,review\nAna García,5,2026-09-01,El personal muy amable y la comida deliciosa.\nJohn Smith,2,2026-09-03,Waited 40 minutes and the food was cold. Very disappointed.\nLaura P.,3,2026-09-05,Buena comida pero la espera fue demasiado larga y el precio algo caro.",
  "columnMapping": {},
  "maxReviews": 1000,
  "llmProvider": "none",
  "replyTone": "warm, professional",
  "reportLanguage": "en",
  "generatePdf": true,
  "includeReviewText": true,
  "includeAuthorNames": false,
  "keepReport": true,
  "deleteUploadedCsv": true,
  "skipEmpty": true
}
```

# Actor output Schema

## `reviews` (type: `string`):

One item per review: source, rating, sentiment, themes, complaint and draft reply.

## `report` (type: `string`):

Downloadable PDF report with KPIs, sentiment distribution, themes, top complaints and suggested replies.

## `summary` (type: `string`):

Average rating, net sentiment, sentiment distribution, themes, top complaints, per-source errors.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "csvText": `author,rating,date,review
Ana García,5,2026-09-01,El personal muy amable y la comida deliciosa.
John Smith,2,2026-09-03,Waited 40 minutes and the food was cold. Very disappointed.
Laura P.,3,2026-09-05,Buena comida pero la espera fue demasiado larga y el precio algo caro.`,
    "columnMapping": {}
};

// Run the Actor and wait for it to finish
const run = await client.actor("ifritdmc/review-insights-own-reviews-gdpr").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "csvText": """author,rating,date,review
Ana García,5,2026-09-01,El personal muy amable y la comida deliciosa.
John Smith,2,2026-09-03,Waited 40 minutes and the food was cold. Very disappointed.
Laura P.,3,2026-09-05,Buena comida pero la espera fue demasiado larga y el precio algo caro.""",
    "columnMapping": {},
}

# Run the Actor and wait for it to finish
run = client.actor("ifritdmc/review-insights-own-reviews-gdpr").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "csvText": "author,rating,date,review\\nAna García,5,2026-09-01,El personal muy amable y la comida deliciosa.\\nJohn Smith,2,2026-09-03,Waited 40 minutes and the food was cold. Very disappointed.\\nLaura P.,3,2026-09-05,Buena comida pero la espera fue demasiado larga y el precio algo caro.",
  "columnMapping": {}
}' |
apify call ifritdmc/review-insights-own-reviews-gdpr --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ifritdmc/review-insights-own-reviews-gdpr"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ns5chGUSef73zHPrM/builds/FLcxVpnZd9o7Iz7sE/openapi.json
