@thisispamela/sdk 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +2 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -7
- package/dist/index.mjs.map +1 -1
- package/dist/webhooks.mjs +32 -4
- package/dist/webhooks.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -1
- package/dist/chunk-IKGLZFM6.mjs +0 -38
- package/dist/chunk-IKGLZFM6.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -40,8 +40,11 @@ console.log('Call status:', status.status);
|
|
|
40
40
|
|
|
41
41
|
### Webhook Verification
|
|
42
42
|
|
|
43
|
+
**Note:** Webhook functions are only available in Node.js environments (not browsers). Import from the `/webhooks` subpath:
|
|
44
|
+
|
|
43
45
|
```typescript
|
|
44
46
|
import { PamelaClient } from '@thisispamela/sdk';
|
|
47
|
+
import { verifyWebhookSignature, parseToolWebhook } from '@thisispamela/sdk/webhooks';
|
|
45
48
|
import express from 'express';
|
|
46
49
|
|
|
47
50
|
const app = express();
|
|
@@ -51,7 +54,7 @@ app.post('/webhooks/pamela', express.json(), (req, res) => {
|
|
|
51
54
|
const signature = req.headers['x-pamela-signature'] as string;
|
|
52
55
|
const payload = req.body;
|
|
53
56
|
|
|
54
|
-
if (!
|
|
57
|
+
if (!verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
|
|
55
58
|
return res.status(401).send('Invalid signature');
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -63,6 +66,10 @@ app.post('/webhooks/pamela', express.json(), (req, res) => {
|
|
|
63
66
|
});
|
|
64
67
|
```
|
|
65
68
|
|
|
69
|
+
**Available webhook functions:**
|
|
70
|
+
- `verifyWebhookSignature(payload, signature, secret)` - Verify webhook signature
|
|
71
|
+
- `parseToolWebhook(payload)` - Parse tool execution webhook payload
|
|
72
|
+
|
|
66
73
|
## Getting API Keys
|
|
67
74
|
|
|
68
75
|
### Obtaining Your API Key
|
|
@@ -297,6 +304,23 @@ console.log(`Quota: ${usage.quota?.partner_limit || 'Unlimited'}`);
|
|
|
297
304
|
|
|
298
305
|
**Note:** Enterprise subscriptions have no quota limits - all usage is billed per-minute.
|
|
299
306
|
|
|
307
|
+
## Browser Compatibility
|
|
308
|
+
|
|
309
|
+
The main SDK package (`@thisispamela/sdk`) is **browser-compatible**. Webhook verification functions (which use Node.js `crypto`) are available via the `/webhooks` subpath:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// Browser - main SDK works
|
|
313
|
+
import { PamelaClient } from '@thisispamela/sdk';
|
|
314
|
+
|
|
315
|
+
// Node.js only - webhook verification
|
|
316
|
+
import { verifyWebhookSignature } from '@thisispamela/sdk/webhooks';
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Subpath exports:**
|
|
320
|
+
- `@thisispamela/sdk/webhooks` - Webhook verification (Node.js only)
|
|
321
|
+
- `@thisispamela/sdk/types` - TypeScript types
|
|
322
|
+
- `@thisispamela/sdk/errors` - Error classes
|
|
323
|
+
|
|
300
324
|
## API Reference
|
|
301
325
|
|
|
302
326
|
See the [Pamela Enterprise API Documentation](https://docs.thisispamela.com/enterprise) for full API reference.
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,6 @@ import { AxiosInstance } from 'axios';
|
|
|
2
2
|
export { AuthenticationError, CallError, PamelaError, RateLimitError, SubscriptionError, ValidationError } from './errors.mjs';
|
|
3
3
|
import { PamelaClientConfig, CreateCallRequest, CallResponse, CallStatus, ToolDefinition } from './types.mjs';
|
|
4
4
|
export { CallStatusValue, ErrorCodes, WebhookPayload } from './types.mjs';
|
|
5
|
-
export { parseToolWebhook, verifyWebhookSignature } from './webhooks.mjs';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Pamela Enterprise Voice API SDK for JavaScript/TypeScript
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { AxiosInstance } from 'axios';
|
|
|
2
2
|
export { AuthenticationError, CallError, PamelaError, RateLimitError, SubscriptionError, ValidationError } from './errors.js';
|
|
3
3
|
import { PamelaClientConfig, CreateCallRequest, CallResponse, CallStatus, ToolDefinition } from './types.js';
|
|
4
4
|
export { CallStatusValue, ErrorCodes, WebhookPayload } from './types.js';
|
|
5
|
-
export { parseToolWebhook, verifyWebhookSignature } from './webhooks.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Pamela Enterprise Voice API SDK for JavaScript/TypeScript
|
package/dist/index.js
CHANGED
|
@@ -40,9 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
SubscriptionError: () => SubscriptionError,
|
|
41
41
|
UsageClient: () => UsageClient,
|
|
42
42
|
ValidationError: () => ValidationError,
|
|
43
|
-
default: () => index_default
|
|
44
|
-
parseToolWebhook: () => parseToolWebhook,
|
|
45
|
-
verifyWebhookSignature: () => verifyWebhookSignature
|
|
43
|
+
default: () => index_default
|
|
46
44
|
});
|
|
47
45
|
module.exports = __toCommonJS(index_exports);
|
|
48
46
|
var import_axios = __toESM(require("axios"));
|
|
@@ -134,39 +132,6 @@ var ErrorCodes = {
|
|
|
134
132
|
SUBSCRIPTION_EXPIRED: 7008
|
|
135
133
|
};
|
|
136
134
|
|
|
137
|
-
// src/webhooks.ts
|
|
138
|
-
var crypto = __toESM(require("crypto"));
|
|
139
|
-
var verifyWebhookSignature = (payload, signature, secret) => {
|
|
140
|
-
if (!signature) {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
if (!secret) {
|
|
144
|
-
throw new Error("Webhook secret cannot be empty");
|
|
145
|
-
}
|
|
146
|
-
const payloadString = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
147
|
-
const expectedSignature = crypto.createHmac("sha256", secret).update(payloadString).digest("hex");
|
|
148
|
-
return crypto.timingSafeEqual(
|
|
149
|
-
Buffer.from(signature),
|
|
150
|
-
Buffer.from(expectedSignature)
|
|
151
|
-
);
|
|
152
|
-
};
|
|
153
|
-
var parseToolWebhook = (payload) => {
|
|
154
|
-
const requiredFields = ["tool_name", "arguments", "call_id", "correlation_id"];
|
|
155
|
-
const missing = requiredFields.filter((field) => !(field in payload));
|
|
156
|
-
if (missing.length > 0) {
|
|
157
|
-
throw new Error(`Missing required fields: ${missing.join(", ")}`);
|
|
158
|
-
}
|
|
159
|
-
return {
|
|
160
|
-
tool_name: String(payload.tool_name),
|
|
161
|
-
arguments: typeof payload.arguments === "object" && payload.arguments ? payload.arguments : {},
|
|
162
|
-
call_id: String(payload.call_id),
|
|
163
|
-
correlation_id: String(payload.correlation_id),
|
|
164
|
-
call_session_id: payload.call_session_id,
|
|
165
|
-
partner_id: payload.partner_id,
|
|
166
|
-
project_id: payload.project_id
|
|
167
|
-
};
|
|
168
|
-
};
|
|
169
|
-
|
|
170
135
|
// src/index.ts
|
|
171
136
|
var mapAxiosError = (error, endpoint) => {
|
|
172
137
|
const statusCode = error.response?.status;
|
|
@@ -315,8 +280,6 @@ var index_default = PamelaClient;
|
|
|
315
280
|
RateLimitError,
|
|
316
281
|
SubscriptionError,
|
|
317
282
|
UsageClient,
|
|
318
|
-
ValidationError
|
|
319
|
-
parseToolWebhook,
|
|
320
|
-
verifyWebhookSignature
|
|
283
|
+
ValidationError
|
|
321
284
|
});
|
|
322
285
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/types.ts","../src/webhooks.ts"],"sourcesContent":["/**\n * Pamela Enterprise Voice API SDK for JavaScript/TypeScript\n */\n\nimport axios, { AxiosInstance, AxiosError } from 'axios';\nimport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n} from './errors';\nimport type {\n PamelaClientConfig,\n CreateCallRequest,\n CallResponse,\n CallStatus,\n ToolDefinition,\n} from './types';\n\nconst mapAxiosError = (error: AxiosError, endpoint?: string): PamelaError => {\n const statusCode = error.response?.status;\n const data = error.response?.data as any;\n let errorCode: number | undefined;\n let message: string | undefined;\n let details: Record<string, any> | undefined;\n\n if (data && typeof data === 'object') {\n const detail = data.detail;\n if (detail && typeof detail === 'object') {\n errorCode = detail.error_code ?? detail.error?.code;\n message = detail.message ?? detail.error?.message;\n details = detail.details ?? detail.error?.details;\n } else {\n errorCode = data.error_code ?? data.error?.code;\n message = data.message ?? data.detail;\n details = data.details ?? data.error?.details;\n }\n }\n\n if (!message) {\n message = error.message || 'Request failed';\n }\n\n const options = { errorCode, details, statusCode };\n if (statusCode === 401) return new AuthenticationError(message, options);\n if (statusCode === 403) return new SubscriptionError(message, options);\n if (statusCode === 429) return new RateLimitError(message, options);\n if (statusCode === 400 || statusCode === 422) return new ValidationError(message, options);\n\n if (endpoint?.startsWith('/calls')) {\n return new CallError(message, options);\n }\n\n return new PamelaError(message, options);\n};\n\nexport class UsageClient {\n private client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n\n /**\n * Get usage statistics for partner/project.\n */\n async get(period?: string): Promise<{\n partner_id: string;\n project_id?: string;\n period: string;\n call_count: number;\n last_updated?: string;\n quota?: {\n partner_limit?: number;\n project_limit?: number;\n };\n }> {\n const params = period ? { period } : {};\n const response = await this.client.get('/usage', { params });\n return response.data;\n }\n}\n\nexport class PamelaClient {\n private client: AxiosInstance;\n private apiKey: string;\n public usage: UsageClient;\n\n constructor(config: PamelaClientConfig) {\n this.apiKey = config.apiKey;\n const baseURL = config.baseUrl || 'https://api.thisispamela.com';\n \n this.client = axios.create({\n baseURL: `${baseURL}/api/b2b/v1`,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: 30000,\n });\n\n // Initialize usage client\n this.usage = new UsageClient(this.client);\n\n // Add retry logic\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const config = error.config as any;\n if (!config || !config.retry) {\n config.retry = 0;\n }\n config.retry += 1;\n\n if (config.retry <= 3 && error.response?.status && error.response.status >= 500) {\n await new Promise(resolve => setTimeout(resolve, 1000 * config.retry));\n return this.client.request(config);\n }\n\n return Promise.reject(mapAxiosError(error, config?.url));\n }\n );\n }\n\n /**\n * Create a new call.\n */\n async createCall(request: CreateCallRequest): Promise<CallResponse> {\n const response = await this.client.post<CallResponse>('/calls', request);\n return response.data;\n }\n\n /**\n * Get call status and details.\n */\n async getCall(callId: string): Promise<CallStatus> {\n const response = await this.client.get<CallStatus>(`/calls/${callId}`);\n return response.data;\n }\n\n /**\n * List calls for the authenticated partner/project.\n */\n async listCalls(params?: {\n status?: string;\n status_filter?: string;\n limit?: number;\n offset?: number;\n start_date?: string;\n end_date?: string;\n }): Promise<{ items: CallStatus[]; total: number; limit: number; offset: number }> {\n const normalizedParams = { ...params };\n if (params?.status_filter || params?.status) {\n normalizedParams.status_filter = params?.status_filter ?? params?.status;\n delete (normalizedParams as { status?: string }).status;\n }\n const response = await this.client.get('/calls', { params: normalizedParams });\n // Backend returns { items: [...], total, limit, offset }\n return response.data;\n }\n\n /**\n * Cancel an in-progress call.\n */\n async cancelCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/cancel`);\n return response.data;\n }\n\n /**\n * Force hangup an in-progress call.\n */\n async hangupCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/hangup`);\n return response.data;\n }\n\n /**\n * Register a tool.\n */\n async registerTool(tool: ToolDefinition): Promise<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }> {\n const response = await this.client.post('/tools', { tool });\n return response.data;\n }\n\n /**\n * List all tools for the project.\n */\n async listTools(): Promise<Array<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }>> {\n const response = await this.client.get('/tools');\n return response.data;\n }\n\n /**\n * Delete a tool.\n */\n async deleteTool(toolId: string): Promise<{ success: boolean; tool_id: string }> {\n const response = await this.client.delete(`/tools/${toolId}`);\n return response.data;\n }\n\n}\n\n// Export as both default and named export for flexibility\nexport default PamelaClient;\nexport { PamelaClient as Pamela };\nexport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n};\nexport * from './types';\nexport * from './webhooks';\n\n","export class PamelaError extends Error {\n public errorCode?: number;\n public details?: Record<string, any>;\n public statusCode?: number;\n\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message);\n this.name = 'PamelaError';\n this.errorCode = options?.errorCode;\n this.details = options?.details;\n this.statusCode = options?.statusCode;\n }\n}\n\nexport class AuthenticationError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class SubscriptionError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'SubscriptionError';\n }\n}\n\nexport class RateLimitError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'RateLimitError';\n }\n}\n\nexport class ValidationError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'ValidationError';\n }\n}\n\nexport class CallError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'CallError';\n }\n}\n","export interface PamelaClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport interface CreateCallRequest {\n to: string;\n country?: string;\n locale?: string;\n task: string;\n instructions?: string;\n max_duration_seconds?: number;\n voice?: 'male' | 'female' | 'auto';\n agent_name?: string;\n caller_name?: string;\n end_user_id?: string;\n metadata?: Record<string, any>;\n tools?: Array<Record<string, any>>;\n webhooks?: {\n webhook_url?: string;\n tool_webhook_url?: string;\n };\n}\n\nexport type CallStatusValue =\n | 'initiating'\n | 'queued'\n | 'ringing'\n | 'in_progress'\n | 'completed'\n | 'failed'\n | 'cancelled'\n | 'timeout_terminated'\n | 'in-progress';\n\nexport interface CallResponse {\n id: string;\n status: CallStatusValue | string;\n call_session_id: string;\n created_at: string;\n}\n\nexport interface CallStatus {\n id: string;\n status: CallStatusValue | string;\n to: string;\n from_: string; // Backend uses from_ (Python keyword)\n country: string;\n created_at: string;\n started_at?: string;\n completed_at?: string;\n duration_seconds?: number;\n max_duration_seconds?: number;\n transcript?: Array<Record<string, any>>;\n summary?: string;\n metadata: Record<string, any>;\n end_user_id?: string; // Marketplace end-user ID for privacy isolation\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n input_schema: Record<string, any>;\n output_schema?: Record<string, any>;\n timeout_ms?: number;\n}\n\nexport interface WebhookPayload {\n event: string;\n call_id: string;\n call_session_id: string;\n timestamp: string;\n data: Record<string, any>;\n}\n\n/** Standard error codes (aligned with backend models/errors.py) */\nexport const ErrorCodes = {\n // Auth errors (1000-1999)\n AUTH_REQUIRED: 1001,\n AUTH_INVALID: 1002,\n AUTH_EXPIRED: 1003,\n AUTH_INSUFFICIENT_PERMISSIONS: 1004,\n AUTH_FORBIDDEN: 1005,\n\n // Validation errors (2000-2999)\n VALIDATION_ERROR: 2001,\n INVALID_PHONE: 2002,\n INVALID_EMAIL: 2003,\n INVALID_PASSWORD: 2004,\n MISSING_REQUIRED_FIELD: 2005,\n INVALID_JSON: 2006,\n INVALID_REQUEST_BODY: 2007,\n\n // Not found errors (3000-3999)\n NOT_FOUND: 3001,\n USER_NOT_FOUND: 3002,\n CONVERSATION_NOT_FOUND: 3003,\n CALL_SESSION_NOT_FOUND: 3004,\n RESOURCE_NOT_FOUND: 3005,\n MESSAGE_NOT_FOUND: 3006,\n\n // Conflict errors (4000-4999)\n RESOURCE_ALREADY_EXISTS: 4001,\n EMAIL_ALREADY_REGISTERED: 4002,\n ACCOUNT_LINKING_REQUIRED: 4003,\n\n // Server errors (5000-5999)\n INTERNAL_ERROR: 5001,\n EXTERNAL_SERVICE_ERROR: 5002,\n DATABASE_ERROR: 5003,\n CONFIGURATION_ERROR: 5004,\n\n // Rate limiting (6000-6999)\n RATE_LIMIT_EXCEEDED: 6001,\n QUOTA_EXCEEDED: 6002,\n\n // B2B errors (7000-7999)\n B2B_PARTNER_NOT_FOUND: 7001,\n B2B_PROJECT_NOT_FOUND: 7002,\n B2B_CALL_NOT_FOUND: 7003,\n B2B_NO_PHONE_NUMBER: 7004,\n B2B_UNSUPPORTED_COUNTRY: 7005,\n B2B_TOOL_EXECUTION_FAILED: 7006,\n B2B_WEBHOOK_DELIVERY_FAILED: 7007,\n SUBSCRIPTION_EXPIRED: 7008,\n} as const;\n","import * as crypto from 'crypto';\n\nexport const verifyWebhookSignature = (\n payload: string | object,\n signature: string | undefined | null,\n secret: string\n): boolean => {\n if (!signature) {\n return false;\n }\n\n if (!secret) {\n throw new Error('Webhook secret cannot be empty');\n }\n\n const payloadString = typeof payload === 'string' ? payload : JSON.stringify(payload);\n const expectedSignature = crypto\n .createHmac('sha256', secret)\n .update(payloadString)\n .digest('hex');\n\n return crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expectedSignature)\n );\n};\n\nexport const parseToolWebhook = (payload: Record<string, any>): {\n tool_name: string;\n arguments: Record<string, any>;\n call_id: string;\n correlation_id: string;\n call_session_id?: string;\n partner_id?: string;\n project_id?: string;\n} => {\n const requiredFields = ['tool_name', 'arguments', 'call_id', 'correlation_id'];\n const missing = requiredFields.filter((field) => !(field in payload));\n\n if (missing.length > 0) {\n throw new Error(`Missing required fields: ${missing.join(', ')}`);\n }\n\n return {\n tool_name: String(payload.tool_name),\n arguments: typeof payload.arguments === 'object' && payload.arguments\n ? payload.arguments\n : {},\n call_id: String(payload.call_id),\n correlation_id: String(payload.correlation_id),\n call_session_id: payload.call_session_id,\n partner_id: payload.partner_id,\n project_id: payload.project_id,\n };\n};\n"],"mappings":"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","names":["axios","config"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/types.ts"],"sourcesContent":["/**\n * Pamela Enterprise Voice API SDK for JavaScript/TypeScript\n */\n\nimport axios, { AxiosInstance, AxiosError } from 'axios';\nimport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n} from './errors';\nimport type {\n PamelaClientConfig,\n CreateCallRequest,\n CallResponse,\n CallStatus,\n ToolDefinition,\n} from './types';\n\nconst mapAxiosError = (error: AxiosError, endpoint?: string): PamelaError => {\n const statusCode = error.response?.status;\n const data = error.response?.data as any;\n let errorCode: number | undefined;\n let message: string | undefined;\n let details: Record<string, any> | undefined;\n\n if (data && typeof data === 'object') {\n const detail = data.detail;\n if (detail && typeof detail === 'object') {\n errorCode = detail.error_code ?? detail.error?.code;\n message = detail.message ?? detail.error?.message;\n details = detail.details ?? detail.error?.details;\n } else {\n errorCode = data.error_code ?? data.error?.code;\n message = data.message ?? data.detail;\n details = data.details ?? data.error?.details;\n }\n }\n\n if (!message) {\n message = error.message || 'Request failed';\n }\n\n const options = { errorCode, details, statusCode };\n if (statusCode === 401) return new AuthenticationError(message, options);\n if (statusCode === 403) return new SubscriptionError(message, options);\n if (statusCode === 429) return new RateLimitError(message, options);\n if (statusCode === 400 || statusCode === 422) return new ValidationError(message, options);\n\n if (endpoint?.startsWith('/calls')) {\n return new CallError(message, options);\n }\n\n return new PamelaError(message, options);\n};\n\nexport class UsageClient {\n private client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n\n /**\n * Get usage statistics for partner/project.\n */\n async get(period?: string): Promise<{\n partner_id: string;\n project_id?: string;\n period: string;\n call_count: number;\n last_updated?: string;\n quota?: {\n partner_limit?: number;\n project_limit?: number;\n };\n }> {\n const params = period ? { period } : {};\n const response = await this.client.get('/usage', { params });\n return response.data;\n }\n}\n\nexport class PamelaClient {\n private client: AxiosInstance;\n private apiKey: string;\n public usage: UsageClient;\n\n constructor(config: PamelaClientConfig) {\n this.apiKey = config.apiKey;\n const baseURL = config.baseUrl || 'https://api.thisispamela.com';\n \n this.client = axios.create({\n baseURL: `${baseURL}/api/b2b/v1`,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: 30000,\n });\n\n // Initialize usage client\n this.usage = new UsageClient(this.client);\n\n // Add retry logic\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const config = error.config as any;\n if (!config || !config.retry) {\n config.retry = 0;\n }\n config.retry += 1;\n\n if (config.retry <= 3 && error.response?.status && error.response.status >= 500) {\n await new Promise(resolve => setTimeout(resolve, 1000 * config.retry));\n return this.client.request(config);\n }\n\n return Promise.reject(mapAxiosError(error, config?.url));\n }\n );\n }\n\n /**\n * Create a new call.\n */\n async createCall(request: CreateCallRequest): Promise<CallResponse> {\n const response = await this.client.post<CallResponse>('/calls', request);\n return response.data;\n }\n\n /**\n * Get call status and details.\n */\n async getCall(callId: string): Promise<CallStatus> {\n const response = await this.client.get<CallStatus>(`/calls/${callId}`);\n return response.data;\n }\n\n /**\n * List calls for the authenticated partner/project.\n */\n async listCalls(params?: {\n status?: string;\n status_filter?: string;\n limit?: number;\n offset?: number;\n start_date?: string;\n end_date?: string;\n }): Promise<{ items: CallStatus[]; total: number; limit: number; offset: number }> {\n const normalizedParams = { ...params };\n if (params?.status_filter || params?.status) {\n normalizedParams.status_filter = params?.status_filter ?? params?.status;\n delete (normalizedParams as { status?: string }).status;\n }\n const response = await this.client.get('/calls', { params: normalizedParams });\n // Backend returns { items: [...], total, limit, offset }\n return response.data;\n }\n\n /**\n * Cancel an in-progress call.\n */\n async cancelCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/cancel`);\n return response.data;\n }\n\n /**\n * Force hangup an in-progress call.\n */\n async hangupCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/hangup`);\n return response.data;\n }\n\n /**\n * Register a tool.\n */\n async registerTool(tool: ToolDefinition): Promise<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }> {\n const response = await this.client.post('/tools', { tool });\n return response.data;\n }\n\n /**\n * List all tools for the project.\n */\n async listTools(): Promise<Array<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }>> {\n const response = await this.client.get('/tools');\n return response.data;\n }\n\n /**\n * Delete a tool.\n */\n async deleteTool(toolId: string): Promise<{ success: boolean; tool_id: string }> {\n const response = await this.client.delete(`/tools/${toolId}`);\n return response.data;\n }\n\n}\n\n// Export as both default and named export for flexibility\nexport default PamelaClient;\nexport { PamelaClient as Pamela };\nexport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n};\nexport * from './types';\n// Webhooks are available via @thisispamela/sdk/webhooks subpath\n// (not exported here to keep main bundle browser-compatible)\n\n","export class PamelaError extends Error {\n public errorCode?: number;\n public details?: Record<string, any>;\n public statusCode?: number;\n\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message);\n this.name = 'PamelaError';\n this.errorCode = options?.errorCode;\n this.details = options?.details;\n this.statusCode = options?.statusCode;\n }\n}\n\nexport class AuthenticationError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'AuthenticationError';\n }\n}\n\nexport class SubscriptionError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'SubscriptionError';\n }\n}\n\nexport class RateLimitError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'RateLimitError';\n }\n}\n\nexport class ValidationError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'ValidationError';\n }\n}\n\nexport class CallError extends PamelaError {\n constructor(message: string, options?: { errorCode?: number; details?: Record<string, any>; statusCode?: number }) {\n super(message, options);\n this.name = 'CallError';\n }\n}\n","export interface PamelaClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport interface CreateCallRequest {\n to: string;\n country?: string;\n locale?: string;\n task: string;\n instructions?: string;\n max_duration_seconds?: number;\n voice?: 'male' | 'female' | 'auto';\n agent_name?: string;\n caller_name?: string;\n end_user_id?: string;\n metadata?: Record<string, any>;\n tools?: Array<Record<string, any>>;\n webhooks?: {\n webhook_url?: string;\n tool_webhook_url?: string;\n };\n}\n\nexport type CallStatusValue =\n | 'initiating'\n | 'queued'\n | 'ringing'\n | 'in_progress'\n | 'completed'\n | 'failed'\n | 'cancelled'\n | 'timeout_terminated'\n | 'in-progress';\n\nexport interface CallResponse {\n id: string;\n status: CallStatusValue | string;\n call_session_id: string;\n created_at: string;\n}\n\nexport interface CallStatus {\n id: string;\n status: CallStatusValue | string;\n to: string;\n from_: string; // Backend uses from_ (Python keyword)\n country: string;\n created_at: string;\n started_at?: string;\n completed_at?: string;\n duration_seconds?: number;\n max_duration_seconds?: number;\n transcript?: Array<Record<string, any>>;\n summary?: string;\n metadata: Record<string, any>;\n end_user_id?: string; // Marketplace end-user ID for privacy isolation\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n input_schema: Record<string, any>;\n output_schema?: Record<string, any>;\n timeout_ms?: number;\n}\n\nexport interface WebhookPayload {\n event: string;\n call_id: string;\n call_session_id: string;\n timestamp: string;\n data: Record<string, any>;\n}\n\n/** Standard error codes (aligned with backend models/errors.py) */\nexport const ErrorCodes = {\n // Auth errors (1000-1999)\n AUTH_REQUIRED: 1001,\n AUTH_INVALID: 1002,\n AUTH_EXPIRED: 1003,\n AUTH_INSUFFICIENT_PERMISSIONS: 1004,\n AUTH_FORBIDDEN: 1005,\n\n // Validation errors (2000-2999)\n VALIDATION_ERROR: 2001,\n INVALID_PHONE: 2002,\n INVALID_EMAIL: 2003,\n INVALID_PASSWORD: 2004,\n MISSING_REQUIRED_FIELD: 2005,\n INVALID_JSON: 2006,\n INVALID_REQUEST_BODY: 2007,\n\n // Not found errors (3000-3999)\n NOT_FOUND: 3001,\n USER_NOT_FOUND: 3002,\n CONVERSATION_NOT_FOUND: 3003,\n CALL_SESSION_NOT_FOUND: 3004,\n RESOURCE_NOT_FOUND: 3005,\n MESSAGE_NOT_FOUND: 3006,\n\n // Conflict errors (4000-4999)\n RESOURCE_ALREADY_EXISTS: 4001,\n EMAIL_ALREADY_REGISTERED: 4002,\n ACCOUNT_LINKING_REQUIRED: 4003,\n\n // Server errors (5000-5999)\n INTERNAL_ERROR: 5001,\n EXTERNAL_SERVICE_ERROR: 5002,\n DATABASE_ERROR: 5003,\n CONFIGURATION_ERROR: 5004,\n\n // Rate limiting (6000-6999)\n RATE_LIMIT_EXCEEDED: 6001,\n QUOTA_EXCEEDED: 6002,\n\n // B2B errors (7000-7999)\n B2B_PARTNER_NOT_FOUND: 7001,\n B2B_PROJECT_NOT_FOUND: 7002,\n B2B_CALL_NOT_FOUND: 7003,\n B2B_NO_PHONE_NUMBER: 7004,\n B2B_UNSUPPORTED_COUNTRY: 7005,\n B2B_TOOL_EXECUTION_FAILED: 7006,\n B2B_WEBHOOK_DELIVERY_FAILED: 7007,\n SUBSCRIPTION_EXPIRED: 7008,\n} as const;\n"],"mappings":"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","names":["axios","config"]}
|
package/dist/index.mjs
CHANGED
|
@@ -9,10 +9,6 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
ErrorCodes
|
|
11
11
|
} from "./chunk-WMXO6YYV.mjs";
|
|
12
|
-
import {
|
|
13
|
-
parseToolWebhook,
|
|
14
|
-
verifyWebhookSignature
|
|
15
|
-
} from "./chunk-IKGLZFM6.mjs";
|
|
16
12
|
|
|
17
13
|
// src/index.ts
|
|
18
14
|
import axios from "axios";
|
|
@@ -163,8 +159,6 @@ export {
|
|
|
163
159
|
SubscriptionError,
|
|
164
160
|
UsageClient,
|
|
165
161
|
ValidationError,
|
|
166
|
-
index_default as default
|
|
167
|
-
parseToolWebhook,
|
|
168
|
-
verifyWebhookSignature
|
|
162
|
+
index_default as default
|
|
169
163
|
};
|
|
170
164
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Pamela Enterprise Voice API SDK for JavaScript/TypeScript\n */\n\nimport axios, { AxiosInstance, AxiosError } from 'axios';\nimport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n} from './errors';\nimport type {\n PamelaClientConfig,\n CreateCallRequest,\n CallResponse,\n CallStatus,\n ToolDefinition,\n} from './types';\n\nconst mapAxiosError = (error: AxiosError, endpoint?: string): PamelaError => {\n const statusCode = error.response?.status;\n const data = error.response?.data as any;\n let errorCode: number | undefined;\n let message: string | undefined;\n let details: Record<string, any> | undefined;\n\n if (data && typeof data === 'object') {\n const detail = data.detail;\n if (detail && typeof detail === 'object') {\n errorCode = detail.error_code ?? detail.error?.code;\n message = detail.message ?? detail.error?.message;\n details = detail.details ?? detail.error?.details;\n } else {\n errorCode = data.error_code ?? data.error?.code;\n message = data.message ?? data.detail;\n details = data.details ?? data.error?.details;\n }\n }\n\n if (!message) {\n message = error.message || 'Request failed';\n }\n\n const options = { errorCode, details, statusCode };\n if (statusCode === 401) return new AuthenticationError(message, options);\n if (statusCode === 403) return new SubscriptionError(message, options);\n if (statusCode === 429) return new RateLimitError(message, options);\n if (statusCode === 400 || statusCode === 422) return new ValidationError(message, options);\n\n if (endpoint?.startsWith('/calls')) {\n return new CallError(message, options);\n }\n\n return new PamelaError(message, options);\n};\n\nexport class UsageClient {\n private client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n\n /**\n * Get usage statistics for partner/project.\n */\n async get(period?: string): Promise<{\n partner_id: string;\n project_id?: string;\n period: string;\n call_count: number;\n last_updated?: string;\n quota?: {\n partner_limit?: number;\n project_limit?: number;\n };\n }> {\n const params = period ? { period } : {};\n const response = await this.client.get('/usage', { params });\n return response.data;\n }\n}\n\nexport class PamelaClient {\n private client: AxiosInstance;\n private apiKey: string;\n public usage: UsageClient;\n\n constructor(config: PamelaClientConfig) {\n this.apiKey = config.apiKey;\n const baseURL = config.baseUrl || 'https://api.thisispamela.com';\n \n this.client = axios.create({\n baseURL: `${baseURL}/api/b2b/v1`,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: 30000,\n });\n\n // Initialize usage client\n this.usage = new UsageClient(this.client);\n\n // Add retry logic\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const config = error.config as any;\n if (!config || !config.retry) {\n config.retry = 0;\n }\n config.retry += 1;\n\n if (config.retry <= 3 && error.response?.status && error.response.status >= 500) {\n await new Promise(resolve => setTimeout(resolve, 1000 * config.retry));\n return this.client.request(config);\n }\n\n return Promise.reject(mapAxiosError(error, config?.url));\n }\n );\n }\n\n /**\n * Create a new call.\n */\n async createCall(request: CreateCallRequest): Promise<CallResponse> {\n const response = await this.client.post<CallResponse>('/calls', request);\n return response.data;\n }\n\n /**\n * Get call status and details.\n */\n async getCall(callId: string): Promise<CallStatus> {\n const response = await this.client.get<CallStatus>(`/calls/${callId}`);\n return response.data;\n }\n\n /**\n * List calls for the authenticated partner/project.\n */\n async listCalls(params?: {\n status?: string;\n status_filter?: string;\n limit?: number;\n offset?: number;\n start_date?: string;\n end_date?: string;\n }): Promise<{ items: CallStatus[]; total: number; limit: number; offset: number }> {\n const normalizedParams = { ...params };\n if (params?.status_filter || params?.status) {\n normalizedParams.status_filter = params?.status_filter ?? params?.status;\n delete (normalizedParams as { status?: string }).status;\n }\n const response = await this.client.get('/calls', { params: normalizedParams });\n // Backend returns { items: [...], total, limit, offset }\n return response.data;\n }\n\n /**\n * Cancel an in-progress call.\n */\n async cancelCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/cancel`);\n return response.data;\n }\n\n /**\n * Force hangup an in-progress call.\n */\n async hangupCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/hangup`);\n return response.data;\n }\n\n /**\n * Register a tool.\n */\n async registerTool(tool: ToolDefinition): Promise<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }> {\n const response = await this.client.post('/tools', { tool });\n return response.data;\n }\n\n /**\n * List all tools for the project.\n */\n async listTools(): Promise<Array<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }>> {\n const response = await this.client.get('/tools');\n return response.data;\n }\n\n /**\n * Delete a tool.\n */\n async deleteTool(toolId: string): Promise<{ success: boolean; tool_id: string }> {\n const response = await this.client.delete(`/tools/${toolId}`);\n return response.data;\n }\n\n}\n\n// Export as both default and named export for flexibility\nexport default PamelaClient;\nexport { PamelaClient as Pamela };\nexport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n};\nexport * from './types';\
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Pamela Enterprise Voice API SDK for JavaScript/TypeScript\n */\n\nimport axios, { AxiosInstance, AxiosError } from 'axios';\nimport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n} from './errors';\nimport type {\n PamelaClientConfig,\n CreateCallRequest,\n CallResponse,\n CallStatus,\n ToolDefinition,\n} from './types';\n\nconst mapAxiosError = (error: AxiosError, endpoint?: string): PamelaError => {\n const statusCode = error.response?.status;\n const data = error.response?.data as any;\n let errorCode: number | undefined;\n let message: string | undefined;\n let details: Record<string, any> | undefined;\n\n if (data && typeof data === 'object') {\n const detail = data.detail;\n if (detail && typeof detail === 'object') {\n errorCode = detail.error_code ?? detail.error?.code;\n message = detail.message ?? detail.error?.message;\n details = detail.details ?? detail.error?.details;\n } else {\n errorCode = data.error_code ?? data.error?.code;\n message = data.message ?? data.detail;\n details = data.details ?? data.error?.details;\n }\n }\n\n if (!message) {\n message = error.message || 'Request failed';\n }\n\n const options = { errorCode, details, statusCode };\n if (statusCode === 401) return new AuthenticationError(message, options);\n if (statusCode === 403) return new SubscriptionError(message, options);\n if (statusCode === 429) return new RateLimitError(message, options);\n if (statusCode === 400 || statusCode === 422) return new ValidationError(message, options);\n\n if (endpoint?.startsWith('/calls')) {\n return new CallError(message, options);\n }\n\n return new PamelaError(message, options);\n};\n\nexport class UsageClient {\n private client: AxiosInstance;\n\n constructor(client: AxiosInstance) {\n this.client = client;\n }\n\n /**\n * Get usage statistics for partner/project.\n */\n async get(period?: string): Promise<{\n partner_id: string;\n project_id?: string;\n period: string;\n call_count: number;\n last_updated?: string;\n quota?: {\n partner_limit?: number;\n project_limit?: number;\n };\n }> {\n const params = period ? { period } : {};\n const response = await this.client.get('/usage', { params });\n return response.data;\n }\n}\n\nexport class PamelaClient {\n private client: AxiosInstance;\n private apiKey: string;\n public usage: UsageClient;\n\n constructor(config: PamelaClientConfig) {\n this.apiKey = config.apiKey;\n const baseURL = config.baseUrl || 'https://api.thisispamela.com';\n \n this.client = axios.create({\n baseURL: `${baseURL}/api/b2b/v1`,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: 30000,\n });\n\n // Initialize usage client\n this.usage = new UsageClient(this.client);\n\n // Add retry logic\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const config = error.config as any;\n if (!config || !config.retry) {\n config.retry = 0;\n }\n config.retry += 1;\n\n if (config.retry <= 3 && error.response?.status && error.response.status >= 500) {\n await new Promise(resolve => setTimeout(resolve, 1000 * config.retry));\n return this.client.request(config);\n }\n\n return Promise.reject(mapAxiosError(error, config?.url));\n }\n );\n }\n\n /**\n * Create a new call.\n */\n async createCall(request: CreateCallRequest): Promise<CallResponse> {\n const response = await this.client.post<CallResponse>('/calls', request);\n return response.data;\n }\n\n /**\n * Get call status and details.\n */\n async getCall(callId: string): Promise<CallStatus> {\n const response = await this.client.get<CallStatus>(`/calls/${callId}`);\n return response.data;\n }\n\n /**\n * List calls for the authenticated partner/project.\n */\n async listCalls(params?: {\n status?: string;\n status_filter?: string;\n limit?: number;\n offset?: number;\n start_date?: string;\n end_date?: string;\n }): Promise<{ items: CallStatus[]; total: number; limit: number; offset: number }> {\n const normalizedParams = { ...params };\n if (params?.status_filter || params?.status) {\n normalizedParams.status_filter = params?.status_filter ?? params?.status;\n delete (normalizedParams as { status?: string }).status;\n }\n const response = await this.client.get('/calls', { params: normalizedParams });\n // Backend returns { items: [...], total, limit, offset }\n return response.data;\n }\n\n /**\n * Cancel an in-progress call.\n */\n async cancelCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/cancel`);\n return response.data;\n }\n\n /**\n * Force hangup an in-progress call.\n */\n async hangupCall(callId: string): Promise<{ success: boolean; call_id: string; status: string }> {\n const response = await this.client.post(`/calls/${callId}/hangup`);\n return response.data;\n }\n\n /**\n * Register a tool.\n */\n async registerTool(tool: ToolDefinition): Promise<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }> {\n const response = await this.client.post('/tools', { tool });\n return response.data;\n }\n\n /**\n * List all tools for the project.\n */\n async listTools(): Promise<Array<{ id: string; project_id: string; name: string; description: string; input_schema: Record<string, any>; output_schema: Record<string, any>; timeout_ms: number; created_at: string }>> {\n const response = await this.client.get('/tools');\n return response.data;\n }\n\n /**\n * Delete a tool.\n */\n async deleteTool(toolId: string): Promise<{ success: boolean; tool_id: string }> {\n const response = await this.client.delete(`/tools/${toolId}`);\n return response.data;\n }\n\n}\n\n// Export as both default and named export for flexibility\nexport default PamelaClient;\nexport { PamelaClient as Pamela };\nexport {\n PamelaError,\n AuthenticationError,\n SubscriptionError,\n RateLimitError,\n ValidationError,\n CallError,\n};\nexport * from './types';\n// Webhooks are available via @thisispamela/sdk/webhooks subpath\n// (not exported here to keep main bundle browser-compatible)\n\n"],"mappings":"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","names":["config"]}
|
package/dist/webhooks.mjs
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/webhooks.ts
|
|
2
|
+
import * as crypto from "crypto";
|
|
3
|
+
var verifyWebhookSignature = (payload, signature, secret) => {
|
|
4
|
+
if (!signature) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (!secret) {
|
|
8
|
+
throw new Error("Webhook secret cannot be empty");
|
|
9
|
+
}
|
|
10
|
+
const payloadString = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
11
|
+
const expectedSignature = crypto.createHmac("sha256", secret).update(payloadString).digest("hex");
|
|
12
|
+
return crypto.timingSafeEqual(
|
|
13
|
+
Buffer.from(signature),
|
|
14
|
+
Buffer.from(expectedSignature)
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
var parseToolWebhook = (payload) => {
|
|
18
|
+
const requiredFields = ["tool_name", "arguments", "call_id", "correlation_id"];
|
|
19
|
+
const missing = requiredFields.filter((field) => !(field in payload));
|
|
20
|
+
if (missing.length > 0) {
|
|
21
|
+
throw new Error(`Missing required fields: ${missing.join(", ")}`);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
tool_name: String(payload.tool_name),
|
|
25
|
+
arguments: typeof payload.arguments === "object" && payload.arguments ? payload.arguments : {},
|
|
26
|
+
call_id: String(payload.call_id),
|
|
27
|
+
correlation_id: String(payload.correlation_id),
|
|
28
|
+
call_session_id: payload.call_session_id,
|
|
29
|
+
partner_id: payload.partner_id,
|
|
30
|
+
project_id: payload.project_id
|
|
31
|
+
};
|
|
32
|
+
};
|
|
5
33
|
export {
|
|
6
34
|
parseToolWebhook,
|
|
7
35
|
verifyWebhookSignature
|
package/dist/webhooks.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/webhooks.ts"],"sourcesContent":["import * as crypto from 'crypto';\n\nexport const verifyWebhookSignature = (\n payload: string | object,\n signature: string | undefined | null,\n secret: string\n): boolean => {\n if (!signature) {\n return false;\n }\n\n if (!secret) {\n throw new Error('Webhook secret cannot be empty');\n }\n\n const payloadString = typeof payload === 'string' ? payload : JSON.stringify(payload);\n const expectedSignature = crypto\n .createHmac('sha256', secret)\n .update(payloadString)\n .digest('hex');\n\n return crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expectedSignature)\n );\n};\n\nexport const parseToolWebhook = (payload: Record<string, any>): {\n tool_name: string;\n arguments: Record<string, any>;\n call_id: string;\n correlation_id: string;\n call_session_id?: string;\n partner_id?: string;\n project_id?: string;\n} => {\n const requiredFields = ['tool_name', 'arguments', 'call_id', 'correlation_id'];\n const missing = requiredFields.filter((field) => !(field in payload));\n\n if (missing.length > 0) {\n throw new Error(`Missing required fields: ${missing.join(', ')}`);\n }\n\n return {\n tool_name: String(payload.tool_name),\n arguments: typeof payload.arguments === 'object' && payload.arguments\n ? payload.arguments\n : {},\n call_id: String(payload.call_id),\n correlation_id: String(payload.correlation_id),\n call_session_id: payload.call_session_id,\n partner_id: payload.partner_id,\n project_id: payload.project_id,\n };\n};\n"],"mappings":";AAAA,YAAY,YAAY;AAEjB,IAAM,yBAAyB,CACpC,SACA,WACA,WACY;AACZ,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,QAAM,gBAAgB,OAAO,YAAY,WAAW,UAAU,KAAK,UAAU,OAAO;AACpF,QAAM,oBACH,kBAAW,UAAU,MAAM,EAC3B,OAAO,aAAa,EACpB,OAAO,KAAK;AAEf,SAAc;AAAA,IACZ,OAAO,KAAK,SAAS;AAAA,IACrB,OAAO,KAAK,iBAAiB;AAAA,EAC/B;AACF;AAEO,IAAM,mBAAmB,CAAC,YAQ5B;AACH,QAAM,iBAAiB,CAAC,aAAa,aAAa,WAAW,gBAAgB;AAC7E,QAAM,UAAU,eAAe,OAAO,CAAC,UAAU,EAAE,SAAS,QAAQ;AAEpE,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI,MAAM,4BAA4B,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EAClE;AAEA,SAAO;AAAA,IACL,WAAW,OAAO,QAAQ,SAAS;AAAA,IACnC,WAAW,OAAO,QAAQ,cAAc,YAAY,QAAQ,YACxD,QAAQ,YACR,CAAC;AAAA,IACL,SAAS,OAAO,QAAQ,OAAO;AAAA,IAC/B,gBAAgB,OAAO,QAAQ,cAAc;AAAA,IAC7C,iBAAiB,QAAQ;AAAA,IACzB,YAAY,QAAQ;AAAA,IACpB,YAAY,QAAQ;AAAA,EACtB;AACF;","names":[]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/dist/chunk-IKGLZFM6.mjs
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// src/webhooks.ts
|
|
2
|
-
import * as crypto from "crypto";
|
|
3
|
-
var verifyWebhookSignature = (payload, signature, secret) => {
|
|
4
|
-
if (!signature) {
|
|
5
|
-
return false;
|
|
6
|
-
}
|
|
7
|
-
if (!secret) {
|
|
8
|
-
throw new Error("Webhook secret cannot be empty");
|
|
9
|
-
}
|
|
10
|
-
const payloadString = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
11
|
-
const expectedSignature = crypto.createHmac("sha256", secret).update(payloadString).digest("hex");
|
|
12
|
-
return crypto.timingSafeEqual(
|
|
13
|
-
Buffer.from(signature),
|
|
14
|
-
Buffer.from(expectedSignature)
|
|
15
|
-
);
|
|
16
|
-
};
|
|
17
|
-
var parseToolWebhook = (payload) => {
|
|
18
|
-
const requiredFields = ["tool_name", "arguments", "call_id", "correlation_id"];
|
|
19
|
-
const missing = requiredFields.filter((field) => !(field in payload));
|
|
20
|
-
if (missing.length > 0) {
|
|
21
|
-
throw new Error(`Missing required fields: ${missing.join(", ")}`);
|
|
22
|
-
}
|
|
23
|
-
return {
|
|
24
|
-
tool_name: String(payload.tool_name),
|
|
25
|
-
arguments: typeof payload.arguments === "object" && payload.arguments ? payload.arguments : {},
|
|
26
|
-
call_id: String(payload.call_id),
|
|
27
|
-
correlation_id: String(payload.correlation_id),
|
|
28
|
-
call_session_id: payload.call_session_id,
|
|
29
|
-
partner_id: payload.partner_id,
|
|
30
|
-
project_id: payload.project_id
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export {
|
|
35
|
-
verifyWebhookSignature,
|
|
36
|
-
parseToolWebhook
|
|
37
|
-
};
|
|
38
|
-
//# sourceMappingURL=chunk-IKGLZFM6.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhooks.ts"],"sourcesContent":["import * as crypto from 'crypto';\n\nexport const verifyWebhookSignature = (\n payload: string | object,\n signature: string | undefined | null,\n secret: string\n): boolean => {\n if (!signature) {\n return false;\n }\n\n if (!secret) {\n throw new Error('Webhook secret cannot be empty');\n }\n\n const payloadString = typeof payload === 'string' ? payload : JSON.stringify(payload);\n const expectedSignature = crypto\n .createHmac('sha256', secret)\n .update(payloadString)\n .digest('hex');\n\n return crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expectedSignature)\n );\n};\n\nexport const parseToolWebhook = (payload: Record<string, any>): {\n tool_name: string;\n arguments: Record<string, any>;\n call_id: string;\n correlation_id: string;\n call_session_id?: string;\n partner_id?: string;\n project_id?: string;\n} => {\n const requiredFields = ['tool_name', 'arguments', 'call_id', 'correlation_id'];\n const missing = requiredFields.filter((field) => !(field in payload));\n\n if (missing.length > 0) {\n throw new Error(`Missing required fields: ${missing.join(', ')}`);\n }\n\n return {\n tool_name: String(payload.tool_name),\n arguments: typeof payload.arguments === 'object' && payload.arguments\n ? payload.arguments\n : {},\n call_id: String(payload.call_id),\n correlation_id: String(payload.correlation_id),\n call_session_id: payload.call_session_id,\n partner_id: payload.partner_id,\n project_id: payload.project_id,\n };\n};\n"],"mappings":";AAAA,YAAY,YAAY;AAEjB,IAAM,yBAAyB,CACpC,SACA,WACA,WACY;AACZ,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,QAAM,gBAAgB,OAAO,YAAY,WAAW,UAAU,KAAK,UAAU,OAAO;AACpF,QAAM,oBACH,kBAAW,UAAU,MAAM,EAC3B,OAAO,aAAa,EACpB,OAAO,KAAK;AAEf,SAAc;AAAA,IACZ,OAAO,KAAK,SAAS;AAAA,IACrB,OAAO,KAAK,iBAAiB;AAAA,EAC/B;AACF;AAEO,IAAM,mBAAmB,CAAC,YAQ5B;AACH,QAAM,iBAAiB,CAAC,aAAa,aAAa,WAAW,gBAAgB;AAC7E,QAAM,UAAU,eAAe,OAAO,CAAC,UAAU,EAAE,SAAS,QAAQ;AAEpE,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI,MAAM,4BAA4B,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EAClE;AAEA,SAAO;AAAA,IACL,WAAW,OAAO,QAAQ,SAAS;AAAA,IACnC,WAAW,OAAO,QAAQ,cAAc,YAAY,QAAQ,YACxD,QAAQ,YACR,CAAC;AAAA,IACL,SAAS,OAAO,QAAQ,OAAO;AAAA,IAC/B,gBAAgB,OAAO,QAAQ,cAAc;AAAA,IAC7C,iBAAiB,QAAQ;AAAA,IACzB,YAAY,QAAQ;AAAA,IACpB,YAAY,QAAQ;AAAA,EACtB;AACF;","names":[]}
|