diff --git a/apps/docs/api-reference/queries-execute.mdx b/apps/docs/api-reference/queries-execute.mdx index aec2163..5811440 100644 --- a/apps/docs/api-reference/queries-execute.mdx +++ b/apps/docs/api-reference/queries-execute.mdx @@ -5,3 +5,48 @@ openapi: post /queries --- This endpoint requires your [private API key](/api-reference/overview#authentication). + +This endpoint allows you to execute read-only queries against your Trench data. +The endpoint will proxy the request to the underlying ClickHouse database. +For more information about ClickHouse's query language, see the [official documentation](https://clickhouse.com/docs/en/sql-reference). + +## Examples + +### Quering event properties, context, and traits + +To query a specific nested property, you can use the `JSONExtract` function. For example, to query all events where the `totalAccounts` property is greater than 3, you can use the following query: + +```sql +SELECT * FROM events WHERE JSONExtract(properties, 'totalAccounts', 'UInt64') > 3 +``` + +Similarly, you can query the context and traits: + +```sql +SELECT * FROM events WHERE JSONExtract(context, 'country', 'String') = 'Denmark' +``` + +### Joining identified users with their events + +All `identify` calls are sent to the same underlying `events` ClickHouse table, so you can join events with identified users using the `userId` column. For example, to query all events for a user with the ID `user-123`, you can use the following query: + +```sql +SELECT * FROM events WHERE userId = 'user-123' +``` + +To get the tracking events and the user's most recently provided email, you can join the `track` and `identify` event types: + +```sql +SELECT + i.email, + e.* +FROM + events e +LEFT JOIN + (SELECT userId, type, JSONExtract(traits, 'email', 'String') AS email FROM events) i +ON + e.userId = i.userId +WHERE + e.type = 'track' + AND i.type = 'identify'; +``` diff --git a/apps/docs/cloud-quickstart.mdx b/apps/docs/cloud-quickstart.mdx index 542850e..02bf6a9 100644 --- a/apps/docs/cloud-quickstart.mdx +++ b/apps/docs/cloud-quickstart.mdx @@ -44,6 +44,14 @@ The example uses the [Trench JavaScript client](https://github.com/trench-dev/tr serverUrl: 'YOUR_SERVER_URL' }); ``` + Optionally, you can identify a user with the `identify` method: + + ```javascript + trench.identify('user-id', { + email: 'test@example.com', + // Add any other traits you want to associate with the user + }) + ``` @@ -51,33 +59,14 @@ The example uses the [Trench JavaScript client](https://github.com/trench-dev/tr Now you can send a sample event to Trench Cloud. Here is an example of how to send an event: ```javascript - trench.track({ - userId: '550e8400-e29b-41d4-a716-446655440000', - event: 'ConnectedAccount', - properties: { - totalAccounts: 4, - country: 'Denmark' - } - }).then(response => { - console.log('Event sent successfully:', response); - }).catch(error => { - console.error('Error sending event:', error); - }); + trench.track("Test Event"); ``` + This will send an event with the name `Test Event`. - You can verify that the event was received by querying the events endpoint. Use your private API key for this: - - ```bash - curl -i -X GET \ - -H "Authorization: Bearer private-YOUR_PRIVATE_API_KEY" \ - 'YOUR_SERVER_URL/events?event=ConnectedAccount' - ``` - - This will return a JSON response with the event that was just sent. Alternatively, you can verify the event was received in the `Events` tab of the Trench Cloud dashboard. - + You can verify that the event was received by opening the `Events` tab in the Trench Cloud dashboard. diff --git a/apps/docs/mint.json b/apps/docs/mint.json index 759855d..07bab43 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -75,7 +75,7 @@ "website": "https://trench.dev" }, "api": { - "baseUrl": "https://sandbox.trench.dev", + "baseUrl": "https://api.trench.dev", "auth": { "method": "bearer" } diff --git a/apps/trench/src/services/data/kafka/kafka.service.ts b/apps/trench/src/services/data/kafka/kafka.service.ts index 70c7fff..518a80f 100644 --- a/apps/trench/src/services/data/kafka/kafka.service.ts +++ b/apps/trench/src/services/data/kafka/kafka.service.ts @@ -79,22 +79,25 @@ export class KafkaService { await consumer.subscribe({ topic, fromBeginning: false }) try { - if (enableBatching) { - await consumer.run({ - eachBatch: async ({ batch }) => { + await consumer.run({ + eachBatch: async ({ batch }) => { + if (enableBatching) { + // Process all messages in batch at once await eachBatch( batch.messages.map((message) => JSON.parse(message.value.toString())), consumer ) - }, - }) - } else { - await consumer.run({ - eachMessage: async ({ topic, partition, message }) => { - await eachBatch([JSON.parse(message.value.toString())], consumer) - }, - }) - } + } else { + // Process messages one at a time + for (const message of batch.messages) { + await eachBatch([JSON.parse(message.value.toString())], consumer) + } + } + }, + autoCommit: true, + autoCommitInterval: 1000, + partitionsConsumedConcurrently: 4, + }) } catch (e) { console.log(`Error initiating consumer for groupId ${groupId}.`, e) } diff --git a/apps/trench/src/webhooks/webhooks.service.ts b/apps/trench/src/webhooks/webhooks.service.ts index 8dbefee..14c7d61 100644 --- a/apps/trench/src/webhooks/webhooks.service.ts +++ b/apps/trench/src/webhooks/webhooks.service.ts @@ -74,7 +74,6 @@ export class WebhooksService implements OnModuleInit { payloads = payloads.filter((payload) => shouldProcessEvent(payload, thisWebhook)) if (payloads.length === 0) { - console.log(`No events to process for webhook ${webhookUUID}.`) return } @@ -115,15 +114,18 @@ export class WebhooksService implements OnModuleInit { const payload = { data: events, } - await fetch(webhook.url, { + const response = await fetch(webhook.url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(webhook.flatten ? flatten(payload) : payload), }) + if (!response.ok) { + console.error('Error sending webhook:', webhook.url, response.statusText) + } } catch (error) { - console.error('Error sending webhook:', error.message) + console.error('Error sending webhook:', webhook.url, error.message) } }