๐ File Structure
MCD UTAMA/
โ
โโโ CNAME โ Custom domain: popfood.vip
โโโ index.html โ Main webpage (form + receipt)
โ
โโโ src/
โ โโโ app.js โ Core logic (form, validation, API, receipt)
โ โโโ food-bg.js โ Floating emoji background animation
โ โโโ style.css โ All styling (McDonald's theme, animations)
โ
โโโ Cloudflare Worker/
โ โโโ index.js โ Backend proxy (validation โ Sheets + Telegram)
โ
โโโ Google App Script/
โ โโโ script.gs โ Google Sheets writer (appends row)
โ
โโโ media/ โ Static assets
โโโ banner.jpg โ Hero banner image
โโโ mcd.png โ McDonald's logo + favicon
โโโ foi.png โ POPFOI logo
โโโ bea.png luz.png n1.png โ Platform logos (emoji click game)
โโโ sur.png zoe.png โ Platform logos (emoji click game)
๐ Hosting & Domain
| Component | Where It Lives |
|---|---|
| Frontend STATIC | GitHub Pages (index.html + src/ + media/) |
| Custom Domain | popfood.vip |
| Cloudflare Worker API | mcd.danilla-vargas1923.workers.dev |
| Google Apps Script BACKEND | Web App (URL in Worker env GOOGLE_SHEET_URL) |
| Telegram Bot NOTIFY | Bot API (token in Worker env TG_BOT_TOKEN) |
| Google Sheet DB | Linked to Apps Script โ stores all registrations |
๐ Complete Data Flow
USER (Browser)
โ
โ 1. Opens popfood.vip
โ โ index.html loads โ style.css โ food-bg.js โ app.js
โ
โ 2. Types Game ID (10 digits) โ Tier table reveals
โ 3. Types Email โ Warning box appears
โ
โ 4. Clicks "REGISTRE-SE!"
โ โ app.js validates: โ 10 digits โ valid email
โ โ Button disabled โ "Enviando..."
โ โ Generates Sรฃo Paulo timezone date/time
โ
โผ
โ 5. POST โ https://mcd.danilla-vargas1923.workers.dev
โ Body: { platform, game_id, email, registered_date, registered_time }
โ Retry: up to 3 attempts (300ms, 600ms delays)
โ
โผ
CLOUDFLARE WORKER
โ
โ 6. Validates again: โ 5 fields โ game_id โ email
โ
โ 7. Fires TWO tasks in parallel (Promise.allSettled)
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
GOOGLE APPS SCRIPT TELEGRAM BOT API
โ โ
โ 8a. POST JSON (3 retries) โ 8b. sendMessage (2 retries)
โ 200ms backoff โ MarkdownV2 format
โ โ
โ 9a. script.gs: โ ๐ NOVA INSCRIรรO
โ โ Parse JSON โ ๐ฑ Platform
โ โ Append row to Sheet โ ๐ฎ Game ID
โ โ {success: true} โ ๐ง Email ๐ Date
โ โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ
โผ
โ 10. Worker checks:
โ โ Sheet MUST succeed (or 502 error)
โ โ Telegram fail = silent (non-blocking)
โ โ Returns { success: true }
โ
โผ
BACK TO BROWSER
โ
โ 11. Success โ Hide form โ Show receipt โ Fill fields โ Scroll top
โ 12. 2s delay โ Auto-download receipt PNG (html2canvas)
โ 13. User can click "๐ฅ Baixar" or "Fazer outra inscriรงรฃo"
๐ File-by-File Breakdown
index.html โ Main Page| Section | ID / Class | Purpose |
|---|---|---|
| Header | .mcd-banner | POPFOI ร McDonald's logo bar |
| Banner Image | .banner-wrap > .banner-img | Hero banner with breathing animation |
| Form Page | #pageForm | Registration form (visible by default) |
| How It Works | .how-it-works | 3-step guide (recharge โ receive โ use) |
| Game ID | #gameId | 10-digit numeric input |
| Tier Table | #tierSection | Hidden until typing; shows R$ โ voucher tiers |
#email | Email with focus-triggered warning | |
| Email Warning | #emailWarning | "Check your email!" warning (hidden until focus) |
| Submit Button | #submitBtn | "๐ REGISTRE-SE! ๐" โ disables on submit |
| Receipt Page | #pageReceipt | Hidden; shown after successful submit |
| Receipt Card | #receiptCapture | Div captured by html2canvas for PNG |
| Receipt Fields | #rcptPlatform #rcptGameId #rcptEmail #rcptDate | Filled dynamically after submit |
| Download | #btnDownload | Manual receipt PNG download |
| Back Button | resetForm() | Reset form, show form page |
| Toast | #toast | Popup notification bar |
| Footer | .mcd-footer | "amo muito tudo issoโข" branding |
| DevTools Block | Inline <script> | Disables F12, Ctrl+Shift+I/J/C, Ctrl+U, right-click |
| Hidden Field | #platform | Always "POPFOI" (hidden input) |
src/app.js โ Core Application Logic| Function / Block | What It Does |
|---|---|
WORKER_URL | https://mcd.danilla-vargas1923.workers.dev |
loadHtml2Canvas() | Lazy-loads html2canvas from jsDelivr CDN |
Preload on window.load | Starts loading html2canvas 1s after page load (non-blocking) |
gameIdInput listener | Shows tier table on first keystroke |
email focus listener | Shows email warning on first focus |
showToast(msg) | Shows toast notification (3.5s duration) |
resetForm() | Clears form, hides receipt, scrolls to top |
generateTicketId() | Creates MCD-XXXX-XXXX ticket (defined but NOT used) |
getSaoPauloDate() | Gets current date in America/Sao_Paulo timezone |
formatDate(d) | โ "Mon, 09 Mar 2026" |
formatTime(d) | โ "14:30:05" |
showReceipt(...) | Fills receipt fields, toggles pages, auto-download after 2s |
downloadReceipt() | html2canvas captures #receiptCapture as PNG |
sendToWorker(data, retries) | POST to Worker with 3 retries; 4xx = no retry, 5xx = retry |
form.submit handler | Validate โ disable btn โ send โ receipt or error |
โ
Client-Side Validation Rules
- Game ID: exactly 10 digits (
/^\d{10}$/) - Email: basic format (
/^[^\s@]+@[^\s@]+\.[^\s@]+$/) - Both fields required
src/food-bg.js โ Background Animation| What | Detail |
|---|---|
| Emojis | ๐ ๐ ๐ฅค ๐ฆ ๐ฎ ๐ โ randomly chosen |
| Count | 12 floating emojis |
| Position | Left 0-20% or right 80-100% of screen |
| Animation | Float upward, 10-20s duration, random delay |
| Click Game | Click emoji โ burst animation + platform logo flash |
| Logos | bea.png foi.png luz.png n1.png sur.png zoe.png |
| Respawn | New emoji replaces clicked one after burst |
Cloudflare Worker/index.js โ Backend Proxy| Section | Detail |
|---|---|
| CORS | All origins (*), POST + OPTIONS only |
| Method Check | Only POST (405 for others) |
| Validation | 5 required fields, game_id 10 digits, valid email |
| Google Sheets | retryFetch() โ 3 attempts, 200ms backoff |
| Sheet Check | Verifies JSON {success:true} (not HTML error page) |
| Telegram | sendTelegram() โ 2 attempts, 300ms delay |
| Parallel | Sheet + Telegram via Promise.allSettled |
| Error Logic | Sheet fail โ 502; Telegram fail โ silent |
| Escaping | escapeMarkdown() for MarkdownV2 special chars |
Google App Script/script.gs โ Sheet Writer| What | Detail |
|---|---|
| Function | doPost(e) โ triggered by HTTP POST |
| Input | JSON from Cloudflare Worker |
| Columns | registered_date | registered_time | platform | game_id | email |
| Flush | SpreadsheetApp.flush() forces immediate write |
| Response | {success: true} or {success: false, error: "..."} |
src/style.css โ Styling (733 lines)| Area | Classes |
|---|---|
| Base | Red background #da291c, diagonal stripe pattern |
| Wrapper | .page-wrapper โ max 420px, centered, rounded |
| Banner | .mcd-banner โ top logo bar |
| Banner Image | .banner-img โ breathing animation (8s) |
| Form | .card โ white card, rounded corners |
| Inputs | Styled with focus glow, shake on invalid |
| Tier Table | .tier-table โ alternating rows, branded |
| Submit Button | .btn-submit โ golden gradient, shine effect |
| Receipt | .receipt-container โ zigzag edge card |
| Toast | .toast โ slide-up popup |
| Food BG | .bg-food span โ float upward animation |
๐ง Troubleshooting
Click any problem to expand the solution.
๐ซ Form submits but nothing happens / "Falha na conexรฃo"
โถ
- Browser Console โ Look for network errors or CORS issues
- Worker URL โ Is
https://mcd.danilla-vargas1923.workers.devalive?
Test:curl -X POST <URL> -H "Content-Type: application/json" -d '{"platform":"test","game_id":"1234567890","email":"t@t.com","registered_date":"x","registered_time":"x"}' - Worker Logs โ Cloudflare Dashboard โ Workers โ Logs
- Google Sheet URL โ Is Apps Script deployed as Web App?
Must be: Execute as Me, Access: Anyone
CheckGOOGLE_SHEET_URLenv var is set
๐ฉ Data saved to sheet but no Telegram notification
โถ
- Check
TG_BOT_TOKENenv var is set in Cloudflare Worker - Check
TG_CHAT_IDenv var is set in Cloudflare Worker - Bot must be added to the chat/group with send message permission
- Telegram failures are silent โ check Worker logs for
"Telegram attempt X"errors
๐ Google Sheet not receiving data
โถ
- Apps Script deployment โ Must be deployed as Web App (not just saved)
- Redeployment โ After editing
script.gs, create a New Deployment - Sheet permissions โ Script must have Sheets access authorized
- Worker env var โ
GOOGLE_SHEET_URLmust point to/execURL (not/dev) - Response format โ Worker checks for JSON
{success:true}; HTML = retry & fail
๐ธ Receipt image not downloading
โถ
- html2canvas CDN โ Check if
cdn.jsdelivr.netis reachable - Mixed content โ All images must be HTTPS or local
- CORS on images โ
useCORS: trueis set, but external images may block - Popup blocker โ Auto-download at 2s may be blocked; user can click "๐ฅ Baixar"
โ ๏ธ Form validation errors
โถ
| Error Message | Cause | Fix |
|---|---|---|
| "Preencha todos os campos!" | Empty game_id or email | Fill both fields |
| "ID do jogo deve ter exatamente 10 dรญgitos!" | Not 10 digits | Enter exactly 10 digits |
| Input shakes | Invalid game_id | Check digit count |
| "Por favor, insira um e-mail vรกlido." | Email fails regex | Enter valid email |
| "Dados invรกlidos" | Worker rejects (4xx) | Check validation rules |
๐ CORS errors in browser console
โถ
- Worker returns
Access-Control-Allow-Origin: *on all responses - Preflight (OPTIONS) returns 204 with CORS headers
- If you see CORS errors, the Worker may be down or misconfigured
- Check Cloudflare dashboard for Worker status
๐จ Page looks broken / unstyled
โถ
- Check
src/style.cssis loading (Network tab) - Check Google Fonts (
fonts.googleapis.com) is reachable - Check
media/images exist and are accessible - Clear browser cache
๐ Floating emojis not showing
โถ
food-bg.jsmust load after DOM (deferattribute)- Check console for JS errors
.bg-foodcontainer is prepended to<body>by the script@keyframes foodFloatmust exist in style.css
๐ Custom domain not working
โถ
CNAMEfile containspopfood.vip- DNS must point to GitHub Pages (or your host)
- HTTPS certificate must be provisioned (GitHub Pages โ Settings โ Pages)
- Cloudflare DNS proxy may interfere โ check DNS settings
๐ Environment Variables
Set in Cloudflare Workers โ Settings โ Variables
GOOGLE_SHEET_URL = https://script.google.com/macros/s/XXXX.../exec
TG_BOT_TOKEN = 123456:ABC-DEF...
TG_CHAT_ID = -100XXXXXXXXXX
TG_BOT_TOKEN = 123456:ABC-DEF...
TG_CHAT_ID = -100XXXXXXXXXX
๐ Key URLs & Endpoints
| What | URL |
|---|---|
| Live Site | https://popfood.vip |
| Worker API | https://mcd.danilla-vargas1923.workers.dev POST |
| Worker Dashboard | Cloudflare โ Workers & Pages โ mcd |
| Apps Script Editor | Google Apps Script dashboard โ find project |
| Google Sheet | Linked to Apps Script (getActiveSpreadsheet()) |
| html2canvas CDN | cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js |
| Fonts | fonts.googleapis.com (Nunito + Courier Prime) |
๐ How to Update / Redeploy
FRONTEND index.html, src/, media/
- Edit files locally
- Push to GitHub (or upload to static host)
- GitHub Pages auto-deploys from branch
WORKER Cloudflare Worker
- Edit
Cloudflare Worker/index.js - Cloudflare Dashboard โ Workers โ
mcdโ Quick Edit (or Wrangler CLI) - Paste updated code โ Save and Deploy
BACKEND Google Apps Script
- Edit
Google App Script/script.gs - Go to Apps Script editor โ paste code
- Deploy โ New Deployment (must create NEW, not just save)
- Copy the new
/execURL - Update
GOOGLE_SHEET_URLin Worker env vars if URL changed
โก Security Measures
| Measure | Where | What |
|---|---|---|
| DevTools Blocked | index.html | F12, Ctrl+Shift+I/J/C, Ctrl+U, Ctrl+S, right-click |
| Double Validation | app.js + Worker | Client AND server validate game_id & email |
| CORS Restricted | Worker | Only POST + OPTIONS allowed |
| Retry + Backoff | Client + Worker | 3x client, 3x sheet, 2x telegram |
| Error Isolation | Worker | Telegram fail doesn't block registration |
| Input Sanitization | Worker | MarkdownV2 chars escaped for Telegram |