JavaScript/TypeScript SDK
The official Hook0 SDK for JavaScript and TypeScript applications, providing a type-safe and idiomatic interface to the Hook0 API.
Installation
npm install hook0-client
# or
yarn add hook0-client
# or
pnpm add hook0-client
Quick Start
import { Hook0Client, Event } from 'hook0-client';
const hook0 = new Hook0Client(
'http://localhost:8081/api/v1',
'app_1234567890', // Your application ID
'{YOUR_TOKEN}'
);
// Send an event
const event = new Event(
'user.account.created',
JSON.stringify({
user_id: 'user_123',
email: 'john.doe@example.com'
}),
'application/json',
{ environment: 'production' }
);
const eventId = await hook0.sendEvent(event);
Configuration
Client Initialization
import { Hook0Client } from 'hook0-client';
const hook0 = new Hook0Client(
'http://localhost:8081/api/v1', // API URL
'app_1234567890', // Your application ID
'{YOUR_TOKEN}', // Authentication token
false // Debug mode (optional)
);
Environment Variables
The current TypeScript SDK implementation requires explicit configuration and does not automatically read from environment variables.
Core Features
Event Management
Send Single Event
import { Hook0Client, Event } from 'hook0-client';
const hook0 = new Hook0Client(
'http://localhost:8081/api/v1',
'app_1234567890',
'{YOUR_TOKEN}'
);
const event = new Event(
'order.checkout.completed',
JSON.stringify({
order_id: 'ord_123',
customer_id: 'cust_456',
total: 99.99,
items: [
{ product_id: 'prod_789', quantity: 2 }
]
}),
'application/json',
{
environment: 'production',
region: 'us-west'
}
);
const eventId = await hook0.sendEvent(event);
console.log('Event ID:', eventId);
The batch events functionality is not currently implemented. Please send events individually using the single event method above.
The event listing and querying functionality is not available in the current SDK implementation. Use the REST API directly for these operations.
Event Type Management
// Upsert event types (creates if not exists)
const addedEventTypes = await hook0.upsertEventTypes([
'user.account.created',
'user.account.updated',
'order.checkout.completed'
]);
console.log('Added event types:', addedEventTypes);
The current SDK implementation provides basic event sending and event type management. For full application and subscription management, please use the REST API directly.
Advanced Features
Webhook Verification
import { verifyWebhookSignature } from 'hook0-client';
import express from 'express';
const app = express();
// Note: Express.js normalizes all header names to lowercase
// Capture raw body for signature verification
app.post('/webhook', express.json({
verify: (req, res, buf) => { (req as any).rawBody = buf; }
}), (req, res) => {
const signature = req.headers['x-hook0-signature'] as string;
const secret = process.env.WEBHOOK_SECRET!;
// Use raw body for signature verification, not JSON.stringify(req.body)
const rawBodyString = (req as any).rawBody.toString('utf8');
try {
// Verify the signature with headers
const headers = new Headers();
Object.entries(req.headers).forEach(([key, value]) => {
if (typeof value === 'string') {
headers.set(key, value);
}
});
const isValid = verifyWebhookSignature(
signature,
rawBodyString,
headers,
secret,
300 // 5-minute tolerance
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook (already parsed via req.body)
console.log('Webhook received:', req.body);
processWebhook(req.body);
res.json({ status: 'processed' });
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Processing failed' });
}
});
Error Handling
import { Hook0ClientError } from 'hook0-client';
try {
const event = new Event(
'user.account.created',
JSON.stringify({ user_id: 'user_123' }),
'application/json',
{ source: 'api' }
);
const eventId = await hook0.sendEvent(event);
} catch (error) {
if (error instanceof Hook0ClientError) {
console.error('Hook0 error:', error.message);
// Handle specific error types
if (error.message.includes('Invalid event type')) {
console.error('Event type format is invalid');
} else if (error.message.includes('Sending event') && error.message.includes('failed')) {
console.error('Failed to send event, retry later');
}
} else {
console.error('Unexpected error:', error);
}
}
Middleware system and event streaming are not available in the current SDK implementation. These features may be added in future versions.
TypeScript Support
The SDK is written in TypeScript and provides type definitions:
import { Hook0Client, Event, EventType, Hook0ClientError } from 'hook0-client';
// Type-safe event creation
const event = new Event(
'user.account.created',
JSON.stringify({
user_id: 'user_123',
email: 'john@example.com'
}),
'application/json',
{ source: 'api' }
);
// EventType helper for parsing event types
const eventType = EventType.fromString('auth.user.create');
if (eventType instanceof Hook0ClientError) {
console.error('Invalid event type format');
} else {
console.log(`Service: ${eventType.service}`);
console.log(`Resource: ${eventType.resourceType}`);
console.log(`Verb: ${eventType.verb}`);
}
Testing
Testing
import { Hook0Client, Event } from 'hook0-client';
import { jest } from '@jest/globals';
describe('Event Handler', () => {
test('should send user created event', async () => {
// Mock the fetch function
global.fetch = jest.fn().mockResolvedValueOnce({
ok: true,
text: async () => '',
});
const client = new Hook0Client(
'http://localhost:8081/api/v1',
'app_test',
'test_token'
);
const event = new Event(
'user.account.created',
JSON.stringify({ email: 'test@example.com' }),
'application/json',
{}
);
const eventId = await client.sendEvent(event);
// Verify fetch was called correctly
expect(fetch).toHaveBeenCalledWith(
'http://localhost:8081/api/v1/event',
expect.objectContaining({
method: 'POST',
headers: expect.objectContaining({
'Authorization': 'Bearer test_token',
'Content-Type': 'application/json'
})
})
);
});
});
Best Practices
1. Use Environment Variables
// Bad - hardcoded credentials
const hook0 = new Hook0Client(
'http://localhost:8081/api/v1',
'app_1234567890',
'hardcoded_token_here'
);
// Good - use environment variables
const hook0 = new Hook0Client(
process.env.HOOK0_API_URL!,
process.env.HOOK0_APP_ID!,
process.env.HOOK0_TOKEN!
);
2. Implement Proper Error Handling
// Bad
await hook0.sendEvent(event);
// Good
try {
await hook0.sendEvent(event);
} catch (error) {
if (error instanceof Hook0ClientError) {
logger.error('Failed to send event', {
message: error.message,
event
});
// Implement retry or fallback logic
}
throw error;
}
3. Efficient Event Sending
// When sending multiple events, consider using Promise.all for parallelization
const eventPromises = users.map(user => {
const event = new Event(
'user.account.created',
JSON.stringify(user),
'application/json',
{ source: 'bulk_import' }
);
return hook0.sendEvent(event);
});
const eventIds = await Promise.all(eventPromises);
console.log(`Sent ${eventIds.length} events`);
4. Use Unique Event IDs
// Provide your own event ID for idempotency
const event = new Event(
'payment.transaction.processed',
JSON.stringify({ amount: 100.00 }),
'application/json',
{ transaction_id },
undefined, // metadata
new Date(), // occurredAt
`payment-${transaction_id}` // Your own event ID
);
const eventId = await hook0.sendEvent(event);
Troubleshooting
Common Issues
Authentication Errors
// Ensure token is passed correctly (without Bearer prefix - SDK adds it)
const hook0 = new Hook0Client(
'http://localhost:8081/api/v1',
'app_1234567890',
'{YOUR_TOKEN}' // ✓ Correct - just the token, SDK adds "Bearer " automatically
);
CORS Issues in Browser
// The SDK uses fetch() which handles CORS automatically
// Ensure your Hook0 application is configured to accept
// requests from your domain
Network Errors
// Implement retry logic for network failures
async function sendEventWithRetry(client: Hook0Client, event: Event, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await client.sendEvent(event);
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
}
}
}
Support
- Documentation: Hook0 API Docs
- Getting Started: Tutorial
- GitHub Issues: Report Issues
- Discord: Join Community
- NPM Package: hook0-client