Skip to main content
The @commandkit/analytics plugin integrates analytics tracking into your CommandKit bot. Monitor command usage, cache performance, and custom events with Umami or PostHog.

Installation

npm install @commandkit/analytics @umami/node

Providers

Umami

Umami is a privacy-focused, open-source analytics platform.
1

Setup Umami

Create an Umami account and get your website ID and API key.
2

Install and configure

src/index.ts
import { CommandKit } from 'commandkit';
import { umami } from '@commandkit/analytics/umami';

new CommandKit({
  client,
  plugins: [
    umami({
      umamiOptions: {
        websiteId: 'your-website-id',
        apiKey: 'your-api-key',
        hostUrl: 'https://analytics.umami.is', // or your self-hosted URL
      },
    }),
  ],
});
3

Track events

Events are automatically tracked by CommandKit.
// Command executions are tracked automatically
// Cache hits/misses are tracked automatically
// Custom events can be tracked manually

PostHog

PostHog is a powerful product analytics platform with feature flags and experimentation.
1

Setup PostHog

Create a PostHog account and get your project API key.
2

Install and configure

src/index.ts
import { CommandKit } from 'commandkit';
import { posthog } from '@commandkit/analytics/posthog';

new CommandKit({
  client,
  plugins: [
    posthog({
      posthogOptions: {
        apiKey: 'your-api-key',
        options: {
          host: 'https://app.posthog.com', // or your self-hosted URL
        },
      },
    }),
  ],
});
3

Track events

Events are automatically tracked by CommandKit.
// All bot activity is tracked

Tracked Events

CommandKit automatically tracks the following events:

Command Events

  • Command Execution - Every time a command is run
    • Event properties: command name, user ID, guild ID, execution time

Cache Events (when using @commandkit/cache)

  • Cache Hit - When cached data is used
    • Event properties: cache key, tags, retrieval time
  • Cache Miss - When data needs to be fetched
    • Event properties: cache key, tags, fetch time
  • Cache Revalidation - When cache is invalidated
    • Event properties: tag name

Manual Event Tracking

Track custom events in your commands:
src/commands/game.ts
import type { CommandRunOptions } from 'commandkit';

export const run: CommandRunOptions = async ({ interaction, context }) => {
  // Access analytics from CommandKit instance
  const analytics = context.commandkit.analytics;
  
  // Track custom event
  analytics.track({
    name: 'game_started',
    id: interaction.user.id,
    data: {
      gameType: 'trivia',
      difficulty: 'hard',
    },
  });
  
  await interaction.reply('Game started!');
};

Configuration

Umami Options

