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)
}
}