{"id":29798312,"url":"https://github.com/edimuj/cordova-plugin-gpgs","last_synced_at":"2025-07-28T07:15:57.943Z","repository":{"id":297389225,"uuid":"996604467","full_name":"edimuj/cordova-plugin-gpgs","owner":"edimuj","description":"Modern Cordova plugin for Google Play Games Services v2 API with comprehensive gaming features.","archived":false,"fork":false,"pushed_at":"2025-06-13T11:33:46.000Z","size":88,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-12T12:46:02.198Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","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/edimuj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2025-06-05T07:29:45.000Z","updated_at":"2025-06-13T11:33:50.000Z","dependencies_parsed_at":"2025-06-05T08:34:51.921Z","dependency_job_id":"efb7a275-91a2-490f-8a94-80dcb337fb08","html_url":"https://github.com/edimuj/cordova-plugin-gpgs","commit_stats":null,"previous_names":["edimuj/cordova-plugin-gpgs"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/edimuj/cordova-plugin-gpgs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edimuj%2Fcordova-plugin-gpgs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edimuj%2Fcordova-plugin-gpgs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edimuj%2Fcordova-plugin-gpgs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edimuj%2Fcordova-plugin-gpgs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edimuj","download_url":"https://codeload.github.com/edimuj/cordova-plugin-gpgs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edimuj%2Fcordova-plugin-gpgs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267477411,"owners_count":24093730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2025-07-28T07:15:53.800Z","updated_at":"2025-07-28T07:15:57.911Z","avatar_url":"https://github.com/edimuj.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Google Play Games Services Plugin for Cordova\n\nA modern Cordova plugin for Google Play Games Services v2 API with comprehensive gaming features.\n\n## Features\n\n- **Authentication**\n  - Manual silent sign-in via initialize()\n  - Background sign-out detection\n  - Manual sign-in support\n  - Sign-in state events\n  - Modern v2 authentication flow\n- **Leaderboards**\n  - Submit scores\n  - Show leaderboards\n  - Get player scores\n  - Get player rankings\n- **Achievements**\n  - Unlock achievements\n  - Increment achievements\n  - Show achievements UI\n  - Reveal hidden achievements\n  - Set achievement steps\n  - Load all achievements\n- **Cloud Saves**\n  - Save game data\n  - Load game data\n  - Show saved games UI\n  - Conflict resolution\n  - Snapshot management\n  - Delete a snapshot\n  - Load all snapshots\n- **Friends**\n  - Get friends list\n  - Show player profiles\n  - Player search\n  - Compare profiles\n- **Player Stats**\n  - Get player info\n  - Get player stats\n  - Get player level info\n- **Events**\n  - Increment events\n  - Get event data\n  - Get all events\n  - Event tracking\n\n## Requirements\n\n- Cordova \u003e= 12.0.0\n- Cordova Android \u003e= 14.0.0\n- Android SDK \u003e= 24\n- Google Play Services \u003e= 21.2.0\n\n## Installation\n\n```bash\ncordova plugin add cordova-plugin-gpgs --variable APP_ID=\"your-app-id\" --variable PLAY_SERVICES_VERSION=\"23.2.0\"\n```\n\n### Configuration Variables\n\n- `APP_ID` (required): Your Google Play Games App ID\n- `PLAY_SERVICES_VERSION` (optional): Version of Google Play Services to use (default: 23.2.0)\n\n## Configuration\n\nAdd the following to your `config.xml`:\n\n```xml\n\u003cpreference name=\"GPGS_DEBUG\" value=\"true\" /\u003e\n```\n\n## Usage\n\n### Initialization\n\nCall `initialize()` once after `deviceready`. It performs a silent sign-in and fires the usual events (`gpgs.signin`, `gpgs.signout`, `gpgs.availability`). All Play Games API calls that require authentication should be made after the `gpgs.signin` event has fired.\n\n```javascript\ndocument.addEventListener('deviceready', () =\u003e {\n    GPGS.initialize()\n        .then(() =\u003e {\n            console.log('GPGS initialization request sent');        \n        })\n        .catch(console.error);\n});\n```\n\nThe plugin NO LONGER attempts silent sign-in automatically; you are in full control of when the operation happens.\n\n### Authentication\n\n```javascript\n// Check if Google Play Services are available\nGPGS.isGooglePlayServicesAvailable().then(result =\u003e {\n    if (result === true) {\n        console.log('Google Play Services are available');\n    } else if (typeof result === 'object') {\n        console.log('Google Play Services are not available:', result.errorString);\n        if (result.isUserResolvable) {\n            // Show UI to help user resolve the issue\n        }\n    }\n});\n// Returns: Promise\u003cboolean|Object\u003e - If services are not available, returns an object with:\n// {\n//   available: false,\n//   errorCode: number,\n//   errorString: string,\n//   isUserResolvable: boolean\n// }\n\n// Check if user is signed in\nGPGS.isSignedIn().then(result =\u003e {\n    if (typeof result === 'object') {\n        console.log('Sign-in status:', result.isSignedIn);\n    } else {\n        console.log('Sign-in status:', result);\n    }\n});\n// Returns: Promise\u003cboolean|Object\u003e - Returns either a boolean or an object with:\n// {\n//   isSignedIn: boolean\n// }\n\n// Manual sign-in\nGPGS.login().then(() =\u003e {\n    console.log('Sign-in successful');\n}).catch(error =\u003e {\n    console.error('Sign-in failed:', error);\n});\n// Returns: Promise\u003cvoid\u003e\n```\n\n### Leaderboards\n\n```javascript\n// Submit a score\nGPGS.submitScore('leaderboard_id', 1000).then(() =\u003e {\n    console.log('Score submitted');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Show a leaderboard\nGPGS.showLeaderboard('leaderboard_id').then(() =\u003e {\n    console.log('Leaderboard shown');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Show all leaderboards\nGPGS.showAllLeaderboards().then(() =\u003e {\n    console.log('All leaderboards shown');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Get player's score\nGPGS.getPlayerScore('leaderboard_id').then(score =\u003e {\n    console.log('Player score:', score);\n});\n// Returns: Promise\u003c{\n//   player_score: number,\n//   player_rank: number\n// }\u003e\n\n// --- Parameter enums ------------------------------------------------------\n// timeSpan   → 0 = daily, 1 = weekly, 2 = all-time\n// collection → 0 = public, 1 = friends\n// For richer code samples see: examples/scores.md\n\n// Load top scores for a leaderboard\nGPGS.loadTopScores('leaderboard_id', 2 /*all-time*/, 0 /*public*/, 25).then(result =\u003e {\n    console.log('Leaderboard:', result.leaderboard);\n    console.log('Scores:', result.scores);\n});\n// Returns: Promise\u003cObject\u003e\n\n// -------------------------------------------------------------------------\n// See examples/scores.md for showing a leaderboard slice around the player\n\n// Load scores centered around the signed-in player\nGPGS.loadPlayerCenteredScores('leaderboard_id', 2 /*all-time*/, 0 /*public*/, 25).then(result =\u003e {\n    console.log('Leaderboard:', result.leaderboard);\n    console.log('Scores:', result.scores);\n});\n// Returns: Promise\u003cObject\u003e\n\n// Load metadata for a single leaderboard\nGPGS.loadLeaderboardMetadata('leaderboard_id').then(metadata =\u003e {\n    console.log('Leaderboard Metadata:', metadata);\n});\n// Returns: Promise\u003cObject\u003e\n\n// Load metadata for all leaderboards\nGPGS.loadLeaderboardMetadata().then(metadata =\u003e {\n    console.log('All Leaderboards Metadata:', metadata);\n});\n// Returns: Promise\u003cArray\u003cObject\u003e\u003e\n```\n\n### Achievements\n\n```javascript\n// Unlock an achievement\nGPGS.unlockAchievement('achievement_id').then(() =\u003e {\n    console.log('Achievement unlocked');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Increment an achievement\nGPGS.incrementAchievement('achievement_id', 1).then(() =\u003e {\n    console.log('Achievement incremented');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Show achievements UI\nGPGS.showAchievements().then(() =\u003e {\n    console.log('Achievements UI shown');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Reveal a hidden achievement\nGPGS.revealAchievement('achievement_id').then(() =\u003e {\n    console.log('Achievement revealed');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Set achievement steps\nGPGS.setStepsInAchievement('achievement_id', 5).then(() =\u003e {\n    console.log('Achievement steps set');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Load all achievements\nGPGS.loadAchievements(false).then(achievements =\u003e {\n    console.log('Achievements:', achievements);\n});\n// Returns: Promise\u003cArray\u003cObject\u003e\u003e\n\n// Get friends list\nGPGS.getFriendsList().then(friends =\u003e {\n    console.log('Friends:', friends);\n});\n// Returns: Promise\u003cArray\u003c{\n//   id: string,\n//   displayName: string\n// }\u003e\u003e\n\n// Show player profile\nGPGS.showPlayerProfile('player_id').then(() =\u003e {\n    console.log('Player profile shown');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Show player search\nGPGS.showPlayerSearch().then(() =\u003e {\n    console.log('Player search shown');\n});\n// Returns: Promise\u003cvoid\u003e\n```\n\n### Cloud Saves\n\n```javascript\n// Save game data\nGPGS.saveGame('save_name', 'description', {\n    level: 1,\n    score: 1000\n}).then(() =\u003e {\n    console.log('Game saved');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Load game data\nGPGS.loadGame('save_name').then(data =\u003e {\n    console.log('Game loaded:', data);\n});\n// Returns: Promise\u003cObject\u003e - The saved game data\n\n// Show saved games UI\nGPGS.showSavedGames({\n    title: 'Saved Games',\n    allowAddButton: true,\n    allowDelete: true,\n    maxSnapshots: 5\n}).then(() =\u003e {\n    console.log('Saved games UI shown');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Delete a snapshot\nGPGS.deleteSnapshot('save_name').then(snapshotId =\u003e {\n    console.log('Snapshot deleted:', snapshotId);\n});\n// Returns: Promise\u003cstring\u003e\n\n// Load all snapshots\nGPGS.loadAllSnapshots(false).then(snapshots =\u003e {\n    console.log('All snapshots:', snapshots);\n});\n// Returns: Promise\u003cArray\u003cObject\u003e\u003e\n```\n\n### Player Stats\n\n```javascript\n// Get player info\nGPGS.getPlayerInfo('player_id', true).then(info =\u003e {\n    console.log('Player info:', info);\n});\n// Returns: Promise\u003c{\n//   id: string,\n//   displayName: string,\n//   title: string,\n//   levelInfo?: {\n//     currentLevel: number,\n//     maxXp: number,\n//     minXp: number\n//   }\n// }\u003e\n\n// Get player stats\nGPGS.getPlayerStats().then(stats =\u003e {\n    console.log('Player stats:', stats);\n});\n// Returns: Promise\u003c{\n//   averageSessionLength: number,\n//   daysSinceLastPlayed: number,\n//   numberOfPurchases: number,\n//   numberOfSessions: number,\n//   sessionPercentile: number,\n//   spendPercentile: number,\n//   spendProbability: number\n// }\u003e\n```\n\n### Events\n\n```javascript\n// Increment an event\nGPGS.incrementEvent('event_id', 1).then(() =\u003e {\n    console.log('Event incremented');\n});\n// Returns: Promise\u003cvoid\u003e\n\n// Get all events\nGPGS.getAllEvents().then(events =\u003e {\n    console.log('All events:', events);\n});\n// Returns: Promise\u003cArray\u003c{\n//   id: string,\n//   name: string,\n//   description: string,\n//   value: number\n// }\u003e\u003e\n\n// Get specific event\nGPGS.getEvent('event_id').then(event =\u003e {\n    console.log('Event:', event);\n});\n// Returns: Promise\u003c{\n//   id: string,\n//   name: string,\n//   description: string,\n//   value: number\n// }\u003e\n```\n\n## Events\n\nThe plugin emits the following events:\n\n### `gpgs.signin`\nEmitted when sign-in state changes.\n```javascript\n{\n    isSignedIn: boolean,\n    error?: string  // Present if sign-in failed\n}\n```\n\n### `gpgs.signout`\nEmitted when user signs out (including background sign-out).\n```javascript\n{\n    isSignedIn: false,\n    reason: string  // e.g., \"background_signout\"\n}\n```\n\n### `gpgs.availability`\nEmitted when Google Play Services availability changes.\n```javascript\n{\n    available: boolean,\n    errorCode?: number,\n    errorString?: string,\n    isUserResolvable?: boolean\n}\n```\n\n## Error Handling\n\nThe plugin uses promises for all operations. Errors are passed to the catch handler:\n```javascript\nGPGS.login().catch(error =\u003e {\n    console.error('Error:', error.message, 'Status Code:', error.statusCode);\n});\n```\n\nThe error object contains:\n- `message`: A descriptive error message\n- `statusCode`: The status code from the underlying Google Play Games SDK (if available)\n\nCommon error codes from the SDK can be found in the official documentation.\n\n## Debug Mode\n\nEnable debug mode in `config.xml` to see detailed logs:\n```xml\n\u003cpreference name=\"GPGS_DEBUG\" value=\"true\" /\u003e\n```\n\n## License\n\nThis project is licensed under the GPL-3.0-or-later License - see the [LICENSE](LICENSE) file for details.\n\n## Author\n\nExelerus AB - [https://exelerus.com](https://exelerus.com)\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## Examples\n\n- [Listening to sign-in events](examples/events.md)\n- [Working with leaderboards \u0026 scores](examples/scores.md)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedimuj%2Fcordova-plugin-gpgs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedimuj%2Fcordova-plugin-gpgs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedimuj%2Fcordova-plugin-gpgs/lists"}