App & Extension Review Intelligence avatar

App & Extension Review Intelligence

Pricing

from $0.50 / 1,000 review data records

Go to Apify Store
App & Extension Review Intelligence

App & Extension Review Intelligence

Monitor public reviews from Google Play, Apple App Store, and Chrome Web Store. Extract normalized review records, detect new reviews, classify sentiment/topics, create app summaries, and send webhook alerts.

Pricing

from $0.50 / 1,000 review data records

Rating

0.0

(0)

Developer

Вадим Захаров

Вадим Захаров

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Store V1 production-ready public review monitor for Google Play reviews, Apple App Store reviews, and Chrome Web Store reviews.

This unofficial Actor is a Google Play reviews scraper, Apple App Store reviews scraper, and Chrome Web Store reviews scraper for app reputation monitoring, competitor review analysis, product feedback, extension review monitor workflows, and negative review alerts.

Use it as an app review monitor when you need one normalized workflow across public mobile app and browser extension review sources.

What this Actor does

App & Extension Review Intelligence collects publicly visible app and extension reviews, normalizes them into one dataset schema, detects new reviews with stateful deduplication, creates app_summary records, classifies rule-based sentiment and topic classification locally, writes a user-facing OUTPUT summary to the Key-Value Store, and can send webhook alerts with new negative reviews.

Use cases:

  • App reputation monitoring across stores, countries, and languages.
  • Competitor review analysis for public app feedback.
  • Product feedback mining from complaint themes such as bug_crash, login, performance, billing, and feature_request.
  • Support automation through negative review alerts to Slack, Make, Zapier, CRM, or helpdesk workflows.
  • Scheduled onlyNewSinceLastRun monitors that output only reviews not already seen for the same stateKey.

Supported sources

The Actor reads public review surfaces exposed by each store. Use the store-specific app or extension ID listed below.

Supported stores

StoreInput idPublic sourceLanguage behaviorDeveloper replies
Google Play reviewsAndroid package name, for example com.spotify.musicPublic Google Play review surfaceUses requested country and language as public endpoint context where supportedIncluded when exposed by the public payload
Apple App Store reviewsNumeric app ID, for example 324684580Public iTunes customer reviews RSS/JSON feedStorefront-specific; requested language is target context, not a guaranteed source filterNot exposed by this public RSS source
Chrome Web Store reviewsExtension ID, for example aapbdbdomjkkjkaonfhkkikfgjllclebPublic Chrome Web Store review surfaceUses requested country/language context where supportedIncluded when exposed by the public payload

What it does not do

  • No login.
  • No cookies.
  • No private APIs.
  • No private developer dashboards.
  • No CAPTCHA bypass.
  • No account impersonation.
  • No guaranteed full historical depth.
  • No AI calls or external enrichment APIs.

This Actor collects public data only. Public reviewer display names can appear only when they are part of public review content. It is not affiliated with Google, Apple, Chrome, or any app/extension owner.

Input schema

FieldTypeDefaultDescription
apps{ store, id, country?, language? }[]requiredApps/extensions to scrape. Store must be google_play, app_store, or chrome_web_store.
maxReviewsPerAppinteger100Maximum raw reviews per concrete target, from 1 to 5000. A concrete target is store + appId + country + language.
maxReviewsPerTargetintegeremptyAlias for maxReviewsPerApp. If both are provided, they must match.
ratingsinteger array[1, 2, 3, 4, 5]Rating filter applied after normalization. Duplicate ratings are removed.
languagesstring array["en"]Global languages used when a target has no app-level language.
countriesstring array["US"]Global countries/storefronts used when a target has no app-level country.
onlyNewSinceLastRunbooleanfalseWhen true, only unseen review records for the same stateKey are pushed to the dataset.
stateKeystringdefaultNamespace for incremental state in the Actor's internal named Key-Value Store.
includeTopicClassificationbooleantrueAdds rule-based topics for negative reviews.
includeAppSummarybooleantruePushes one app_summary record per successful target.
webhookUrlHTTP(S) URLemptySends one final JSON POST with summaries and new negative reviews.
proxyConfigurationApify proxy object{ "useApifyProxy": true }Standard Apify proxy configuration used for store HTTP requests when a proxy URL is available.
maxConcurrencyinteger3Maximum store targets fetched in parallel.
requestTimeoutSecsinteger30Timeout for public HTTP requests.
maxRequestRetriesinteger3Retry budget for transient store request failures.
maxTargetsinteger100Safety limit for expanded concrete targets.
maxTotalReviewsinteger10000Safety limit for expandedTargets.length * maxReviewsPerApp.

