{"id":51787727,"url":"https://github.com/zmsp/appstore-analytics","last_synced_at":"2026-07-20T19:13:11.685Z","repository":{"id":372005550,"uuid":"1304700909","full_name":"zmsp/appstore-analytics","owner":"zmsp","description":"Automated analytics ingestion pipeline for Google Play Console \u0026 Apple App Store Connect. Sync active devices, installs, uninstalls, and crashes without sales tables via Node.js \u0026 Docker.","archived":false,"fork":false,"pushed_at":"2026-07-18T09:05:23.000Z","size":1433,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-18T09:13:43.712Z","etag":null,"topics":["andorid","app-analytics","app-store-connect-api","apple","appstore","devops-analytics","dockerized-dashboard","google-play-console","play-store-stats","playstore"],"latest_commit_sha":null,"homepage":"https://www.zobairshahadat.com/appstore-analytics/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zmsp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-18T07:33:58.000Z","updated_at":"2026-07-18T09:05:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zmsp/appstore-analytics","commit_stats":null,"previous_names":["zmsp/appstore-playstore-analytics-pipeline"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zmsp/appstore-analytics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmsp%2Fappstore-analytics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmsp%2Fappstore-analytics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmsp%2Fappstore-analytics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmsp%2Fappstore-analytics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zmsp","download_url":"https://codeload.github.com/zmsp/appstore-analytics/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmsp%2Fappstore-analytics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35696962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"ssl_error","status_checked_at":"2026-07-20T02:08:09.736Z","response_time":111,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["andorid","app-analytics","app-store-connect-api","apple","appstore","devops-analytics","dockerized-dashboard","google-play-console","play-store-stats","playstore"],"created_at":"2026-07-20T19:13:10.928Z","updated_at":"2026-07-20T19:13:11.672Z","avatar_url":"https://github.com/zmsp.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# App Store Stats Viewer\n\nA premium Node.js application for aggregating and visualizing install, active device, and uninstall metrics across the Google Play Store and Apple App Store.\n\nIncludes a web-based dashboard, a CLI for programmatic access, and a mock-data demo mode for local evaluation.\n\n![Dashboard Preview](docs/screenshot_dashboard.png)\n\n---\n\n## Live Demo\n[Explore the Dashboard Demo](https://www.zobairshahadat.com/appstore-analytics/)  \n*(Note: The demo is locked in Simulated Mode with rich sample data)*\n\n---\n\n## Quick Start (Docker)\n\n### Option A: Pre-built Image (Recommended)\nPull the latest image directly from the GitHub Container Registry.\n\n1. **Pull the image:**\n   ```bash\n   docker pull ghcr.io/zmsp/appstore-analytics:sha-65d8ec55f30974f879afd526106cdf21aea8a15b\n   ```\n\n2. **Prepare configuration:**\n   Create a `config` directory in your host path. Place your `config.json` and any required `.json` or `.p8` API keys inside it.\n\n3. **Run the container:**\n   ```bash\n   docker run -d \\\n     -p 3000:3000 \\\n     -v $(pwd)/data:/app/data \\\n     --name appstore-analytics \\\n     ghcr.io/zmsp/appstore-analytics:sha-65d8ec55f30974f879afd526106cdf21aea8a15b\n   ```\n   *Note: Place your `config.json` and keys directly inside the `data` directory on your host for persistent storage.*\n\n### Option B: Build from Source\n1. **Clone the repository:**\n   ```bash\n   git clone https://github.com/your-username/store_stat_viewer.git\n   cd store_stat_viewer\n   ```\n\n2. **Run via Docker Compose:**\n   ```bash\n   docker-compose up -d\n   ```\n\n3. **Access the Web UI:**\n   Navigate to `http://localhost:3000`.\n   - **Initial Setup**: You will be prompted to configure an admin password on the first run.\n   - **Demo Mode**: Toggle the switch in the sidebar to bypass authentication and preview the UI with simulated data.\n\n---\n\n## Key Features\n\n* **Web Dashboard**: Glassmorphic dark-themed UI with Chart.js visualizations for daily event trends, segmentable by country, OS version, app version, and device type.\n* **Multi-Platform Aggregation**: Unified data layer fetching from Google Play Console (via GCS exports) and Apple App Store Connect.\n* **Headless CLI**: Terminal utility for scripting, cron jobs, or rapid querying without the web interface.\n* **Self-Hosted \u0026 Secure**: Local data persistence and JWT-based authentication for the web interface. Service account keys remain on your host.\n\n---\n\n## Architecture \u0026 Data Flow\n\n### System Architecture\nThe backend is an Express-based Node.js server that handles API communication with Google Cloud Storage and App Store Connect, serving data to a single-page frontend.\n\n```mermaid\ngraph TD\n    subgraph Frontend\n        WebUI[Web Dashboard]\n        StaticConfig[static_config.json]\n    end\n\n    subgraph Backend\n        Server[Express Server]\n        CLI[CLI Utility]\n    end\n\n    subgraph Core Libraries\n        GCSLib[Google Play Lib]\n        AppleLib[App Store Lib]\n    end\n\n    subgraph External Data Sources\n        GCS[(Google Cloud Storage)]\n        AppStoreAPI[(App Store Connect API)]\n    end\n\n    User([User / Browser]) \u003c--\u003e WebUI\n    WebUI \u003c--\u003e Server\n    WebUI -- Read if Static --\u003e StaticConfig\n    Server --\u003e GCSLib\n    Server --\u003e AppleLib\n    CLI --\u003e GCSLib\n    \n    GCSLib \u003c--\u003e GCS\n    AppleLib \u003c--\u003e AppStoreAPI\n    \n    Server \u003c--\u003e LocalCache[(Local Cache)]\n```\n\n### CI/CD Pipeline\nPushes to the `main` branch trigger a GitHub Actions workflow that builds a new production Docker image (GHCR) and updates the static demo deployed to GitHub Pages.\n\n```mermaid\ngraph LR\n    Push[git push main] --\u003e GHA[GitHub Actions]\n    subgraph GitHub Actions\n        BuildDemo[Build Demo]\n        BuildDocker[Build Docker]\n    end\n    BuildDemo --\u003e GHPages[GitHub Pages]\n    BuildDocker --\u003e GHCR[GitHub Container Registry]\n    \n    GHPages --\u003e DemoUser([Public User])\n    GHCR --\u003e SelfHost([Self-Hosted Docker])\n```\n\n---\n\n## Prerequisites \u0026 Authentication Setup\n\n### 1. Google Play Console (GCS Exports)\nGoogle Play exports bulk reports directly into a Google Cloud Storage (GCS) bucket.\n\n#### A. Retrieve the GCP Service Account Key\n1. Go to the [Google Cloud IAM Service Accounts Console](https://console.cloud.google.com/iam-admin/serviceaccounts).\n2. Create a service account (e.g. `playstore-stats-reader`).\n3. In the **Keys** tab, click **Add Key** -\u003e **Create New Key** (JSON).\n4. Save the file to `config/keys/google_key.json`.\n\n#### B. Connect to your Play Console\n1. Go to the [Google Play Console](https://play.google.com/apps/publish) -\u003e **Users and Permissions**.\n2. Invite the service account email.\n3. Grant **\"View app information and download bulk reports (read-only)\"** permission.\n4. *Note: It can take up to 24 hours for bucket permissions to synchronize.*\n\n#### C. Find your Bucket Name\n1. In Play Console, go to **Download reports** -\u003e **Statistics**.\n2. Click **Copy Cloud Storage URI** (e.g. `gs://pubsite_prod_12345678/stats/installs/`).\n3. The bucket name is the part between `gs://` and the first slash: `pubsite_prod_12345678`.\n\n### 2. Apple App Store Connect\n1. Go to [App Store Connect](https://appstoreconnect.apple.com/) -\u003e **Users and Access** -\u003e **Keys**.\n2. Generate an API Key with **Sales and Reports** access.\n3. Download the `.p8` file and save it to `config/keys/apple_key.p8`.\n4. Note your **Issuer ID** and **Key ID**.\n\n---\n\n## Configuration\n\nThe dashboard and CLI look for a `config/config.json` file. Use the following template as a guide.\n\n```json\n[\n  {\n    \"name\": \"Production Account\",\n    \"projectID\": \"your-gcp-project-id\",\n    \"bucketName\": \"pubsite_prod_12345678\",\n    \"keyFilePath\": \"keys/google_key.json\",\n    \"appleIssuerId\": \"xxxx-xxxx-xxxx\",\n    \"appleKeyId\": \"XXXXXXXXXX\",\n    \"keyFilePath_apple\": \"keys/apple_key.p8\",\n    \"ignoredPackages\": [\"com.example.testapp\"]\n  }\n]\n```\n\n| Field | Platform | Description |\n|-------|----------|-------------|\n| `name` | Both | Display name for this configuration set. |\n| `projectID` | Google | Your Google Cloud Project ID. |\n| `bucketName` | Google | The GCS bucket name where Play Console exports reports. |\n| `keyFilePath` | Google | Path to the service account JSON key (relative to `config.json`). |\n| `appleIssuerId`| Apple | Issuer ID from App Store Connect API. |\n| `appleKeyId` | Apple | Key ID from App Store Connect API. |\n| `keyFilePath_apple` | Apple | Path to the `.p8` private key (relative to `config.json`). |\n| `ignoredPackages` | Google | Optional array of package names to hide from the dashboard. |\n\n---\n\n## Usage\n\n### CLI Utility\nYou can query your stats directly in the command line.\n\n**Option A: Using a Saved Project (Recommended)**\n```bash\n# Query the first project in config (index 0)\nnode app/cli.js -s 0\n\n# Query by project name\nnode app/cli.js -s \"Production Account\"\n```\n\n**Option B: Manual Parameters**\n```bash\nnode app/cli.js \\\n  --key=\"config/keys/google_key.json\" \\\n  --projectID=\"your-id\" \\\n  --bucketName=\"your-bucket\" \\\n  --packageName=\"com.example.app\"\n```\n\n#### CLI Options\n| Argument | Alias | Description |\n|----------|-------|-------------|\n| `--key` | `-k` | Path to the service account JSON key file |\n| `--project` | `-s` | Name or index of the saved project from config |\n| `--config` | `-c` | Path to `config.json` (defaults to `../config/config.json`) |\n| `--projectID`| `-g` | Google Cloud Project ID |\n| `--bucketName`| `-b` | Google Play Console GCS Bucket name |\n| `--packageName`|`-p` | App package identifier (e.g. `com.example.app`) |\n\n---\n\n## Project Structure\n\n```text\n.\n├── app/\n│   ├── lib/              # Core logic for GCS and App Store integration\n│   ├── public/           # Dashboard frontend (HTML/JS/CSS)\n│   ├── server.js         # Express API backend server\n│   └── cli.js            # Command-line utility\n├── config/               # User configuration and keys (GIT IGNORED)\n├── Dockerfile            # Multi-stage production Docker image\n└── docker-compose.yml    # Docker orchestration\n```\n\n---\n\n## License\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmsp%2Fappstore-analytics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzmsp%2Fappstore-analytics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmsp%2Fappstore-analytics/lists"}