Custom Analytics Providers
CommandKit's analytics system is designed to be extensible, allowing you to create custom analytics providers for your specific needs.
Creating a Custom Provider
To create a custom provider, implement the AnalyticsProvider
interface:
import {
AnalyticsProvider,
AnalyticsEvent,
IdentifyEvent,
} from 'commandkit/analytics';
class AnonymousAnalyticsProvider implements AnalyticsProvider {
readonly name = 'anonymous-analytics';
constructor(private readonly analytics: YourAnalyticsService) {}
async track(engine: AnalyticsEngine, event: AnalyticsEvent): Promise<void> {
// Implement your tracking logic here
const { name, data } = event;
// Example: Send anonymous data to your analytics service
await this.analytics.track({
name,
// Only include anonymous data
data: {
...data,
// Add anonymous session info
sessionId: this.generateSessionId(),
timestamp: Date.now(),
},
});
}
async identify(engine: AnalyticsEngine, event: IdentifyEvent): Promise<void> {
// Implement anonymous session identification
await this.analytics.identify({
// Use anonymous session identifiers
sessionId: this.generateSessionId(),
timestamp: Date.now(),
// Include anonymous session properties
properties: {
environment: process.env.NODE_ENV,
version: '1.0.0',
},
});
}
private generateSessionId(): string {
return 'session_' + Math.random().toString(36).substring(7);
}
}
Creating a Plugin
Create a plugin class that extends RuntimePlugin
:
import { CommandKitPluginRuntime, RuntimePlugin } from 'commandkit/plugin';
import { AnonymousAnalyticsProvider } from './provider';
export interface AnonymousAnalyticsPluginOptions {
analyticsOptions: {
apiKey: string;
options?: YourAnalyticsOptions;
};
}
export class AnonymousAnalyticsPlugin extends RuntimePlugin<AnonymousAnalyticsPluginOptions> {
public readonly name = 'AnonymousAnalytics';
private provider: AnonymousAnalyticsProvider | null = null;
public async activate(ctx: CommandKitPluginRuntime): Promise<void> {
const analytics = new YourAnalyticsService(
this.options.analyticsOptions.apiKey,
this.options.analyticsOptions.options,
);
this.provider = new AnonymousAnalyticsProvider(analytics);
ctx.commandkit.analytics.registerProvider(this.provider);
}
public async deactivate(ctx: CommandKitPluginRuntime): Promise<void> {
if (!this.provider) return;
// Cleanup if needed
await this.provider.analytics.shutdown?.();
ctx.commandkit.analytics.removeProvider(this.provider);
}
}
Using Your Custom Provider
Add your custom provider to your CommandKit configuration:
import { AnonymousAnalyticsPlugin } from './anonymous-analytics-plugin';
export default defineConfig({
plugins: [
new AnonymousAnalyticsPlugin({
analyticsOptions: {
apiKey: 'YOUR_API_KEY',
options: {
// Your analytics service options
},
},
}),
],
});
Best Practices
- Keep your provider implementation focused and single-purpose
- Handle errors gracefully and log them appropriately
- Implement both
track
andidentify
methods if your analytics service supports them - Use TypeScript for better type safety and developer experience
- Document your provider's configuration options and requirements
- Consider Discord's rate limits when sending data
- Only track anonymous, aggregated data
- Avoid storing personal information
- Use hashed identifiers when necessary
- Be transparent about what data you collect
Example: Simple Console Provider
Here's a simple example of a provider that logs anonymous events to the console:
import {
AnalyticsProvider,
AnalyticsEvent,
IdentifyEvent,
} from 'commandkit/analytics';
class ConsoleProvider implements AnalyticsProvider {
readonly name = 'console';
async track(engine: AnalyticsEngine, event: AnalyticsEvent): Promise<void> {
console.log('Analytics Event:', {
name: event.name,
// Only log anonymous data
data: {
...event.data,
timestamp: Date.now(),
},
});
}
async identify(engine: AnalyticsEngine, event: IdentifyEvent): Promise<void> {
console.log('Session Identified:', {
sessionId: 'session_' + Math.random().toString(36).substring(7),
timestamp: Date.now(),
environment: process.env.NODE_ENV,
});
}
}
// Plugin implementation
export class ConsoleAnalyticsPlugin extends RuntimePlugin {
public readonly name = 'ConsoleAnalytics';
private provider: ConsoleProvider | null = null;
public async activate(ctx: CommandKitPluginRuntime): Promise<void> {
this.provider = new ConsoleProvider();
ctx.commandkit.analytics.registerProvider(this.provider);
}
public async deactivate(ctx: CommandKitPluginRuntime): Promise<void> {
if (!this.provider) return;
ctx.commandkit.analytics.removeProvider(this.provider);
}
}
Next Steps
- Learn about PostHog analytics
- Learn about Umami analytics