App-level country and language override global arrays. Without overrides, the Actor expands every app into global countries x languages combinations. maxReviewsPerApp is applied after expansion, per concrete target.

Input examples

1. Google Play review monitor

{
"apps": [
{ "store": "google_play", "id": "com.spotify.music", "country": "US", "language": "en" }
],
"maxReviewsPerApp": 100,
"ratings": [1, 2, 3, 4, 5],
"includeAppSummary": true,
"stateKey": "google-play-monitor"
}

Google Play example

The example above is the standard Google Play example for a single app monitor.

2. Apple App Store review monitor

{
"apps": [
{ "store": "app_store", "id": "324684580", "country": "US", "language": "en" }
],
"maxReviewsPerApp": 100,
"includeAppSummary": true,
"stateKey": "apple-app-store-monitor"
}

Apple App Store example

The example above monitors a public Apple App Store RSS review feed by numeric app ID.

3. Chrome Web Store review monitor

{
"apps": [
{ "store": "chrome_web_store", "id": "aapbdbdomjkkjkaonfhkkikfgjllcleb", "country": "US", "language": "en" }
],
"maxReviewsPerApp": 50,
"includeAppSummary": true,
"stateKey": "chrome-extension-monitor"
}

Chrome Web Store example

The example above is a Chrome extension monitor for public extension reviews.

4. Multi-store competitor review analysis

{
"apps": [
{ "store": "google_play", "id": "com.spotify.music", "country": "US", "language": "en" },
{ "store": "google_play", "id": "com.duolingo", "country": "US", "language": "en" },
{ "store": "app_store", "id": "324684580", "country": "US", "language": "en" },
{ "store": "chrome_web_store", "id": "aapbdbdomjkkjkaonfhkkikfgjllcleb", "country": "US", "language": "en" }
],
"maxReviewsPerTarget": 100,
"includeAppSummary": true,
"includeTopicClassification": true,
"stateKey": "competitor-review-analysis"
}

5. onlyNewSinceLastRun scheduled monitor

{
"apps": [
{ "store": "google_play", "id": "com.spotify.music", "country": "US", "language": "en" },
{ "store": "app_store", "id": "324684580", "country": "US", "language": "en" }
],
"maxReviewsPerApp": 50,
"onlyNewSinceLastRun": true,
"includeAppSummary": true,
"stateKey": "daily-negative-review-monitor"
}

6. negative review webhook alert

{
"apps": [
{ "store": "google_play", "id": "com.spotify.music", "country": "US", "language": "en" },
{ "store": "app_store", "id": "324684580", "country": "US", "language": "en" }
],
"ratings": [1, 2],
"onlyNewSinceLastRun": true,
"webhookUrl": "https://example.com/review-alerts",
"includeAppSummary": true,
"stateKey": "daily negative review monitor"
}

Output examples

Output schema

Review records use "recordType": "review":

{
"recordType": "review",
"store": "google_play",
"appId": "com.example.app",
"appName": null,
"appUrl": null,
"developerName": null,
"country": "US",
"language": "en",
"scrapedAt": "2026-05-29T09:00:00.000Z",
"reviewId": "review-123",
"fingerprint": "google_play:com.example.app:review-123",
"reviewUrl": null,
"rating": 1,
"title": "Crashes after update",
"text": "The app crashes every time I open it after the latest update.",
"reviewDate": "2026-05-28T00:00:00.000Z",
"reviewCreatedAt": "2026-05-28T00:00:00.000Z",
"reviewUpdatedAt": null,
"authorName": "Public reviewer name",
"authorId": null,
"authorUrl": null,
"appVersion": "4.2.1",
"developerReply": null,
"developerReplyText": null,
"developerReplyDate": null,
"hasDeveloperReply": false,
"sentiment": "negative",
"sentimentMethod": "rating_plus_rules",
"topic": "bug_crash",
"topicMethod": "rule_based",
"primaryTopic": "bug_crash",
"topics": ["bug_crash"],
"topicScores": { "bug_crash": 2 },
"isNew": true,
"sourceUrl": "https://play.google.com/store/apps/details?id=com.example.app&hl=en&gl=US",
"sourceLanguageFilterApplied": true,
"languageFilterReliability": "best_effort",
"storeCategory": null,
"storeRating": null,
"storeReviewCount": null,
"warnings": [],
"storeData": {}
}

