{"record":{"id":"de2708a2de63520f","repo":"tonhowtf/omniget","slug":"n-o-achei-o-id-da-sua-conta-na-p-gina-de-importa-o-do","errorCode":null,"errorMessage":"não achei o id da sua conta na página de importação do Goodreads","messagePattern":"não achei o id da sua conta na página de importação do Goodreads","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/lists/goodreads.rs","lineNumber":254,"sourceCode":"        }\n    }\n    None\n}\n\n/// Dispara o export e espera o CSV aparecer. Devolve `(csv, segundos)`.\n///\n/// O caminho é o mesmo do navegador: pegar o token anti-CSRF da página de\n/// importação, mandar o POST em `/review_porter/export/<id>` e depois ficar\n/// perguntando pelo arquivo, que responde 404 enquanto não fica pronto.\nasync fn trigger_and_wait(f: &Fetcher, opts: &Options, p: &ProgressFn) -> Result<(String, u64)> {\n    let page = f.get_text(IMPORT_URL).await?;\n    if is_signed_out(&page) {\n        return Err(anyhow!(\n            \"a sessão do Goodreads não está válida: capture os cookies de goodreads.com na extensão\"\n        ));\n    }\n    let uid = user_id(&page).ok_or_else(|| {\n        anyhow!(\"não achei o id da sua conta na página de importação do Goodreads\")\n    })?;\n    let csv_url = export_csv_url(&uid);\n\n    // Se já existe um export pronto, aproveita: o Goodreads só deixa gerar um\n    // a cada poucos dias, e gerar um novo apaga o anterior.\n    let ready = !opts.force && export_link(&page).is_some();\n    let started = Instant::now();\n    if !ready {\n        let token = csrf_token(&page).ok_or_else(|| {\n            anyhow!(\n                \"não achei o token anti-CSRF do Goodreads; recapture os cookies e tente de novo\"\n            )\n        })?;\n        f.pace().await;\n        let resp = f\n            .client()\n            .post(export_post_url(&uid))\n            .header(reqwest::header::REFERER, IMPORT_URL)","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/lists/goodreads.rs#L236-L272","documentation":"After confirming the session is valid, trigger_and_wait extracts the Goodreads user id from the import page HTML via user_id(). The id is required to build the /review_porter/export/<id> URL. If the page HTML does not match the expected pattern, the library cannot proceed and returns this error.","triggerScenarios":"user_id() returning None on a fetched import page: Goodreads changed their page markup/attributes embedding the user id, a localized/A-B-test variant of the page renders different HTML, or a partial/interstitial page was returned despite passing the signed-out check.","commonSituations":"Goodreads frontend redesign altering the data attribute or script blob containing the user id; page served in a different language/locale; bot-check or Cloudflare interstitial returned instead of the real page.","solutions":["Retry once — transient interstitials can produce a page without the id; then rerun.","Capture fresh cookies via the extension (the signed-out check can pass on a partial page) and rerun.","Check for an updated version of this tool — a Goodreads markup change requires updating the user_id() extraction pattern.","Open goodreads.com/review/import in a browser and confirm the page loads normally (no bot challenge) before rerunning."],"exampleFix":"// before: user_id() regex misses new markup\nlet uid = user_id(&page).ok_or_else(|| anyhow!(...))?;\n\n// after: update extractor for new Goodreads markup\nfn user_id(page: &str) -> Option<u64> {\n    // match current attribute, e.g. data-user-id=\"12345\"\n    ...\n}","handlingStrategy":"retry","validationCode":"let page = fetcher.get_text(IMPORT_URL).await?;\nif user_id(&page).is_none() {\n    // fetch once more before giving up; interstitials happen\n    let page = fetcher.get_text(IMPORT_URL).await?;\n    anyhow::ensure!(user_id(&page).is_some(), \"import page did not contain user id\");\n}","typeGuard":null,"tryCatchPattern":"match run(&fetcher, &opts).await {\n    Err(e) if e.to_string().contains(\"id da sua conta\") => {\n        warn_user_of_possible_goodreads_markup_change_and_report();\n    }\n    r => r?,\n}","preventionTips":["Retry the page fetch once on extraction failure","Keep the tool updated — extraction patterns break on Goodreads redesigns","Report persistent failures with a saved copy of the page HTML for diagnosis"],"tags":["html-parsing","goodreads","scraping","upstream-change"],"backgroundTag":"unexpected-response-shape","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}