{"id":47115403,"url":"https://github.com/matthewgall/octoevents","last_synced_at":"2026-03-12T18:58:18.145Z","repository":{"id":314742456,"uuid":"1056591638","full_name":"matthewgall/octoevents","owner":"matthewgall","description":"A Go-based service that fetches Octopus Energy free electricity events using their GraphQL API and maintains a continuously updated JSON file via GitHub Actions.","archived":false,"fork":false,"pushed_at":"2025-12-12T18:37:44.000Z","size":119,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-14T09:26:14.110Z","etag":null,"topics":["free-electricity","free-electricity-sessions","github-actions","github-pages","go","goland","graphql","octopus","octopus-energy","octopus-energy-gb","octopus-energy-uk","octopusenergy","octopusenergygb","octopusenergyuk"],"latest_commit_sha":null,"homepage":"http://matthewgall.github.io/octoevents/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matthewgall.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":"2025-09-14T12:18:06.000Z","updated_at":"2025-12-12T18:37:42.000Z","dependencies_parsed_at":"2025-09-14T14:41:30.945Z","dependency_job_id":"c878c542-fcd5-42a8-b03e-3968b4fe5ce4","html_url":"https://github.com/matthewgall/octoevents","commit_stats":null,"previous_names":["matthewgall/octoevents"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/matthewgall/octoevents","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewgall%2Foctoevents","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewgall%2Foctoevents/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewgall%2Foctoevents/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewgall%2Foctoevents/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matthewgall","download_url":"https://codeload.github.com/matthewgall/octoevents/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matthewgall%2Foctoevents/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30439115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T14:34:45.044Z","status":"ssl_error","status_checked_at":"2026-03-12T14:09:33.793Z","response_time":114,"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":["free-electricity","free-electricity-sessions","github-actions","github-pages","go","goland","graphql","octopus","octopus-energy","octopus-energy-gb","octopus-energy-uk","octopusenergy","octopusenergygb","octopusenergyuk"],"created_at":"2026-03-12T18:58:17.365Z","updated_at":"2026-03-12T18:58:18.139Z","avatar_url":"https://github.com/matthewgall.png","language":"Go","funding_links":["https://github.com/sponsors/matthewgall"],"categories":[],"sub_categories":[],"readme":"# OctoEvents\n\nA Go-based service that fetches Octopus Energy free electricity events using their GraphQL API and maintains a continuously updated JSON file via GitHub Actions.\n\n## Features\n\n- Fetches free electricity events from Octopus Energy's GraphQL API\n- Merges new events with existing ones (never deletes events)\n- Prevents publishing empty files\n- Runs automatically every hour via GitHub Actions\n- Sorts events chronologically by start time\n\n## Setup\n\n### Configuration Methods\n\nThe application supports multiple configuration methods (in order of precedence):\n\n1. **Command Line Arguments** (highest priority)\n2. **Configuration File** (YAML)\n3. **Environment Variables** (lowest priority)\n\n### Command Line Usage\n\n```bash\n# Using command line flags\ngo run . -key sk_live_your_api_key_here -account A-12345678 -meter 1000000000000\n\n# Using config file\ngo run . -config config.yaml\n\n# Using environment variables\nexport OCTOPUS_API_KEY=\"sk_live_your_api_key_here\"\nexport ACCOUNT_NUMBER=\"A-12345678\" \nexport METER_POINT_ID=\"1000000000000\"\ngo run .\n\n# Custom output file and logging\ngo run . -key sk_live_your_api_key_here -account A-12345678 -meter 1000000000000 -output events.json\n\n# Log format options\ngo run . -config config.yaml -log-format text  # Human-readable logs\ngo run . -config config.yaml -log-format json  # Structured JSON logs  \ngo run . -config config.yaml -log-format auto  # Auto-detect (default)\n\n# Show version\ngo run . -version\n```\n\n### Configuration File\n\nCreate a `config.yaml` file:\n\n```yaml\naccountNumber: A-12345678\nmeterPointID: \"1000000000000\"\napiKey: sk_live_your_api_key_here\noutputFile: free_electricity.json\n```\n\n### GitHub Secrets\n\nFor GitHub Actions, configure these secrets:\n\n- `OCTOPUS_API_KEY`: Your Octopus Energy API key (e.g., \"sk_live_...\")\n- `ACCOUNT_NUMBER`: Your Octopus account number (e.g., \"A-12345678\")\n- `METER_POINT_ID`: Your electricity meter point ID (MPAN, e.g., \"1000000000000\")\n\n## Output\n\nThe service generates `free_electricity.json` containing an array of events with the following structure:\n\n```json\n{\n  \"data\": [\n    {\n      \"start\": \"2024-08-15T12:00:00.000Z\",\n      \"end\": \"2024-08-15T13:00:00.000Z\",\n      \"code\": \"1\"\n    },\n    {\n      \"start\": \"2024-11-27T11:00:00.000Z\",\n      \"end\": \"2024-11-27T12:00:00.000Z\",\n      \"code\": \"2\",\n      \"is_test\": true\n    }\n  ]\n}\n```\n\n### Fields\n\n- **data**: Array wrapper containing all events\n- **start**: Event start time in UTC (ISO 8601 format with milliseconds)\n- **end**: Event end time in UTC (ISO 8601 format with milliseconds)  \n- **code**: Sequential integer identifier starting from 1 (as string)\n- **is_test**: Optional boolean flag indicating test events (only appears when true)\n\n## How It Works\n\n1. GitHub Actions runs the Go application every hour\n2. The app authenticates with Octopus Energy using your API key to obtain a JWT token\n3. Using the JWT token, it fetches current events from Octopus Energy's GraphQL API\n4. Merges David Kendall's historical data with new events from Octopus GraphQL\n5. Events are deduplicated using start+end time as unique identifiers\n6. Sequential integer codes are assigned (1, 2, 3...)\n7. The file is only updated if new events are found\n8. Changes are automatically committed and deployed to GitHub Pages\n\nThis ensures a continuously growing dataset of historical and upcoming free electricity events.\n\n## Public API\n\nOnce deployed, the data will be available at:\n- **API Endpoint**: `https://matthewgall.github.io/octoevents/free_electricity.json`\n- **Documentation**: `https://matthewgall.github.io/octoevents/`\n\nThe API provides:\n- Real-time free electricity event data\n- Historical events from David Kendall's API merged with new Octopus data  \n- Sequential integer codes for easy reference\n- Optional `is_test` flags for test events\n- Automatic hourly updates\n- High availability via GitHub Pages\n\n## Authentication Flow\n\nThe service implements proper Octopus Energy authentication:\n- Uses your API key to obtain a JWT token via GraphQL mutation\n- Automatically refreshes the JWT token when it expires (with 5-minute buffer)\n- Includes all required headers to match browser behavior\n- Thread-safe token management with mutex locks\n\n## GitHub Pages Setup\n\nTo enable GitHub Pages deployment:\n\n1. Go to your repository Settings → Pages\n2. Set Source to \"GitHub Actions\"  \n3. The workflow will automatically deploy after each data update\n\n## Building and Versioning\n\n### Development Builds\n```bash\ngo build .                    # Version: git commit hash or \"dev\"\ngo run . -version             # Show current version\n```\n\n### Release Builds\n```bash\n# Build with explicit version\ngo build -ldflags \"-X main.buildVersion=1.0.0\" -o octoevents .\n\n# Build with version and commit\ngo build -ldflags \"-X main.buildVersion=1.0.0 -X main.buildCommit=$(git rev-parse HEAD)\" .\n```\n\n### Version Detection Strategy\n1. **Explicit version** via `-ldflags -X main.buildVersion=...` (highest priority)\n2. **Git commit hash** from build info (auto-detected)\n3. **Explicit commit** via `-ldflags -X main.buildCommit=...`\n4. **Fallback** to \"dev\" for local development\n\n## Performance Features\n\nThe service includes several optimizations:\n\n- **HTTP Connection Pooling**: Reuses connections for better performance\n- **Smart Caching**: Uses ETag conditional requests to avoid unnecessary downloads\n- **GitHub Actions Cache**: Persists cache data across workflow runs (daily rotation)\n- **Memory Optimization**: Pre-allocated data structures and efficient string handling\n- **Structured Logging**: JSON-formatted logs with contextual information\n- **Graceful Fallback**: Continues operation even if external API is unavailable\n\nCache benefits:\n- **First run**: Downloads David Kendall's data (~18 events)\n- **Subsequent runs**: Uses 304 Not Modified responses when data unchanged\n- **Daily rotation**: Cache keys rotate daily to ensure freshness\n\n## Support the Project\n\nIf you find OctoJoin useful, here are some ways to support its continued development:\n\n### 💷 Join Octopus Energy\n\nNot an Octopus Energy customer yet? Use my referral link to join and we'll both get £50 credit:\n\n**[Join Octopus Energy - Get £50 credit](https://share.octopus.energy/maize-ape-570)**\n\nThis helps fund development of OctoJoin and you'll get access to:\n- Saving Sessions (earn money for reducing usage during peak times)\n- Free electricity sessions (completely free electricity during certain periods)\n- Competitive energy rates and excellent customer service\n- The greenest energy supplier in the UK\n\n### ❤️ GitHub Sponsor\n\nSupport ongoing development and maintenance:\n\n**[Become a GitHub Sponsor](https://github.com/sponsors/matthewgall)**\n\nYour sponsorship helps with:\n- Adding new features and improvements\n- Maintaining compatibility with API changes  \n- Providing support and bug fixes\n- Keeping the project free and open source\n\n### ⭐ Star the Repository\n\nShow your appreciation by starring the repository on GitHub - it helps others discover the project!\n\n## Disclaimer\n\nThis is an unofficial third-party application developed independently. \"Octopus Energy\" is a trademark of Octopus Energy Group Limited. This application is not affiliated with, endorsed by, or connected to Octopus Energy Group Limited in any way.\n\nThe application interacts with publicly documented Octopus Energy APIs for data gathering purposes. Users are responsible for ensuring their use complies with Octopus Energy's terms of service.\n\n## License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewgall%2Foctoevents","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatthewgall%2Foctoevents","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatthewgall%2Foctoevents/lists"}