LogoRobo.js

Configuration

Plugin options, environment variables, and auto-detection behavior.

Configure the analytics plugin through environment variables, a plugin config file, or both.

Environment variables

The simplest way to configure the plugin. Add these to your .env file:

Google Analytics

.env
GOOGLE_ANALYTICS_MEASURE_ID="G-XXXXXXXXX"
GOOGLE_ANALYTICS_SECRET="your-api-secret"
VariableRequiredDescription
GOOGLE_ANALYTICS_MEASURE_IDYesGA4 Measurement ID (starts with G-)
GOOGLE_ANALYTICS_SECRETYesMeasurement Protocol API Secret

Plausible

.env
PLAUSIBLE_DOMAIN="example.com"
VariableRequiredDescription
PLAUSIBLE_DOMAINYesSite domain registered in Plausible

Plugin options

Create a config file for advanced setup. The only option is engine, which overrides auto-detection entirely.

config/plugins/robojs/analytics.mjs
export default {
	engine: undefined // Optional: custom BaseEngine instance
}
config/plugins/robojs/analytics.mjs
export default {
	engine: undefined // Optional: custom BaseEngine instance
}

Prop

Type

Examples

Use Google Analytics with explicit credentials:

config/plugins/robojs/analytics.mjs
import { GoogleAnalytics } from '@robojs/analytics'

export default {
	engine: new GoogleAnalytics({
		measureId: 'G-XXXXXXXXX',
		token: 'your-api-secret'
	})
}
config/plugins/robojs/analytics.mjs
import { GoogleAnalytics } from '@robojs/analytics'

export default {
	engine: new GoogleAnalytics({
		measureId: 'G-XXXXXXXXX',
		token: 'your-api-secret'
	})
}

Use Plausible with explicit domain:

config/plugins/robojs/analytics.mjs
import { PlausibleAnalytics } from '@robojs/analytics'

export default {
	engine: new PlausibleAnalytics('example.com')
}
config/plugins/robojs/analytics.mjs
import { PlausibleAnalytics } from '@robojs/analytics'

export default {
	engine: new PlausibleAnalytics('example.com')
}

Use multiple services:

config/plugins/robojs/analytics.mjs
import { GoogleAnalytics, PlausibleAnalytics, ManyEngines } from '@robojs/analytics'

export default {
	engine: new ManyEngines(
		new GoogleAnalytics(),
		new PlausibleAnalytics()
	)
}
config/plugins/robojs/analytics.mjs
import { GoogleAnalytics, PlausibleAnalytics, ManyEngines } from '@robojs/analytics'

export default {
	engine: new ManyEngines(
		new GoogleAnalytics(),
		new PlausibleAnalytics()
	)
}

When using ManyEngines in the config file, engine constructors still fall back to environment variables for their credentials.

Auto-detection

When no engine is set in the config, the plugin reads environment variables at startup and creates the appropriate engine automatically.

Environment variables presentEngine created
GOOGLE_ANALYTICS_MEASURE_ID + PLAUSIBLE_DOMAINManyEngines(GoogleAnalytics, PlausibleAnalytics)
GOOGLE_ANALYTICS_MEASURE_ID onlyGoogleAnalytics
PLAUSIBLE_DOMAIN onlyPlausibleAnalytics
NeitherNo engine. Warning logged.

This detection runs in the plugin's start lifecycle hook (src/robo/start.ts). If a custom engine is provided in the config, auto-detection is skipped entirely.

Setting both Google Analytics and Plausible environment variables automatically sends events to both services. No ManyEngines config needed.

Initialization lifecycle

The plugin initializes during the Robo start lifecycle hook (src/robo/start.ts):

Check for custom engine

If engine is set in plugin options, use it directly. Skip to step 3.

Auto-detect from environment

Check for GOOGLE_ANALYTICS_MEASURE_ID and PLAUSIBLE_DOMAIN. Create the appropriate engine(s) or log a warning if neither is set.

Freeze and activate

The engine is frozen with Object.freeze() and stored in the Analytics singleton. Analytics.isReady() now returns true.

After initialization, the Analytics object and its engine are immutable. They cannot be changed at runtime.

Seed files

When installed with npx robo add @robojs/analytics, the plugin seeds three files into your project:

test-analytics.ts/test-analytics
guildCreate.tsTracks server joins
track-commands.tsAuto-tracks commands
Seed fileTarget pathPurpose
track-commands.tssrc/middleware/track-commands.tsMiddleware that tracks every slash command automatically
test-analytics.tssrc/commands/test-analytics.tsTest command to verify analytics integration
guildCreate.tssrc/events/guildCreate.tsTracks server_join when the bot joins a new server

Command tracking middleware

The seeded middleware intercepts all slash commands and sends an event:

src/middleware/track-commands.ts
import { Analytics } from '@robojs/analytics'
import type { ChatInputCommandInteraction } from 'discord.js'
import type { MiddlewareData } from '@robojs/discordjs'

export default async (data: MiddlewareData) => {
	const { payload, record } = data

	if (record.type === 'command') {
		const interaction = payload[0] as ChatInputCommandInteraction
		const name = record.key.replaceAll('/', '_').replaceAll('-', '_')

		Analytics.event(name, {
			data: { type: 'slash_command' },
			sessionId: interaction.channelId ?? interaction.guildId,
			userId: interaction.user?.id
		})
	}
}
src/middleware/track-commands.js
import { Analytics } from '@robojs/analytics'

export default async (data) => {
	const { payload, record } = data

	if (record.type === 'command') {
		const interaction = payload[0]
		const name = record.key.replaceAll('/', '_').replaceAll('-', '_')

		Analytics.event(name, {
			data: { type: 'slash_command' },
			sessionId: interaction.channelId ?? interaction.guildId,
			userId: interaction.user?.id
		})
	}
}

Command names are normalized: /moderation/ban becomes moderation_ban. This fires for every slash command without requiring per-command tracking code.

Server join tracking

The seeded event handler requires the Guilds intent:

src/events/guildCreate.ts
import { Analytics } from '@robojs/analytics'
import type { Guild } from 'discord.js'

export default (guild: Guild) => {
	Analytics.event('server_join', {
		data: { name: guild.name, type: 'event' },
		sessionId: guild.id
	})
}
src/events/guildCreate.js
import { Analytics } from '@robojs/analytics'

export default (guild) => {
	Analytics.event('server_join', {
		data: { name: guild.name, type: 'event' },
		sessionId: guild.id
	})
}

Enable the intent in your Discord plugin config if you want this tracking:

config/plugins/robojs/discordjs.mjs
export default {
	clientOptions: {
		intents: ['Guilds']
	}
}
config/plugins/robojs/discordjs.mjs
export default {
	clientOptions: {
		intents: ['Guilds']
	}
}

Next Steps

On this page