@open-composer/posthog-worker
v1.0.3
Published
Cloudflare Worker for anonymous PostHog logging with IP-based rate limiting
Readme
PostHog Anonymous Logger Worker
A TypeScript Cloudflare Worker that provides anonymous event logging to PostHog with IP-based rate limiting for abuse prevention.
Features
- TypeScript: Full type safety and better developer experience
- Anonymous Event Logging: Strips personally identifiable information and forwards events to PostHog
- IP-Based Rate Limiting: Uses Durable Objects to prevent abuse (100 requests per minute per IP)
- CORS Support: Handles cross-origin requests for web applications
- Error Handling: Comprehensive error handling and response formatting
- Comprehensive Testing: Unit tests using Vitest and Cloudflare Workers testing framework
Setup
Install Dependencies:
npm installConfigure PostHog API Key: Update the
POSTHOG_PROJECT_API_KEYvariable inwrangler.tomlwith your PostHog project API key.Set up Rate Limiting (Optional): If you want to use the native Rate Limiting API instead of Durable Objects, update the
namespace_idin thewrangler.tomlfile with your Cloudflare namespace ID.Deploy:
npm run deploy
Usage
Send POST requests to the worker endpoint with the following structure:
interface IncomingEvent {
event?: string;
properties?: Record<string, any>;
anonymous_id?: string;
timestamp?: string;
}Example request:
{
"event": "button_click",
"properties": {
"button_name": "signup",
"page": "landing"
},
"anonymous_id": "optional-anonymous-id"
}The worker will:
- Check rate limits based on client IP
- Strip any identifying information (
$set,$set_once,distinct_id) - Add anonymous identifiers (
$ip,anonymous_id) - Forward the event to PostHog
Rate Limiting
- Limit: 100 requests per minute per IP address
- Method: Sliding window using Durable Objects
- Response: 429 status with retry-after header when exceeded
- Cleanup: Automatically removes old rate limit windows
Testing
The project includes comprehensive tests using Vitest and Cloudflare Workers testing framework:
# Run tests once
npm run test
# Run tests in watch mode
npm run test:watch
# Type check
npm run type-checkTest Coverage
- CORS handling: Preflight requests and headers
- HTTP method validation: Only POST requests allowed
- Rate limiting: IP-based limits with Durable Objects
- Event processing: JSON parsing and PostHog forwarding
- Data sanitization: Removal of identifying information
- Error handling: Invalid JSON and network errors
- Edge cases: Concurrent requests, window boundaries, cleanup
Security Considerations
- IP-based rate limiting may affect users behind shared proxies
- No authentication required for anonymous logging
- Events are sanitized to remove identifying information
- CORS is enabled for all origins (consider restricting in production)
- All personally identifiable properties are stripped
Configuration
Environment Variables in wrangler.toml:
POSTHOG_HOST: PostHog instance URL (default: https://app.posthog.com)POSTHOG_PROJECT_API_KEY: Your PostHog project API key
TypeScript Configuration:
- Target: ES2022
- Module: ES2022 with bundler resolution
- Strict mode: Enabled for type safety
- Workers Types: @cloudflare/workers-types included
Development
# Start local development server
npm run dev
# Build (dry run deploy)
npm run build
# Type check
npm run type-check
# Run tests
npm run test
# View logs
npm run tail
# Deploy to production
npm run deployFile Structure
workers/
├── src/
│ └── index.ts # Main worker code
├── test/
│ ├── index.test.ts # Main worker tests
│ ├── rate-limiter.test.ts # Rate limiter specific tests
│ └── setup.ts # Test setup and mocks
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── vitest.config.ts # Test configuration
├── wrangler.toml # Cloudflare Workers configuration
└── README.md # This file