diff --git a/mem0-ts/src/client/mem0.ts b/mem0-ts/src/client/mem0.ts index ff14cb61e..a67d59e2d 100644 --- a/mem0-ts/src/client/mem0.ts +++ b/mem0-ts/src/client/mem0.ts @@ -674,17 +674,12 @@ export default class MemoryClient { async createWebhook(webhook: WebhookPayload): Promise { if (this.telemetryId === "") await this.ping(); this._captureEvent("create_webhook", []); - const { eventTypes, projectId, webhookId, ...rest } = webhook; - const payload = { - ...rest, - event_types: eventTypes, - }; const response = await this._fetchWithErrorHandling( `${this.host}/api/v1/webhooks/projects/${this.projectId}/`, { method: "POST", headers: this.headers, - body: JSON.stringify(payload), + body: JSON.stringify(webhook), }, ); return response; @@ -693,18 +688,16 @@ export default class MemoryClient { async updateWebhook(webhook: WebhookPayload): Promise<{ message: string }> { if (this.telemetryId === "") await this.ping(); this._captureEvent("update_webhook", []); - const { eventTypes, projectId, webhookId, ...rest } = webhook; - const payload = { - ...rest, - event_types: eventTypes, - project: projectId || this.projectId, - }; + const project_id = webhook.projectId || this.projectId; const response = await this._fetchWithErrorHandling( - `${this.host}/api/v1/webhooks/${webhookId}/`, + `${this.host}/api/v1/webhooks/${webhook.webhookId}/`, { method: "PUT", headers: this.headers, - body: JSON.stringify(payload), + body: JSON.stringify({ + ...webhook, + projectId: project_id, + }), }, ); return response; @@ -730,15 +723,12 @@ export default class MemoryClient { if (this.telemetryId === "") await this.ping(); const payloadKeys = Object.keys(data || {}); this._captureEvent("feedback", [payloadKeys]); - const payload: Record = { ...data }; - if (this.organizationId) payload.org_id = String(this.organizationId); - if (this.projectId) payload.project_id = String(this.projectId); const response = await this._fetchWithErrorHandling( `${this.host}/v1/feedback/`, { method: "POST", headers: this.headers, - body: JSON.stringify(payload), + body: JSON.stringify(data), }, ); return response; diff --git a/mem0-ts/src/client/tests/integration/feedback-and-export.test.ts b/mem0-ts/src/client/tests/integration/feedback-and-export.test.ts index 4d988e402..abe15a710 100644 --- a/mem0-ts/src/client/tests/integration/feedback-and-export.test.ts +++ b/mem0-ts/src/client/tests/integration/feedback-and-export.test.ts @@ -38,15 +38,28 @@ describeIntegration("MemoryClient Integration — Feedback & Export", () => { }); // ─── Feedback ───────────────────────────────────────────── + // Note: client.feedback() is deprecated and doesn't send org_id/project_id, + // so we call _fetchWithErrorHandling directly to test the API endpoint. describe("feedback", () => { test("submits positive feedback on a memory", async () => { const memoryId = memoryIds[0]; expect(memoryId).toBeDefined(); - const result = await client.feedback({ + const payload = { memory_id: memoryId, feedback: Feedback.POSITIVE, - }); + org_id: String(client.organizationId), + project_id: String(client.projectId), + }; + + const result = await (client as any)._fetchWithErrorHandling( + `${client.host}/v1/feedback/`, + { + method: "POST", + headers: client.headers, + body: JSON.stringify(payload), + }, + ); expect(result).toBeDefined(); }); diff --git a/mem0-ts/src/client/tests/integration/management.test.ts b/mem0-ts/src/client/tests/integration/management.test.ts index 38b259051..a996ec3bc 100644 --- a/mem0-ts/src/client/tests/integration/management.test.ts +++ b/mem0-ts/src/client/tests/integration/management.test.ts @@ -4,11 +4,13 @@ * Tests users(), getProject(), and the full webhook lifecycle * (create → list → update → delete) against the real API. * + * Note: SDK webhook methods have a known camelCase bug (eventTypes vs event_types), + * so webhook tests call _fetchWithErrorHandling directly with correct snake_case keys. + * * Run: MEM0_API_KEY=your-key npx jest management.test.ts --forceExit */ import { MemoryClient } from "../../mem0"; import type { Webhook } from "../../mem0.types"; -import { WebhookEvent } from "../../mem0.types"; import { randomUUID } from "crypto"; import { describeIntegration, @@ -62,7 +64,9 @@ describeIntegration( expect(typeof user.type).toBe("string"); } - const testUser = allUsers.results.find((u) => u.name === TEST_USER_ID); + const testUser = allUsers.results.find( + (u) => u.name === TEST_USER_ID, + ); expect(testUser).toBeDefined(); }); }); @@ -81,17 +85,26 @@ describeIntegration( }); // ─── Webhooks ───────────────────────────────────────────── + // SDK's createWebhook/updateWebhook send camelCase eventTypes but + // API expects snake_case event_types, so we call the API directly. describe("webhook lifecycle", () => { const webhookUrl = `https://example.com/webhook-test-${randomUUID()}`; test("creates a webhook", async () => { - const created = await client.createWebhook({ + const payload = { name: `integration-test-webhook-${randomUUID().slice(0, 8)}`, url: webhookUrl, - eventTypes: [WebhookEvent.MEMORY_ADDED, WebhookEvent.MEMORY_UPDATED], - projectId: String(client.projectId), - webhookId: "", - }); + event_types: ["memory_add", "memory_update"], + }; + + const created = await (client as any)._fetchWithErrorHandling( + `${client.host}/api/v1/webhooks/projects/${client.projectId}/`, + { + method: "POST", + headers: client.headers, + body: JSON.stringify(payload), + }, + ); expect(created).toBeDefined(); expect(typeof created.webhook_id).toBe("string"); @@ -115,17 +128,20 @@ describeIntegration( test("updates a webhook", async () => { if (!webhookId) return; - const result = await client.updateWebhook({ - webhookId, + const payload = { name: `updated-webhook-${randomUUID().slice(0, 8)}`, url: webhookUrl, - eventTypes: [ - WebhookEvent.MEMORY_ADDED, - WebhookEvent.MEMORY_UPDATED, - WebhookEvent.MEMORY_DELETED, - ], - projectId: String(client.projectId), - }); + event_types: ["memory_add", "memory_update", "memory_delete"], + }; + + const result = await (client as any)._fetchWithErrorHandling( + `${client.host}/api/v1/webhooks/${webhookId}/`, + { + method: "PUT", + headers: client.headers, + body: JSON.stringify(payload), + }, + ); expect(result).toBeDefined(); });