umamiOptions
object
required
Umami configuration options.
websiteId
string
required
Your Umami website ID.
apiKey
string
required
Your Umami API key.
hostUrl
string
required
Umami host URL (e.g., https://analytics.umami.is).

PostHog Options

posthogOptions
object
required
PostHog configuration options.
apiKey
string
required
Your PostHog project API key.
options
object
Additional PostHog client options.
host
string
PostHog host URL (default: https://app.posthog.com).
flushAt
number
Number of events to queue before sending (default: 20).
flushInterval
number
Time in milliseconds between automatic flushes (default: 10000).

Examples

Track Feature Usage

src/commands/premium.ts
import type { CommandRunOptions } from 'commandkit';

export const run: CommandRunOptions = async ({ interaction, context }) => {
  const analytics = context.commandkit.analytics;
  
  const isPremium = await checkPremiumStatus(interaction.user.id);
  
  analytics.track({
    name: 'premium_feature_access',
    id: interaction.user.id,
    data: {
      feature: 'advanced_stats',
      isPremium,
      guildId: interaction.guildId,
    },
  });
  
  if (!isPremium) {
    return interaction.reply('This feature requires premium!');
  }
  
  // Show premium feature
};

Track User Journey

src/commands/onboarding.ts
import type { CommandRunOptions } from 'commandkit';

export const run: CommandRunOptions = async ({ interaction, context }) => {
  const analytics = context.commandkit.analytics;
  const step = interaction.options.getString('step');
  
  analytics.track({
    name: 'onboarding_step',
    id: interaction.user.id,
    data: {
      step,
      timestamp: Date.now(),
    },
  });
  
  // Handle onboarding step
};

Track Errors

src/commands/risky.ts
import type { CommandRunOptions } from 'commandkit';

export const run: CommandRunOptions = async ({ interaction, context }) => {
  const analytics = context.commandkit.analytics;
  
  try {
    await riskyOperation();
  } catch (error) {
    analytics.track({
      name: 'command_error',
      id: interaction.user.id,
      data: {
        command: 'risky',
        error: error.message,
        stack: error.stack,
      },
    });
    
    await interaction.reply('An error occurred!');
  }
};

Track Performance

src/commands/search.ts
import type { CommandRunOptions } from 'commandkit';

export const run: CommandRunOptions = async ({ interaction, context }) => {
  const analytics = context.commandkit.analytics;
  const start = Date.now();
  
  const results = await searchDatabase(query);
  const duration = Date.now() - start;
  
  analytics.track({
    name: 'search_completed',
    id: interaction.user.id,
    data: {
      query,
      resultCount: results.length,
      duration,
      cached: false,
    },
  });
  
  await interaction.reply(`Found ${results.length} results`);
};

Using Multiple Providers

You can use both Umami and PostHog simultaneously:
src/index.ts
import { umami } from '@commandkit/analytics/umami';
import { posthog } from '@commandkit/analytics/posthog';

new CommandKit({
  client,
  plugins: [
    umami({
      umamiOptions: {
        websiteId: 'umami-id',
        apiKey: 'umami-key',
        hostUrl: 'https://analytics.umami.is',
      },
    }),
    posthog({
      posthogOptions: {
        apiKey: 'posthog-key',
      },
    }),
  ],
});

Analytics API

Access the analytics API from the CommandKit instance:
import { getCommandKit } from 'commandkit';

const commandkit = getCommandKit();
const analytics = commandkit.analytics;

// Track event
analytics.track({
  name: 'custom_event',
  id: 'user-123',
  data: { key: 'value' },
});

// Register custom provider
analytics.registerProvider(customProvider);

// Remove provider
analytics.removeProvider(provider);

Best Practices

Privacy First

Don’t track sensitive user data. Both Umami and PostHog offer privacy-focused features.

Meaningful Events

Track events that help you understand user behavior and improve your bot.

Use Properties

Add relevant data properties to events for better analysis.

Monitor Performance

Track execution times and cache performance to identify bottlenecks.

Self-Hosting

Both Umami and PostHog can be self-hosted:

Umami Self-Hosted

umami({
  umamiOptions: {
    websiteId: 'your-id',
    apiKey: 'your-key',
    hostUrl: 'https://analytics.yourdomain.com',
  },
})

PostHog Self-Hosted

posthog({
  posthogOptions: {
    apiKey: 'your-key',
    options: {
      host: 'https://posthog.yourdomain.com',
    },
  },
})

API Reference

umami(options)

Creates the Umami analytics plugin. Parameters:
  • options.umamiOptions - Umami configuration
Returns: UmamiPlugin

posthog(options)

Creates the PostHog analytics plugin. Parameters:
  • options.posthogOptions - PostHog configuration
Returns: PostHogPlugin

analytics.track(event)

Tracks a custom event. Parameters:
  • event.name - Event name
  • event.id - User or entity ID
  • event.data - Event properties (object)
Returns: void

analytics.registerProvider(provider)

Registers a custom analytics provider. Parameters:
  • provider - Analytics provider instance

analytics.removeProvider(provider)

Removes an analytics provider. Parameters:
  • provider - Analytics provider instance

Build docs developers (and LLMs) love