Scrapes FotMob and Sofascore for FC Barcelona match data and generates formatted match reports (text + charts) for posting on X.
- Hook insight — one sharp sentence, written last
- xG vs actual — over/under-performance
- Buildup & progression patterns
- Pressing structure — PPDA, triggers
- Opponent-specific exploits
- Set-piece breakdown
- Underused player / tactical wrinkle
- Visuals — shot map, xG timeline, pass map
- Forward-looking note
config/
config.js Team IDs, endpoint paths, request settings (placeholders for now)
src/
scrapers/
fotmob.js FotMob JSON endpoint calls
sofascore.js Sofascore JSON endpoint calls
processors/
normalize.js Merges both sources into one match object
insights/
index.js One function per report section, finds the findings
charts/
index.js Renders shot maps, xG timelines, pass maps as images
templates/
report.js Assembles insights + charts into the final report
index.js Pipeline entry point
data/
raw/ Cached raw scrape responses
reports/ Generated reports
npm install
cp .env.example .envSkeleton only — every module has TODOs. Next steps:
- Map real FotMob/Sofascore JSON endpoints (via browser dev tools,
Network tab, on an actual match page) and fill them into
config/config.js - Wire up
src/scrapers/fotmob.jsandsrc/scrapers/sofascore.jsagainst those real endpoints - Fill in
src/processors/normalize.jsonce we've seen real response shapes - Implement insight functions in
src/insights/index.js - Implement chart functions in
src/charts/index.js - Wire it all together in
src/index.js
FotMob and Sofascore's JSON endpoints are unofficial/internal — not public
APIs. Keep request frequency low (see config.request.minDelayMs), avoid
redistributing raw scraped data, and only publish transformative analysis
(insights/reports built from the data, not the raw data itself).