המטרה
הסוכנות Realtorships משרתת עשרות לקוחות נדל"ן עם מודעות realtor.com יומיות. המטרה: פייפליין יומי ללא תחזוקה שמגרד לפי ZIP של כל לקוח, כותב לגוגל שיט של הלקוח, ומגיש דאשבורד ממותג בלי login.
הפתרון
מערכת דו-שכבתית: (1) Apps Script Code.gs רץ ב-trigger יומי, עובר על Users sheet, יורה 8 שאילתות GraphQL של realtor.com, מעמוד 100+ תוצאות, וכותב לגיליון של כל לקוח. (2) Web app ב-Apps Script תחת webapp/ מגיש URL אחד ?ss=<id> עם דאשבורד ממותג — סינון, טבלה ממוינת, pagination, CSV export, ACL דרך whitelist של parent sheet, caching בשתי השכבות.
עיקרי הדברים
- פייפליין יומי ללא תחזוקה — בלי שרת
- 8 שאילתות GraphQL של realtor.com הוסגרו מהדפדפן
- URL bookmarkable לכל לקוח ללא auth, עם whitelist מ-parent sheet
- URL יציב בין גרסאות — bookmarks של הלקוחות לא נשברים
האתגר
ל-realtor.com אין API ציבורי — רק GraphQL לדפדפן עם שאילתות מסתובבות.
לכידת 8 GraphQL calls + detail מהדפדפן, נרמול ל-UrlFetchApp עם headers/doc_ids מדויקים, pagination לפי nextCursor. probe_inline_query.py לרענון.
עשרות לקוחות, כל אחד צריך גיליון חי משלו — DB מיותר.
Users sheet אחד עם hyperlinks ל-spreadsheets של לקוחות ב-column C. הסקרייפר עובר וכותב לכל לקוח בנפרד.
לקוחות רצו URL bookmarkable בלי login, אבל הלינק לא יכול לחשוף דאטה של אחר.
doGet מחלץ ?ss=<id>, בודק מול Users sheet ומגיש רק אם ה-ID מופיע ב-column C. ID זר = 'Dashboard not found'. Onboarding = הוסף שורה, offboarding = הסר.
רנדור נאיבי ב-Apps Script נתן זמני טעינה של 8-10 שניות.
השרת מחזיר דאטה מנורמל; לקוח מריץ filter/sort/pagination מקומית. Cache 60s לקוח + 5min שרת. לוגו base64 חוסך round-trip.
לקוחות שומרים את URL הדאשבורד — redeploy שובר להם.
Manage deployments → New version — ה-URL יציב בין deploys וכל הלקוחות רואים גרסה חדשה מיד.
מה נמסר
- שירות scraping ב-Code.gs עם iteration על parent sheet
- חבילת Web app (webapp/Code.gs + 4 קובצי HTML + appsscript.json)
- webapp/README.md עם מדריך פריסה של 6 שלבים ו-troubleshooting
- זוגות GraphQL request/response מוקלטים
- Probes ב-Python לרענון schemas
- דאשבורד ממותג Realtorships עם לוגו base64
- AVAILABLE_FIELDS_FOR_REALTOR.md
תוצאות
8 + detail
שאילתות GraphQL
100+/batch
גודל batch
7
סינון דאשבורד
Daily
תזמון
מה זה לימד אותי
- לפורטלים בלי auth, ?ss=<whitelisted-id> מול parent sheet מנצח בניית auth
- Filter/sort/pagination בצד הלקוח שומרים את ה-UI מהיר בלי backend
- לכידת GraphQL של הדפדפן היא הדרך הקיימא לאינטגרציית APIs לא מתועדים
