Gojek Indonesian User Reviews
v1PublishedPublic Indonesian-language user reviews about Gojek from Google Play and Apple App Store review pages.
Output & API
Preview the latest data, download it, or call this collector as an API.
| # | page_title | source_url | review_date | review_text | source_site | reviewer_name | rating_if_available |
|---|---|---|---|---|---|---|---|
| 0 | Gojek - Transportasi & Makanan - Aplikasi di Google Play | https://play.google.com/store/apps/details?id=com.gojek.app&hl=id&gl=ID | 2026-06-28T14:37:13.000Z | Driver belum mengantarkan makanan sesuai dengan penerima yang benar, dan CS sangat tidak membantu, makanan belum sampai, di bilang sudah sampai. sudah cek tetangga dan sekitar tidak ada yang menerima, kemungkinan Driver melakukan penipuan, bahkan saya chat kembali tidak ada jawaban dari driver terkait.. dan lebih utama sangat kecewa dengan CS bantuan, karena hanya cek via sistem otomatis tanpa konfirmasi ke driver bersangkutan | Google Play | Dhanni Rama | 1 |
| 1 | Gojek - Transportasi & Makanan - Aplikasi di Google Play | https://play.google.com/store/apps/details?id=com.gojek.app&hl=id&gl=ID | 2026-06-25T17:03:37.000Z | skip, untuk pembelian selain ojek mending ga usah, apalagi yg urgent kaya masalah listrik yg bisa mati di tengah malam. mending beli di apk lain yg lebih responsif, saya ga sengaja ngisi gopay untuk beli listrik, tapi karena gagal 1x dan mau coba lagi malah tidak bisa, berujung membeli dari apk lainnya. layanan yang lama seperti ini mesti di upd, merugikan bagi org yang uangnya pas-passan dan kehabisan listrik di tengah malam, cust mau disuruh tanpa listrik sampe pagi kayanya! | Google Play | yeny octavii | 1 |
| 2 | Gojek - Transportasi & Makanan - Aplikasi di Google Play | https://play.google.com/store/apps/details?id=com.gojek.app&hl=id&gl=ID | 2026-06-28T05:40:35.000Z | saya mau berlangganan disney+ dan sudah mencoba 3 cara untuk dapatkan kode via otp, tapi tetap saja setelah menggunakan 3 cara itu tetap minta pin gopay. harusnya langsung ada opsi lupa pin gopay biar lebih mudah. saya jadi marah dengan fitur aplikasi ini yang tidak menyediakan langsung opsi lupa pin gopay. tolong dipahami. harus langsung ada opsi lupa pin gopay. biar mudah langganan disney+ | Google Play | M. Akbar Putra Arianto | 1 |
Marketplace
Publish this collector so others can deploy it — you keep ownership.
0 runs in 14d · published 3d ago
Versions
Every build and self-heal appends a version. Pin one to lock runs to it.
v1builtapprovedcurrent3d ago
How this script collects data
import Firecrawl from "@mendable/firecrawl-js";
import * as cheerio from "cheerio";
const apiKey = process.env.FIRECRAWL_API_KEY;
if (!apiKey) {
console.error("FIRECRAWL_API_KEY is not set");
process.exit(1);
}
const firecrawl = new Firecrawl({ apiKey });
const TARGET_COUNT = 200;
type ReviewRow = {
review_text: string;
rating_if_available: number | null;
review_date: string;
reviewer_name: string;
page_title: string;
source_site: string;
source_url: string;
};
function normalizeText(value: string): string {
return value.replace(/\s+/g, " ").trim();
}
function dedupeKey(value: string): string {
return normalizeText(value).toLowerCase();
}
function decodeJsonString(value: string): string {
try {
return JSON.parse(`"${value.replace(/\n/g, "\\n")}"`);
} catch {
return value;
}
}
function looksIndonesian(text: string): boolean {
const lowered = ` ${text.toLowerCase()} `;
const markers = [
" yang ",
" dan ",
" di ",
" ke ",
" dari ",
" untuk ",
" dengan ",
" karena ",
" kalau ",
" saya ",
" aku ",
" ga ",
" gak ",
" nggak ",
" tidak ",
" bisa ",
" banget ",
" udah ",
" sudah ",
" aja ",
" tapi ",
" driver ",
" aplikasi ",
" pesanan ",
" makanan ",
" saldo ",
" promo ",
" gofood ",
" goride ",
" gopay ",
" gojek ",
" mahal ",
" lama ",
" susah ",
" tolong ",
" kecewa ",
" membantu ",
];
return markers.some((marker) => lowered.includes(marker));
}
function addReview(rows: ReviewRow[], seen: Set<string>, row: ReviewRow): void {
row.review_text = normalizeText(row.review_text);
row.reviewer_name = normalizeText(row.reviewer_name);
row.page_title = normalizeText(row.page_title);
if (row.review_text.length < 20) return;
if (!looksIndonesian(row.review_text)) return;
const key = dedupeKey(row.review_text);
if (seen.has(key)) return;
seen.add(key);
rows.push(row);
}
async function scrapeRawHtml(url: string): Promise<string> {
const doc = (await firecrawl.scrape(url, {
formats: ["rawHtml"],
integration: "prometheus",
})) as { rawHtml?: string; html?: string };
const rawHtml = doc.rawHtml ?? doc.html ?? "";
if (!rawHtml) {
throw new Error(`no raw HTML returned for ${url}`);
}
return rawHtml;
}
async function collectGooglePlay(rows: ReviewRow[], seen: Set<string>): Promise<void> {
const sourceUrl = "https://play.google.com/store/apps/details?id=com.gojek.app&hl=id&gl=ID";
const rawHtml = await scrapeRawHtml(sourceUrl);
const pageTitle = normalizeText(cheerio.load(rawHtml)("title").first().text()) || "Gojek - Google Play";
const reviewPattern =
/\["([a-f0-9-]{36})",\["((?:\\.|[^"\\])*)",[\s\S]{0,1400}?\],(\d),null,"((?:\\.|[^"\\])*)",\[(\d{10}),\d+\]/g;
let match: RegExpExecArray | null;
while ((match = reviewPattern.exec(rawHtml)) !== null) {
const reviewerName = decodeJsonString(match[2]);
const rating = Number(match[3]);
const reviewText = decodeJsonString(match[4]);
const reviewDate = new Date(Number(match[5]) * 1000).toISOString();
addReview(rows, seen, {
review_text: reviewText,
rating_if_available: Number.isFinite(rating) ? rating : null,
review_date: reviewDate,
reviewer_name: reviewerName,
page_title: pageTitle,
source_site: "Google Play",
source_url: sourceUrl,
});
}
}
async function collectAppleAppStore(rows: ReviewRow[], seen: Set<string>): Promise<void> {
for (let page = 1; page <= 10 && rows.length < TARGET_COUNT; page += 1) {
const sourceUrl = `https://itunes.apple.com/id/rss/customerreviews/page=${page}/id=944875099/sortby=mostrecent/xml`;
const rawXml = await scrapeRawHtml(sourceUrl);
const $ = cheerio.load(rawXml, { xmlMode: true });
$("entry").each((_, entry) => {
if (rows.length >= TARGET_COUNT) return false;
const reviewText = $(entry).find('content[type="text"]').first().text();
const ratingText = $(entry).find("im\\:rating").first().text();
const rating = Number(ratingText);
const reviewDate = $(entry).find("updated").first().text();
const reviewerName = $(entry).find("author > name").first().text();
addReview(rows, seen, {
review_text: reviewText,
rating_if_available: Number.isFinite(rating) ? rating : null,
review_date: reviewDate,
reviewer_name: reviewerName,
page_title: "Gojek - Ratings and Reviews - App Store",
source_site: "Apple App Store",
source_url: sourceUrl,
});
return undefined;
});
}
}
async function main() {
const rows: ReviewRow[] = [];
const seen = new Set<string>();
await collectGooglePlay(rows, seen);
await collectAppleAppStore(rows, seen);
if (rows.length < 150) {
throw new Error(`collected fewer review rows than expected: ${rows.length}`);
}
process.stdout.write(JSON.stringify(rows.slice(0, TARGET_COUNT)));
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Deploy this collector to unlock schedules, the API endpoint, and destinations.