/** * Webhooks Resource * * Manage webhook endpoints for event notifications. */ import type { OilPriceAPI } from "../client.js"; /** * Webhook endpoint configuration */ export interface WebhookEndpoint { /** Unique webhook identifier */ id: string; /** User-friendly description of the webhook */ description?: string; /** Webhook URL (must be HTTPS) */ url: string; /** Event types to subscribe to */ events: string[]; /** Lifecycle status (e.g. 'active', 'disabled') */ status?: string; /** Optional secret for signature verification (generated server-side) */ secret?: string; /** Number of successful deliveries */ successful_deliveries: number; /** Number of failed deliveries */ failed_deliveries: number; /** Last delivery status */ last_delivery_status?: "success" | "failed"; /** ISO timestamp of last delivery attempt */ last_delivery_at?: string; /** ISO timestamp when webhook was created */ created_at: string; /** ISO timestamp when webhook was last updated */ updated_at: string; } /** * Parameters for creating a webhook * * NOTE: The API permits a flat (un-nested) body with the fields below. Earlier * SDK versions nested these under a `webhook` key and used `name`/`enabled`, * which the controller dropped — the controller reads `description` and `status`. */ export interface CreateWebhookParams { /** Webhook URL (must be HTTPS) */ url: string; /** Event types to subscribe to */ events: string[]; /** User-friendly description */ description?: string; /** Lifecycle status (e.g. 'active', 'disabled') */ status?: string; /** Commodity codes to filter events to */ commodity_filters?: string[]; /** US state codes to filter events to */ state_filters?: string[]; /** Per-second delivery rate limit */ rate_limit_per_second?: number; /** Delivery timeout in seconds */ timeout_seconds?: number; /** Max delivery retry attempts */ max_retries?: number; } /** * Parameters for updating a webhook */ export interface UpdateWebhookParams { /** Webhook URL */ url?: string; /** Event types to subscribe to */ events?: string[]; /** User-friendly description */ description?: string; /** Lifecycle status (e.g. 'active', 'disabled') */ status?: string; /** Commodity codes to filter events to */ commodity_filters?: string[]; /** US state codes to filter events to */ state_filters?: string[]; /** Per-second delivery rate limit */ rate_limit_per_second?: number; /** Delivery timeout in seconds */ timeout_seconds?: number; /** Max delivery retry attempts */ max_retries?: number; } /** * Webhook test response */ export interface WebhookTestResponse { /** Test result status */ success: boolean; /** HTTP status code from webhook endpoint */ status_code: number; /** Response time in milliseconds */ response_time_ms: number; /** Response body from webhook endpoint */ response_body?: string; /** Error message if test failed */ error?: string; } /** * Webhook event record */ export interface WebhookEvent { /** Event ID */ id: string; /** Webhook endpoint ID */ webhook_id: string; /** Event type */ event_type: string; /** Event payload */ payload: Record; /** Delivery status */ status: "pending" | "success" | "failed"; /** Number of delivery attempts */ attempts: number; /** HTTP status code from delivery */ status_code?: number; /** Error message if delivery failed */ error?: string; /** ISO timestamp when event was created */ created_at: string; /** ISO timestamp of last delivery attempt */ delivered_at?: string; } /** * Webhooks Resource * * Manage webhook endpoints for notifications about price changes, * alerts, and other events. * * @example * ```typescript * import { OilPriceAPI } from 'oilpriceapi'; * * const client = new OilPriceAPI({ apiKey: 'your_key' }); * * // Create a webhook * const webhook = await client.webhooks.create({ * name: 'Price Updates', * url: 'https://myapp.com/webhooks/prices', * events: ['price.updated', 'alert.triggered'], * enabled: true * }); * * // Test the webhook * const test = await client.webhooks.test(webhook.id); * console.log(`Test result: ${test.success ? 'passed' : 'failed'}`); * * // List all webhooks * const webhooks = await client.webhooks.list(); * webhooks.forEach(wh => { * console.log(`${wh.name}: ${wh.successful_deliveries} successful`); * }); * * // Update webhook * await client.webhooks.update(webhook.id, { * enabled: false * }); * * // Delete webhook * await client.webhooks.delete(webhook.id); * ``` */ export declare class WebhooksResource { private client; constructor(client: OilPriceAPI); /** * List all webhook endpoints * * @returns Array of webhook endpoints * * @throws {OilPriceAPIError} If API request fails * @throws {AuthenticationError} If API key is invalid * * @example * ```typescript * const webhooks = await client.webhooks.list(); * webhooks.forEach(wh => { * console.log(`${wh.name} (${wh.enabled ? 'enabled' : 'disabled'})`); * console.log(` Events: ${wh.events.join(', ')}`); * }); * ``` */ list(): Promise; /** * Get a specific webhook endpoint * * @param id - Webhook ID * @returns Webhook endpoint details * * @throws {NotFoundError} If webhook not found * @throws {OilPriceAPIError} If API request fails * * @example * ```typescript * const webhook = await client.webhooks.get('webhook-id'); * console.log(`${webhook.name}: ${webhook.url}`); * console.log(`Success rate: ${webhook.successful_deliveries}/${webhook.successful_deliveries + webhook.failed_deliveries}`); * ``` */ get(id: string): Promise; /** * Create a new webhook endpoint * * @param params - Webhook configuration * @returns Created webhook endpoint * * @throws {OilPriceAPIError} If API request fails * @throws {AuthenticationError} If API key is invalid * * @example * ```typescript * const webhook = await client.webhooks.create({ * name: 'Production Alerts', * url: 'https://api.myapp.com/webhooks', * events: ['alert.triggered', 'price.updated'], * secret: 'my-webhook-secret', * enabled: true * }); * console.log(`Webhook created: ${webhook.id}`); * ``` */ create(params: CreateWebhookParams): Promise; /** * Update a webhook endpoint * * @param id - Webhook ID * @param params - Fields to update * @returns Updated webhook endpoint * * @throws {NotFoundError} If webhook not found * @throws {OilPriceAPIError} If API request fails * * @example * ```typescript * // Disable a webhook * await client.webhooks.update(webhookId, { enabled: false }); * * // Change events * await client.webhooks.update(webhookId, { * events: ['alert.triggered'] * }); * ``` */ update(id: string, params: UpdateWebhookParams): Promise; /** * Delete a webhook endpoint * * @param id - Webhook ID * * @throws {NotFoundError} If webhook not found * @throws {OilPriceAPIError} If API request fails * * @example * ```typescript * await client.webhooks.delete(webhookId); * console.log('Webhook deleted'); * ``` */ delete(id: string): Promise; /** * Test a webhook endpoint * * Sends a test payload to the webhook URL to verify it's reachable. * * @param id - Webhook ID * @returns Test results * * @throws {NotFoundError} If webhook not found * @throws {OilPriceAPIError} If API request fails * * @example * ```typescript * const test = await client.webhooks.test(webhookId); * console.log(`Test ${test.success ? 'passed' : 'failed'}`); * console.log(`Response time: ${test.response_time_ms}ms`); * if (!test.success) { * console.log(`Error: ${test.error}`); * } * ``` */ test(id: string): Promise; /** * Get webhook event history * * Returns recent delivery events for a webhook. * * @param id - Webhook ID * @returns Array of webhook events * * @throws {NotFoundError} If webhook not found * @throws {OilPriceAPIError} If API request fails * * @example * ```typescript * const events = await client.webhooks.events(webhookId); * events.forEach(event => { * console.log(`${event.event_type}: ${event.status} (${event.attempts} attempts)`); * }); * ``` */ events(id: string): Promise; /** * Verify a webhook signature. * * Validates that a webhook payload was sent by OilPriceAPI by checking * the HMAC-SHA256 signature. Uses constant-time comparison to prevent * timing attacks. * * @param payload - Raw request body (string or Buffer) * @param signature - Value of the X-OilPriceAPI-Signature header (e.g., "sha256=abc123...") * @param secret - Your webhook signing secret * @returns true if signature is valid * * @example * ```typescript * import express from 'express'; * import { OilPriceAPI } from 'oilpriceapi'; * * const app = express(); * const client = new OilPriceAPI({ apiKey: 'your_key' }); * * // Use raw body parser for webhook routes * app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { * const signature = req.headers['x-oilpriceapi-signature'] as string; * const isValid = client.webhooks.verifySignature(req.body, signature, 'your_secret'); * * if (!isValid) { * return res.status(401).send('Invalid signature'); * } * * const event = JSON.parse(req.body.toString()); * console.log('Verified webhook:', event.type); * res.sendStatus(200); * }); * ``` */ verifySignature(payload: string | Buffer, signature: string, secret: string): boolean; }