If a source does not expose an optional field, the Actor writes null or [] instead of breaking the schema.

Summary records use "recordType": "app_summary":

{
"recordType": "app_summary",
"store": "google_play",
"appId": "com.example.app",
"country": "US",
"language": "en",
"scrapedAt": "2026-05-29T09:00:00.000Z",
"stateKey": "weekly-monitoring",
"reviewsScraped": 100,
"reviewsOutput": 17,
"newReviews": 17,
"newNegativeReviews": 8,
"reviewCount": 100,
"averageRating": 3.42,
"negativeRate": 0.32,
"sentimentCounts": { "negative": 32, "neutral": 18, "positive": 50 },
"topTopics": [
{ "topic": "bug_crash", "count": 12, "rate": 0.375 }
],
"developerReplyRate": 0.12,
"developerReplyCoverage": "available",
"sourceLanguageFilterApplied": true,
"languageFilterReliability": "best_effort",
"sentimentMethod": "rating_plus_rules",
"topicMethod": "rule_based",
"appName": null,
"appUrl": null,
"developerName": null,
"storeCategory": null,
"storeRating": null,
"storeReviewCount": null,
"warnings": []
}

User-facing Key-Value Store output

Each run writes a compact OUTPUT record in the default Key-Value Store. This is separate from internal incremental state and is safe to use as the run-level summary for integrations.

OUTPUT contains actorName, runId, status, scrapedAt, stateKey, onlyNewSinceLastRun, datasetId, keyValueStoreId, summary counters, byStore, byTarget, appSummaries, warnings, and errors. Status is succeeded, partial_success, or failed.

If all targets fail, the Actor still writes OUTPUT with status="failed" and then throws so the Apify run is marked failed.

Webhook usage

When webhookUrl is set, the Actor sends one final JSON POST after dataset records and state are written. The webhook payload includes run metadata, summary counters, app summaries, warnings, errors, and up to 100 new negative reviews with review text truncated to avoid huge payloads.

Webhook payload example

{
"actorName": "App & Extension Review Intelligence",
"runId": "apify-run-id",
"scrapedAt": "2026-05-29T09:00:00.000Z",
"stateKey": "weekly-monitoring",
"onlyNewSinceLastRun": true,
"summary": {
"targetsProcessed": 3,
"targetsSucceeded": 3,
"targetsFailed": 0,
"reviewsScraped": 250,
"reviewsOutput": 42,
"newReviews": 42,
"newNegativeReviews": 19
},
"appSummaries": [],
"newNegativeReviews": [],
"warnings": [],
"errors": [],
"datasetId": "default-dataset-id",
"keyValueStoreId": "default-key-value-store-id"
}

Webhook failures are warnings, not scraping failures. If delivery fails after retries, the Actor writes LAST_WEBHOOK_FAILURE with failedAt, attempts, errorCode, errorMessage, webhook host only, datasetId, summary counters, and newNegativeReviewsCount. It does not store full webhook payloads, raw HTML, cookies, tokens, or secrets.

Incremental state / stateKey

onlyNewSinceLastRun controls dataset output, not scraping. The Actor still fetches the current public review page, normalizes records, deduplicates within the run, and updates state for successful targets.

State is stored in the Actor's internal named Apify Key-Value Store, separate from the per-run default store that holds INPUT, OUTPUT, and webhook diagnostics. Internal state entries use:

APP_EXTENSION_REVIEW_INTELLIGENCE_STATE_<safeStateKey>

