From 662975dc085083833198af3106c58ef3695b11c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Gerhard=20Lindesva=CC=88rd?= Date: Wed, 3 Dec 2025 10:26:36 +0100 Subject: [PATCH] docs: add rust and ruby --- .../content/docs/(tracking)/sdks/index.mdx | 12 +- .../content/docs/(tracking)/sdks/meta.json | 2 + .../content/docs/(tracking)/sdks/ruby.mdx | 218 ++++++++++++++++++ .../content/docs/(tracking)/sdks/rust.mdx | 204 ++++++++++++++++ packages/sdks/_info/frameworks.tsx | 16 ++ packages/sdks/_info/icons/ruby-icon.tsx | 46 ++++ packages/sdks/_info/icons/rust-icon.tsx | 17 ++ 7 files changed, 514 insertions(+), 1 deletion(-) create mode 100644 apps/public/content/docs/(tracking)/sdks/ruby.mdx create mode 100644 apps/public/content/docs/(tracking)/sdks/rust.mdx create mode 100644 packages/sdks/_info/icons/ruby-icon.tsx create mode 100644 packages/sdks/_info/icons/rust-icon.tsx diff --git a/apps/public/content/docs/(tracking)/sdks/index.mdx b/apps/public/content/docs/(tracking)/sdks/index.mdx index c6ca11be..5bffc11b 100644 --- a/apps/public/content/docs/(tracking)/sdks/index.mdx +++ b/apps/public/content/docs/(tracking)/sdks/index.mdx @@ -81,6 +81,16 @@ For most web projects, we recommend starting with one of these: - ✅ Async support - ✅ Django and Flask compatible +- **[Rust](/docs/sdks/rust)** - Rust SDK for server-side tracking + - ✅ Async/await support + - ✅ Type-safe API + - ✅ Environment variable configuration + +- **[Ruby](/docs/sdks/ruby)** - Ruby SDK for server-side tracking + - ✅ Rails integration + - ✅ Gem-based installation + - ✅ Simple API + ## Mobile SDKs - **[React Native](/docs/sdks/react-native)** - Cross-platform mobile analytics @@ -108,7 +118,7 @@ Not sure which SDK to use? Here are some recommendations: - **Static website or HTML?** → Use [Script Tag](/docs/sdks/script) - **React app?** → Use [Web SDK](/docs/sdks/web) or [Script Tag](/docs/sdks/script) - **Next.js app?** → Use [Next.js SDK](/docs/sdks/nextjs) -- **Server-side tracking?** → Use [Python](/docs/sdks/python) or [Node](/docs/sdks/javascript) +- **Server-side tracking?** → Use [Python](/docs/sdks/python), [Rust](/docs/sdks/rust), [Ruby](/docs/sdks/ruby), or [Node](/docs/sdks/javascript) - **Mobile app?** → Use [React Native](/docs/sdks/react-native), [Swift](/docs/sdks/swift), or [Kotlin](/docs/sdks/kotlin) diff --git a/apps/public/content/docs/(tracking)/sdks/meta.json b/apps/public/content/docs/(tracking)/sdks/meta.json index 9e414baf..46af77e4 100644 --- a/apps/public/content/docs/(tracking)/sdks/meta.json +++ b/apps/public/content/docs/(tracking)/sdks/meta.json @@ -11,6 +11,8 @@ "remix", "express", "python", + "rust", + "ruby", "react-native", "swift", "kotlin", diff --git a/apps/public/content/docs/(tracking)/sdks/ruby.mdx b/apps/public/content/docs/(tracking)/sdks/ruby.mdx new file mode 100644 index 00000000..16fff43f --- /dev/null +++ b/apps/public/content/docs/(tracking)/sdks/ruby.mdx @@ -0,0 +1,218 @@ +--- +title: Ruby +--- + +import { Step, Steps } from 'fumadocs-ui/components/steps'; +import { Callout } from 'fumadocs-ui/components/callout'; +import CommonSdkConfig from '@/components/common-sdk-config.mdx'; + +The OpenPanel Ruby SDK allows you to track user behavior in your Ruby applications. This guide provides instructions for installing and using the Ruby SDK in your project. + + +View the [Ruby SDK on GitHub](https://github.com/tstaetter/openpanel-ruby-sdk) for the latest updates and source code. + + +## Installation + + +### Install dependencies + +If you're using Bundler, add to your `Gemfile`: + +```bash +bundle add openpanel-sdk +``` + +Or install the gem directly: + +```bash +gem install openpanel-sdk +``` + +### Set environment variables + +Set your environment variables in a `.env` file: + +```bash +OPENPANEL_TRACK_URL=https://api.openpanel.dev/track +OPENPANEL_CLIENT_ID= +OPENPANEL_CLIENT_SECRET= +``` + +### Initialize + +Require and initialize the OpenPanel SDK: + +```ruby +require 'openpanel-sdk' + +tracker = OpenPanel::SDK::Tracker.new +``` + +### Configuration Options + + + +Additional Ruby-specific options: + +- `disabled` - Set to `true` to disable all event tracking +- `env` - Environment name (e.g., `Rails.env.to_s`) + +```ruby +tracker = OpenPanel::SDK::Tracker.new( + { env: Rails.env.to_s }, + disabled: Rails.env.development? +) +``` + + + +## Usage + +### Tracking Events + +To track an event, use the `track` method: + +```ruby +tracker.track('test_event', payload: { name: 'test' }) +``` + +### Identifying Users + +Create an `IdentifyUser` object and pass it to the `identify` method: + +```ruby +identify_user = OpenPanel::SDK::IdentifyUser.new +identify_user.profile_id = 'user_123' +identify_user.email = 'user@example.com' +identify_user.first_name = 'John' +identify_user.last_name = 'Doe' +identify_user.properties = { tier: 'premium', company: 'Acme Inc' } + +response = tracker.identify(identify_user) +``` + +### Incrementing Properties + +To increment a numeric property on a user profile: + +```ruby +tracker.increment_property(identify_user, 'visits', 1) +``` + +### Decrementing Properties + +To decrement a numeric property on a user profile: + +```ruby +tracker.decrement_property(identify_user, 'credits', 1) +``` + +### Filtering Events + +Filters are used to prevent sending events to OpenPanel in certain cases. You can filter events by passing a `filter` lambda to the `track` method: + +```ruby +filter = lambda { |payload| + # Return true to send the event, false to skip it + payload[:name] == 'test' +} + +response = tracker.track('test_event', payload: { name: 'test' }, filter: filter) +# If filter returns false, response will be nil +``` + +## Rails Integration + +### Setting up the Tracker + +Add the following to your `application_controller.rb`: + +```ruby +before_action :set_openpanel_tracker + +protected + +def set_openpanel_tracker + @openpanel_tracker = OpenPanel::SDK::Tracker.new( + { env: Rails.env.to_s }, + disabled: Rails.env.development? + ) + @openpanel_tracker.set_header 'x-client-ip', request.ip + @openpanel_tracker.set_header 'user-agent', request.user_agent +end +``` + +### Tracking Events in Controllers + +Use `@openpanel_tracker` in your controllers to track events: + +```ruby +def create + @user = User.create(user_params) + @openpanel_tracker.track('user_created', payload: { user_id: @user.id }) + redirect_to @user +end +``` + +### Identifying Users + +Create a helper method to convert your app's user model to an `IdentifyUser`: + +```ruby +def identify_user_from_app_user(user, properties: {}) + iu = OpenPanel::SDK::IdentifyUser.new + iu.profile_id = user.id.to_s + iu.email = user.email + iu.first_name = user.first_name + iu.last_name = user.last_name + iu.properties = properties + iu +end + +# Usage in controller +def show + iu = identify_user_from_app_user(current_user) + @openpanel_tracker.identify(iu) +end +``` + +## Advanced Usage + +### Setting Custom Headers + +You can set custom headers for requests: + +```ruby +tracker.set_header 'x-client-ip', request.ip +tracker.set_header 'user-agent', request.user_agent +``` + +### Error Handling + +The SDK returns a `Faraday::Response` object. Check the response status: + +```ruby +response = tracker.track('event', payload: { name: 'test' }) +if response&.status == 200 + puts 'Event tracked successfully' +else + puts "Failed to track event: #{response&.status}" +end +``` + +### Disabling Tracking + +You can disable tracking during initialization or in specific environments: + +```ruby +# Disable during initialization +tracker = OpenPanel::SDK::Tracker.new({}, disabled: true) + +# Or disable in development +tracker = OpenPanel::SDK::Tracker.new( + { env: Rails.env.to_s }, + disabled: Rails.env.development? +) +``` + diff --git a/apps/public/content/docs/(tracking)/sdks/rust.mdx b/apps/public/content/docs/(tracking)/sdks/rust.mdx new file mode 100644 index 00000000..0face0d5 --- /dev/null +++ b/apps/public/content/docs/(tracking)/sdks/rust.mdx @@ -0,0 +1,204 @@ +--- +title: Rust +--- + +import { Step, Steps } from 'fumadocs-ui/components/steps'; +import { Callout } from 'fumadocs-ui/components/callout'; +import CommonSdkConfig from '@/components/common-sdk-config.mdx'; + +The OpenPanel Rust SDK allows you to track user behavior in your Rust applications. This guide provides instructions for installing and using the Rust SDK in your project. + + +View the [Rust SDK on GitHub](https://github.com/tstaetter/openpanel-rust-sdk/) for the latest updates and source code. + + +## Installation + + +### Install dependencies + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +openpanel-sdk = "0.1.0" +``` + +Or install via cargo: + +```bash +cargo add openpanel-sdk +``` + +### Set environment variables + +Set your environment variables in a `.env` file: + +```bash +OPENPANEL_TRACK_URL=https://api.openpanel.dev/track +OPENPANEL_CLIENT_ID= +OPENPANEL_CLIENT_SECRET= +``` + +### Initialize + +Import and initialize the OpenPanel SDK: + +```rust +use openpanel_sdk::sdk::Tracker; + +let tracker = Tracker::try_new_from_env()?.with_default_headers()?; +``` + +### Configuration Options + + + + + +## Usage + +### Tracking Events + +To track an event, use the `track` method: + +```rust +use std::collections::HashMap; +use openpanel_sdk::sdk::Tracker; + +let mut properties = HashMap::new(); +properties.insert("name".to_string(), "rust".to_string()); + +let response = tracker + .track("test_event".to_string(), Some(properties), None) + .await?; +``` + +### Identifying Users + +To identify a user, you need to convert your user struct into `user::IdentifyUser` by implementing the `From` trait: + +```rust +use std::collections::HashMap; +use openpanel_sdk::sdk::Tracker; +use openpanel_sdk::user; + +struct Address { + pub street: String, + pub city: String, + pub zip: String, +} + +struct AppUser { + pub id: String, + pub email: String, + pub first_name: String, + pub last_name: String, + pub address: Address, +} + +impl From
for HashMap { + fn from(address: Address) -> Self { + let mut properties = HashMap::new(); + properties.insert("street".to_string(), address.street); + properties.insert("city".to_string(), address.city); + properties.insert("zip".to_string(), address.zip); + properties + } +} + +impl From for user::IdentifyUser { + fn from(app_user: AppUser) -> Self { + Self { + profile_id: app_user.id, + email: app_user.email, + first_name: app_user.first_name, + last_name: app_user.last_name, + properties: app_user.address.into(), + } + } +} + +// Usage +let user = AppUser { /* ... */ }; +let response = tracker.identify(user.into()).await?; +``` + +### Incrementing Properties + +To increment a numeric property on a user profile: + +```rust +let response = tracker + .increment_property(profile_id, "visits", 1) + .await?; +``` + +### Decrementing Properties + +To decrement a numeric property on a user profile: + +```rust +let response = tracker + .decrement_property(profile_id, "credits", 1) + .await?; +``` + +### Filtering Events + +Filters are used to prevent sending events to OpenPanel in certain cases. You can filter events by passing a `filter` function to the `track` method: + +```rust +use std::collections::HashMap; + +let filter = |properties: HashMap| { + // Return true to send the event, false to skip it + properties.contains_key("required_key") +}; + +let mut properties = HashMap::new(); +properties.insert("name".to_string(), "rust".to_string()); + +let response = tracker + .track("test_event".to_string(), Some(properties), Some(&filter)) + .await; + +// If filter returns false, the event won't be sent and an Err is returned +match response { + Ok(_) => println!("Event sent successfully"), + Err(_) => println!("Event was filtered out"), +} +``` + +## Advanced Usage + +### Error Handling + +The SDK uses Rust's `Result` type for error handling. Always handle errors appropriately: + +```rust +match tracker.track("event".to_string(), Some(properties), None).await { + Ok(response) => { + if response.status() == 200 { + println!("Event tracked successfully"); + } + } + Err(e) => { + eprintln!("Failed to track event: {}", e); + } +} +``` + +### Async Runtime + +The SDK uses async/await. Make sure you're running within an async runtime (e.g., Tokio): + +```rust +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let tracker = Tracker::try_new_from_env()?.with_default_headers()?; + // ... use tracker + Ok(()) +} +``` + diff --git a/packages/sdks/_info/frameworks.tsx b/packages/sdks/_info/frameworks.tsx index e24dd979..e163eac2 100644 --- a/packages/sdks/_info/frameworks.tsx +++ b/packages/sdks/_info/frameworks.tsx @@ -11,6 +11,8 @@ import { RemixIcon } from './icons/remix-icon'; import { RestIcon } from './icons/rest-icon'; import { SwiftIcon } from './icons/swift-icon'; import { VueIcon } from './icons/vue-icon'; +import { RustIcon } from './icons/rust-icon'; +import { RubyIcon } from './icons/ruby-icon'; export type Framework = { key: string; @@ -98,6 +100,20 @@ export const frameworks: Framework[] = [ href: 'https://github.com/tbleckert/openpanel-laravel/tree/main', type: ['backend'], }, + { + key: 'rust', + IconComponent: RustIcon, + name: 'Rust', + href: 'https://openpanel.dev/docs/sdks/rust', + type: ['backend'], + }, + { + key: 'ruby', + IconComponent: RubyIcon, + name: 'Ruby', + href: 'https://openpanel.dev/docs/sdks/ruby', + type: ['backend'], + }, { key: 'ios', IconComponent: SwiftIcon, diff --git a/packages/sdks/_info/icons/ruby-icon.tsx b/packages/sdks/_info/icons/ruby-icon.tsx new file mode 100644 index 00000000..c96d53ac --- /dev/null +++ b/packages/sdks/_info/icons/ruby-icon.tsx @@ -0,0 +1,46 @@ +import type { IconProps } from './types'; + +export function RubyIcon({ className }: IconProps) { + return ( + + + + + + ); +} diff --git a/packages/sdks/_info/icons/rust-icon.tsx b/packages/sdks/_info/icons/rust-icon.tsx new file mode 100644 index 00000000..4e724227 --- /dev/null +++ b/packages/sdks/_info/icons/rust-icon.tsx @@ -0,0 +1,17 @@ +import type { IconProps } from './types'; + +export function RustIcon({ className }: IconProps) { + return ( + + + + ); +}