2026-01-26 13:12:17 +00:00
|
|
|
import { apiClient } from './api/client';
|
|
|
|
|
import { logger } from '@/utils/logger';
|
|
|
|
|
|
|
|
|
|
export interface Webhook {
|
|
|
|
|
id: string;
|
|
|
|
|
url: string;
|
|
|
|
|
events: string[];
|
|
|
|
|
status: 'active' | 'failed';
|
|
|
|
|
lastTriggered: string;
|
|
|
|
|
secret?: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const webhookService = {
|
|
|
|
|
list: async (): Promise<Webhook[]> => {
|
|
|
|
|
try {
|
|
|
|
|
const response = await apiClient.get<any[]>('/webhooks');
|
|
|
|
|
return (response.data || []).map(hook => ({
|
|
|
|
|
id: hook.id,
|
|
|
|
|
url: hook.url,
|
|
|
|
|
events: hook.events || [],
|
|
|
|
|
status: hook.status || 'active',
|
|
|
|
|
lastTriggered: hook.last_triggered || 'Never',
|
|
|
|
|
created_at: hook.created_at,
|
|
|
|
|
}));
|
2026-02-10 18:38:13 +00:00
|
|
|
} catch (error: unknown) {
|
2026-02-10 18:48:48 +00:00
|
|
|
const err = error as { response?: { status?: number }; code?: number };
|
|
|
|
|
const status = err?.response?.status ?? err?.code;
|
|
|
|
|
const is5xx = typeof status === 'number' && status >= 500;
|
2026-02-10 18:51:20 +00:00
|
|
|
if (!is5xx) {
|
2026-02-10 18:38:13 +00:00
|
|
|
logger.error('[Webhooks] Failed to list webhooks', { error });
|
|
|
|
|
}
|
2026-02-10 18:51:20 +00:00
|
|
|
// 5xx: no log (backend error, avoid console noise)
|
2026-01-26 13:12:17 +00:00
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
create: async (url: string, events: string[] = ['*']): Promise<Webhook> => {
|
|
|
|
|
const response = await apiClient.post<any>('/webhooks', {
|
|
|
|
|
url,
|
|
|
|
|
events,
|
|
|
|
|
});
|
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
delete: async (id: string): Promise<void> => {
|
|
|
|
|
await apiClient.delete(`/webhooks/${id}`);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
regenerateKey: async (id: string): Promise<{ api_key: string }> => {
|
|
|
|
|
const response = await apiClient.post<{ data: { api_key: string } }>(`/webhooks/${id}/regenerate-key`);
|
|
|
|
|
// APIClient might already unwrap the first level of "data"
|
|
|
|
|
// If response.data is { api_key }, we return it.
|
|
|
|
|
return response.data as any;
|
|
|
|
|
}
|
|
|
|
|
};
|