Appearance
API Reference
initNewttrace(config)
Initialize the SDK with automatic Discord client hooks.
ts
import { initNewttrace } from "newttrace";
const newttrace = initNewttrace({
botId: "my-bot",
version: "1.0.0",
exporters: [
new DatadogExporter({ apiKey: "...", service: "my-bot" }),
],
auto: true,
client,
});Returns a NewttraceSDK instance with hooks already attached.
NewttraceSDK
init(client?)
Attach event listeners to a Discord client. Called automatically by initNewttrace if auto: true.
ts
const sdk = new NewttraceSDK(config);
sdk.init(client); // manual init if auto: falsetrace(eventName, meta?, guildId?)
Emit a custom event with optional metadata and guild ID.
ts
// Simple event
newttrace.trace("premium_upgrade");
// With metadata
newttrace.trace("premium_upgrade", {
userId: "123",
tier: "pro",
});
// With metadata and guild ID
newttrace.trace("premium_upgrade", { tier: "pro" }, interaction.guildId);Parameters:
eventName: string— Event type (e.g.,"premium_upgrade")meta?: Record<string, unknown>— Arbitrary metadata attached to the eventguildId?: string— Optional guild ID to link the event to a server
traceCommand(interaction, commandName)
Explicitly track a command usage. Emits a command_used event.
ts
newttrace.traceCommand(interaction, "play");Parameters:
interaction: Interaction— Discord interaction objectcommandName: string— Name of the command executed
generateInviteUrl(clientId, options)
Generate a Discord OAuth invite URL with campaign attribution via the state parameter.
ts
const url = newttrace.generateInviteUrl("123456789", {
campaignId: "summer_2024",
permissions: "8",
scopes: ["bot", "applications.commands"],
});Parameters:
clientId: string— Your Discord application's client IDoptions:permissions?: string— Discord permission integer. Default:"0"scopes?: string[]— OAuth scopes. Default:["bot"]campaignId?: string— Campaign identifier stored instateredirectUri?: string— OAuth redirect URI (required forstateto be returned)
Returns: string — The complete Discord OAuth URL
Note: Without a redirectUri, Discord does not return state to the bot. The guildCreate event will not contain attribution data. See the Attribution guide for details.
shutdown()
Remove Discord event listeners and clean up internal state.
ts
process.on("SIGINT", () => {
newttrace.shutdown();
client.destroy();
});Type Exports
TraceEvent
The normalized event object sent to all exporters:
ts
interface TraceEvent {
event: string; // Event name: "guild_join", "interaction", etc.
timestamp: number; // Unix timestamp in milliseconds
bot_id: string; // Your botId from config
guild_id?: string; // Guild ID, if applicable
source?: string; // Attribution source, if resolved
version: string; // SDK version from config
meta: Record<string, unknown>; // Event-specific metadata
}Exporter
Implement this interface to create a custom exporter:
ts
interface Exporter {
send(event: TraceEvent): Promise<void>;
}NewttraceConfig
ts
interface NewttraceConfig {
botId: string;
version?: string;
exporters: Exporter[];
auto?: boolean;
client?: Client;
attribution?: {
enabled?: boolean;
storage?: StateStore;
guildStore?: GuildStore;
};
}StateStore
For the advanced redirect-server attribution flow:
ts
interface StateStore {
get(state: string): string | undefined;
set(state: string, campaignId: string): void;
delete(state: string): void;
}GuildStore
Maps guild IDs to attribution sources. Used with recordGuildSource() / resolveGuildSource():
ts
interface GuildStore {
get(guildId: string): string | undefined | Promise<string | undefined>;
set(guildId: string, source: string): void | Promise<void>;
delete(guildId: string): void | Promise<void>;
}HttpGuildStore
Queries a redirect server directly for attribution. No shared database needed.
ts
import { HttpGuildStore } from "newttrace";
new HttpGuildStore("https://your-worker.workers.dev");The store calls GET /resolve?guild_id=XXX and expects { source?: string } in response.
RedisGuildStore
Shared Redis store for attribution data. Requires npm install ioredis.
ts
import { RedisGuildStore } from "newttrace";
new RedisGuildStore("redis://localhost:6379", 86400);Parameters:
redisUrl: string— Redis connection URLttlSeconds: number— Key TTL. Default:86400(24 hours)
InMemoryGuildStore
Default in-memory store. Attribution is lost on bot restart.
ts
import { InMemoryGuildStore } from "newttrace";
new InMemoryGuildStore();