Use different stateKey values for independent monitors, for example weekly-monitoring, competitors-us, or release-7-2. Fingerprints are namespaced by store + appId + country + language, so the same app can be monitored separately across locales.

Rule-based sentiment and topic classification

The Actor uses deterministic local rules and does not call external AI, sentiment, enrichment, or topic APIs.

The rule-based sentiment method is rating_plus_rules. Ratings 1 and 2 are negative, rating 3 is neutral, and ratings 4 and 5 are positive, with limited keyword rules for borderline cases.

Topic classification runs for negative reviews when includeTopicClassification=true. It returns topic, primaryTopic, topics, and topicScores. Supported topics are billing, bug_crash, login, performance, support, pricing, UX, feature_request, spam, and other.

Understanding warnings

Warning codeMeaning
APP_STORE_LANGUAGE_FILTER_NOT_GUARANTEEDApple App Store public RSS is storefront-based and does not guarantee filtering by requested language.
TOPIC_CLASSIFICATION_ENGLISH_BIASEDTopic rules use an English keyword dictionary; interpret non-English topic labels cautiously.
NO_PUBLIC_REVIEWS_FOUNDThe public source returned no reviews for the target/filter combination.
PUBLIC_ACCESS_BLOCKEDThe public source returned a login, CAPTCHA, or access-blocked response.
GOOGLE_PLAY_PARSE_FAILEDGoogle Play public payload changed or could not be parsed.
APP_STORE_RSS_UNAVAILABLEApple RSS feed failed or returned malformed data.
CHROME_WEB_STORE_LIMITED_REVIEWSChrome reports more public reviews than this run could retrieve from the public endpoint.
CHROME_WEB_STORE_PARSE_FAILEDChrome Web Store public payload changed or could not be parsed.
LOW_CONFIDENCE_INCREMENTAL_DEDUPEA review lacked stable identifiers, so incremental dedupe used a lower-confidence fallback.
WEBHOOK_DELIVERY_FAILEDThe webhook endpoint timed out or returned an error.

Limitations

Apple language limitation

Apple App Store public RSS is storefront-based. Requested language is preserved in output and target keys, but source-side language filtering is not guaranteed. Apple targets include sourceLanguageFilterApplied=false, languageFilterReliability="not_applied", and APP_STORE_LANGUAGE_FILTER_NOT_GUARANTEED.

Apple developer reply limitation

Apple App Store public RSS does not expose developer replies. Apple summaries use developerReplyCoverage="not_exposed_by_source".

Google/Chrome public endpoint limitation

Google Play and Chrome Web Store data comes from public review surfaces. Availability, ordering, pagination depth, historical coverage, developer replies, and metadata can change by store, country, language, app, and time. Public endpoint limitations are reported as warnings when possible.

Store limitations and troubleshooting

SymptomLikely reasonWhat to check
No records for a targetNo public reviews were returned for that country/language/filterTry another country/language or broader ratings.
Partial successOne target failed while others succeededCheck OUTPUT.byTarget and warnings/errors.
All-target failureEvery target failed validation or fetchingCheck run logs and failed OUTPUT.
Apple language warningApple RSS language filtering is not guaranteedTreat Apple language as target context.
Webhook warningEndpoint rejected or timed outVerify the endpoint accepts JSON POST and returns HTTP 2xx.

Pricing note

For Store V1, keep pricing simple. A good draft is a small Actor start event plus a low per-result price based on default dataset items. Because this Actor writes both review and app_summary records to the default dataset, default dataset item pricing charges both record types unless configured otherwise in Apify Console. Do not apply pricing automatically without final owner approval.

Public data only

This Actor works with public review sources only. It does not request credentials, does not read private dashboards, does not use cookies, and does not bypass CAPTCHA or access controls. Use it in a way that respects source terms and local laws.

Development

  • npm run build compiles TypeScript to dist/.
  • npm start runs the compiled Actor entrypoint.
  • npm run dev runs the TypeScript entrypoint with tsx.
  • npm run smoke:live runs a small real-source smoke against one target per supported store and writes storage/smoke-live-report.json.
  • npm test runs the Vitest suite once.
  • npm run test:watch runs Vitest in watch mode.