Fix Alexa To Reminders: persistent WebView auth + XHR API calls#34
Fix Alexa To Reminders: persistent WebView auth + XHR API calls#34BrutalByte wants to merge 22 commits into
Conversation
- Alexa To Reminders Access: fix makeLogin always returning false after WebView login, await main() before Script.complete(), null-guard item.value before split, move Reminder.all() outside loop, remove debug log calls - MEE6 LeaderBoard Info: fix async forEach → for...of with await, single regex.exec call, break after first player match, remove dead WebView block, declare dir with let - RH-Downloads: parseInt for delta math, name null-guard, declare ab/dir with let - ScriptBackup: recursive backup including subdirectories, skip ScriptBackup folder to avoid re-copying old backups - Twitter Widget: fix checkUpdates===true strict comparison, remove hardcoded bearer token - Weather Overview: fix now.getTime() parentheses, ms→seconds for night detection, amtLabel scope, Script.setWidget before complete, and several other rendering fixes - Both Calendar Indicators: fix async splice→filter, isCalEvent guard ordering for item.calendar.title, multipleAllDay cross-month fix, item.endDate NaN guard for reminders, version bump to 2.8, remove duplicate Scriptable headers and dead const backgroundColor - tests/: full unit test suite (148 tests) covering all scripts with injectable mocks for all Scriptable APIs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PostToolUse hook: auto-runs test suite after every file edit - PreToolUse hook: warns before editing shared scriptable-mocks.js - /new-script skill: scaffolds new Scriptable widget with required headers - /gen-test skill: generates test files following project conventions - scriptable-reviewer agent: audits widgets for size/API/pattern issues - context7 MCP server: live Scriptable API documentation lookup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parse response as string first and catch JSON.parse errors to avoid crashing when Amazon returns HTML (login wall, CAPTCHA, session expiry). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Guard against null reminderCalendar when list name doesn't match - Log actual error message in catch block instead of generic string Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows an action sheet of all available reminder lists on the device instead of silently exiting when reminderListName doesn't match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Saves the user-selected list to AlexaToReminders/settings.json so subsequent runs use it automatically without prompting again. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds timestamped vlog() helper and covers every major step: auth check, login flow, list lookup, JSON parse, per-item create/skip/delete, and sync summary counts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Validate parsed JSON is a plain object before iterating lists; Amazon was returning a quoted string which for..in treated as chars - makeLogin now always re-checks the API after loading the homepage instead of assuming success when the sign-in indicator is absent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Script fixes: - vlog now uses local device time instead of UTC - checkIfUserIsAuthenticated returns true only for 2xx (was accepting 5xx) - makeLogin presents fallback WebView when homepage looks logged-in but API still returns 401, so user can always recover a stale session Test fixes: - makeCheckIfUserIsAuthenticated helper updated to match 2xx-only logic - makeMakeLogin helper updated to match fallback WebView behavior - Added: 5xx/302 rejection tests for auth check - Added: fallback WebView test for makeLogin - Added: JSON response type validation suite (string/null/array rejection) - Added: settings persistence suite (save, load, fallback, key preservation) 160 tests, 0 failures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Loading the Amazon homepage wasn't establishing the right cookies for the shopping list API. Loading the API URL directly forces Amazon to set the correct session cookies for that endpoint. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Request and WebView use separate cookie stores on iOS — logging in via WebView had no effect on subsequent Request calls. Now a single sessionView WebView instance is used for both auth checking and data fetching, ensuring cookies are consistent throughout the session. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Scriptable's Request and WebView have completely separate cookie stores on iOS — no amount of WebView login would affect Request calls. Replaced all Amazon API calls with wvFetch(), which executes fetch() inside the WebView's JS context using its own cookie jar. The same sessionView is loaded on amazon.com first to establish same-origin context, then all GET and DELETE calls run through it. Also simplified auth flow: ensureAuthenticated() tries the API once, presents WebView if it fails, then retries once — and passes the already-fetched JSON directly to synchronizeReminders() to avoid a redundant second API call. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Scriptable's evaluateJavaScript completion callback does not support Promises. fetch() returns a Promise as the expression value before completion() fires, causing the "unsupported type" error. Replaced fetch() with XMLHttpRequest using onload/onerror callbacks, which call completion() directly and work correctly with Scriptable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The completion() callback pattern causes "unsupported type" errors when called asynchronously. Scriptable natively resolves JS Promises returned from evaluateJavaScript, so wrapping the XHR in a Promise avoids the issue entirely. Removed useCallback flag. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dropped the WebView-for-everything approach. Instead: - Show a WebView for login once, then extract document.cookie - Inject extracted cookies as a Cookie header on all Request calls - Cache cookies in settings.json so subsequent runs skip the WebView - Fall back to login WebView only when cached cookies are missing/expired evaluateJavaScript on a simple synchronous expression (document.cookie) works reliably; async XHR/Promise patterns do not in this Scriptable env. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eliminates evaluateJavaScript for all auth-sensitive operations. Amazon's HttpOnly auth cookies stay in WKWebView and are used automatically by loadURL navigations and loadHTML XHR calls. - fetchListJSON: loadURL to API endpoint, getHTML to read response, extract JSON from HTML (pre tag or stripped body text) - deleteListItem: loadHTML with inline synchronous XHR helper page, getHTML to read the status result — no evaluateJavaScript needed - ensureAuthenticated: try API directly, present WebView if it fails, retry once after user dismisses Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… cookies amazon.com homepage auth is insufficient for the Alexa Shopping List API. The WebView must visit /alexa-lists first so Amazon sets the Alexa session state before the API call is retried. Also adds an instruction alert so the user knows to wait for the list to load before tapping Done. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Direct loadURL navigation to the API doesn't send the headers Amazon requires for its AJAX endpoints (X-Requested-With, Accept: application/json). Switched to the same loadHTML+XHR pattern used for DELETE so those headers are included and status can be checked. Also changed the sign-in WebView to load https://alexa.amazon.com (the full Alexa app) instead of the www.amazon.com/alexa-lists stub page (only 2KB, no real auth state). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rewrites the script entry to cover the new authentication approach (persistent WKWebView session via alexa.amazon.com), setup steps, the Reminders list picker, and settings persistence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@BrutalByte thanks for your work! I just tested successfully in my environment. One thing you IMHO should correct: You shouldn’t hard-code alexa.amazon.com URL, as this also differs for region. Either this should be configurable too. IMHO a better solution might be to derive it from configured Amazon URL. Isn‘t it? |
Fixes regional support — e.g. amazon.co.uk now correctly uses alexa.amazon.co.uk. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Good point!
Good call — fixed in this PR. The Alexa URL is now derived from baseURL using a simple subdomain swap (www.→alexa.), so regional users only need to set baseURL and everything follows from that. |
Summary
loadURLnavigation to the Alexa API endpoint doesn't send the headers Amazon's AJAX endpoints require (X-Requested-With: XMLHttpRequest,Accept: application/json). SwitchedfetchListJSONto the sameloadHTML+ synchronous XHR helper pattern already used for DELETE calls — this sends the correct headers and works within the WebView's authenticated session.www.amazon.comhomepage toalexa.amazon.comso the user establishes a full Alexa session (not just a general Amazon login) before the API is retried.reminderListNamedoesn't match any list, an alert lets the user pick from all available lists. The choice is saved toAlexaToReminders/settings.jsonin iCloud.Test plan
alexa.amazon.comloads in WebView, items sync after tapping Done