{"id":"khanpython/analytics-service-wrapper","name":"analytics-service-wrapper","scope":"khanpython","platform":"roblox","description":"A Promise-based Analytics Service Wrapper for Roblox.","version":"3.1.1","latest":"3.1.1","versions":["1.0.0","1.1.0","1.2.0","1.3.0","1.4.0","1.5.0","2.0.0","2.0.1","2.1.0","2.2.0","3.1.0","3.1.1"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{"evaera/promise":{"version":"^4.0.0","alias":"promise"}},"integrity":"4e8340490cfd8aaa1d8521905a0ff96352590de025c0cb4e26daeff08838f709","likes":0,"downloads":0,"install":"forest install khanpython/analytics-service-wrapper","url":"https://forest.dev/p/roblox/khanpython/analytics-service-wrapper","files":"https://api.forest.dev/ai/package/roblox/khanpython/analytics-service-wrapper/files","readme":"<div align=\"center\">\r\n\t<h1>Analytics Service Wrapper</h1>\r\n  <p>A promise-based Analytics Service wrapper for Roblox.</p>\r\n</div>\r\n\r\n\r\n### Features:\r\n\r\n- **Queuing System:** Ensures all analytics events are processed without throttling (FIFO-basis).\r\n- **Promise-Based API:** Handles unexpected errors during execution, logging problems while maintaining overall service functionality.\r\n- **Type Safe-Guarding**: Protects against invalid or malformed inputs, such as empty lists or incorrect data types, with strict validation mechanisms.\r\n\r\n---\r\n\r\n### Installation via Wally:\r\n\r\n1. Ensure you have the [Wally package manager](https://github.com/UpliftGames/wally) installed on your system.\r\n2. Add the following line to your `wally.toml` file under the `[dependencies]` section:\r\n   ```toml\r\n   analytics-service-wrapper = \"khanpython/analytics-service-wrapper@3.1.1\"\r\n   ```\r\n3. Run the Wally install command to download and integrate the package:\r\n    ```bash\r\n    wally install\r\n    ```\r\n4. The package will be placed in your Packages folder. Use the following code snippet to require it in your project:\r\n    ```lua\r\n    local AnalyticsServiceWrapper = require(path-to-package)\r\n    ```\r\n\r\n---\r\n\r\n\r\n### Methods:\r\n\r\nThis wrapper includes all methods provided by the default Analytics Service, with the exception of ProgressionEvents. For detailed information on the available parameters, visit the official [Analytics Service Documentation](https://create.roblox.com/docs/reference/engine/classes/AnalyticsService#summary).\r\n\r\n- **`LogCustomEvent(player, eventName, value?, customFields?)`**\r\n  - Logs a custom event with optional value and custom fields.\r\n- **`LogEconomyEvent(player, flowType, currencyType, amount, endingBalance, transactionType, itemSKU?, customFields?)`**\r\n  - Logs an economic event, such as purchases or earnings.\r\n- **`LogFunnelStep(player, funnelName, funnelSessionId?, stepNumber, stepName?, customFields?)`**\r\n  - Logs a step in the funnel. If no funnelSessionId is provided, then a GUID will be generated.\r\n- **`LogOnboardingFunnelStep(player, stepNumber, stepName?, customFields?)`**\r\n  - Logs a step in the onboarding funnel.\r\n- **`AnalyticsWrapper:ForValues(callback, playerList)`**\r\n  - Iterates through a list of players, executing a callback function for each. The callback must return a promise. Promise rejection here will not throw a rejection to the overall operation.\r\n---\r\n\r\n### Example Usage:\r\n\r\n#### 1. Log a Funnel Step\r\n\r\n```lua\r\nAnalyticsWrapper:LogFunnelStep(player, \"LevelProgression\", 2, \"LevelStart\")\r\n    :andThen(function()\r\n        print(\"Funnel step logged successfully.\")\r\n    end)\r\n    :catch(function(errMessage)\r\n        warn(\"Error logging funnel step: \" .. tostring(errMessage))\r\n    end)\r\n```\r\n\r\n#### 2. Log Events for Multiple Players\r\n\r\n```lua\r\nAnalyticsWrapper:ForValues(function(player: Player)\r\n        return AnalyticsWrapper:LogFunnelStep(player, \"RoundProgression\", 1, \"Lobby\")\r\n    end, Players:GetPlayers())\r\n    :catch(function(errMessage)\r\n        warn(\"Unable to log funnel step: \" .. tostring(errMessage))\r\n    end)\r\n```\r\n\r\n---\r\n### FAQ (WIP):\r\n1. **How are actions processed from the queue?**\r\n   \r\n   A background loop runs continuously ensuring that For each player and event type:\r\n   - The system checks if the cooldown for the event type has expired.\r\n   - If the cooldown has expired, the first action in the queue is removed using table.remove.\r\n   - The action is executed, and any success or failure is handled through the `resolve` or `reject` callbacks.\r\n---\r\n2. **How does rate-limiting work in the queue?**\r\n   \r\n    It attempts to adhere to the limits imposed by Roblox using `120 + (20 * CCU)`. The global CCU is retrieved using [`MessagingService`](https://create.roblox.com/docs/reference/cloud/messaging-service/v1) API. \r\n\r\n3. **What happens if a funnel step is logged out of sequence?**\r\n\r\n    The wrapper ensures that funnel steps are logged in order of precedence. If a step number is less than or equal to the highest previously logged step for a specific `funnelSessionId` (if relevant), the wrapper will reject the action with an error message indicating the issue. This safeguard prevents duplicate or incorrect step logging. Read more on [Repeated steps](https://create.roblox.com/docs/production/analytics/funnel-events#repeated-steps) and [Skipped steps](https://create.roblox.com/docs/production/analytics/funnel-events#skipping-steps).\r\n---\r\n### Resources:\r\n\r\n- [Promises and Why You Should Use Them](https://devforum.roblox.com/t/promises-and-why-you-should-use-them/350825)\r\n- [Official Analytics Service Documentation](https://create.roblox.com/docs/reference/engine/classes/AnalyticsService#summary)","readmeTruncated":false}