@channlize/core 0.1.0-alpha.1 → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # @channlize/core
2
+
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 69f414f: `submitContactForm` now sends `customFields` (they were silently dropped), so a contact form's topic, company and custom fields reach the API and the Slack post.
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - c113208: Add Events: post a Slack message from your server when something happens.
14
+
15
+ - `@channlize/core`: `client.notify(event, data?, { idempotencyKey?, channel? })` and a standalone `createNotifier()` that reads `CHANNLIZE_SERVER_API_KEY` / `CHANNLIZE_API_KEY` and `CHANNLIZE_PROJECT_ID`. Both call `POST /v1/notify` with the server API key (write scope). Event keys and data can be typed with `createNotifier<AppEvents>()` or by augmenting `ChannlizeEvents`. `trackEvent` / `trackServerEvent` are unchanged and now documented as log tracking. Fix: an explicit `baseUrl: undefined` or `timeout: undefined` no longer overrides the defaults.
16
+ - `@channlize/mcp`: new `notify_event` tool, enabled with `--server-api-key` / `CHANNLIZE_SERVER_API_KEY`.
17
+ - `@channlize/react`: docs only. `useChannlizeAnalytics().track` is documented as log tracking.
18
+
19
+ ## 0.1.0
20
+
21
+ ### Minor Changes
22
+
23
+ - 9ddf630: Errors thrown by the client now carry the API's human-readable `message`
24
+ (field messages joined for validation failures) instead of the error code,
25
+ and `ChannlizeError.code` is set from the API's `error` code.
26
+
27
+ `CreateContactResponse` gains the fields the API actually returns:
28
+ `success`, `conversationId` and `message`. The old `id`, `status` and
29
+ `slackThreadUrl` fields were never returned and are deprecated. The MCP
30
+ `submit_contact_form` tool now reports `conversationId`.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @channlize/core
2
2
 
3
- Core TypeScript SDK for the Channlize platform. Provides API client functionality for submitting contact forms and managing chat sessions.
3
+ Core TypeScript SDK for the Channlize platform. Provides API client functionality for submitting contact forms, managing chat sessions, posting Events to Slack from your server, and log tracking.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,6 +8,15 @@ Core TypeScript SDK for the Channlize platform. Provides API client functionalit
8
8
  npm install @channlize/core
9
9
  ```
10
10
 
11
+ ## Quick start: notify Slack from your server (Events)
12
+
13
+ ```typescript
14
+ import { createNotifier } from '@channlize/core';
15
+
16
+ const notify = createNotifier(); // reads CHANNLIZE_API_KEY (server key) + CHANNLIZE_PROJECT_ID
17
+ await notify('user.subscribed', { username: user.name, plan: 'Pro' });
18
+ ```
19
+
11
20
  ## Usage
12
21
 
13
22
  ### Basic Setup
@@ -68,6 +77,76 @@ const messages = await client.getChatMessages(session.id, 50, 0);
68
77
 
69
78
  // Close session
70
79
  await client.closeChatSession(session.id);
80
+
81
+ ```
82
+
83
+ ### Events: notify Slack from your server
84
+
85
+ Post a Slack message when something happens in your app. Each event key (`user.subscribed`, `invoice.paid`…) has its own Slack channel and message template, configured under **Events** in the dashboard; `data` fills the template's `{{field}}` placeholders (e.g. `:tada: *{{username}}* subscribed to {{plan}}`).
86
+
87
+ ```typescript
88
+ import { createNotifier } from '@channlize/core';
89
+
90
+ // Server key from CHANNLIZE_SERVER_API_KEY or CHANNLIZE_API_KEY (ch_live_…, write scope),
91
+ // project from CHANNLIZE_PROJECT_ID, API from CHANNLIZE_BASE_URL (optional).
92
+ // Or pass them: createNotifier({ serverApiKey, projectId, baseUrl }).
93
+ const notify = createNotifier();
94
+
95
+ const res = await notify('user.subscribed', { username: 'ada', plan: 'Pro' });
96
+ // res.status: 'queued' (posting to Slack) or 'skipped' (see res.reason)
97
+
98
+ // Retry-safe: the same idempotency key is only posted once.
99
+ await notify('invoice.paid', { amount: '$49' }, { idempotencyKey: invoice.id });
100
+
101
+ // Post one call to another channel (Slack channel ID).
102
+ await notify('deploy.finished', { version: '1.4.2' }, { channel: 'C0123456' });
103
+
104
+ // Or on a client configured with serverApiKey + projectId:
105
+ await client.notify('user.subscribed', { username: 'ada', plan: 'Pro' });
106
+ ```
107
+
108
+ - **Server only.** It needs a server API key; never ship it to the browser. Calling with the public widget key (`wk_…`) throws a `ValidationError`.
109
+ - **Ship code before configuring.** An event key the dashboard doesn't know yet is saved as a disabled draft and answered `status: 'skipped'` (no exception), ready to configure and enable.
110
+ - The Channlize bot must be in the Slack channel (`/invite @Channlize`); otherwise the delivery fails, and the dashboard shows why under **Events → Recent deliveries**.
111
+
112
+ Typed event names and data (optional):
113
+
114
+ ```typescript
115
+ type AppEvents = {
116
+ 'user.subscribed': { username: string; plan: string };
117
+ 'invoice.paid': { amount: string };
118
+ };
119
+ const notify = createNotifier<AppEvents>();
120
+ await notify('user.subscribed', { username: 'ada', plan: 'Pro' }); // autocompleted + type-checked
121
+
122
+ // Or app-wide, for client.notify too:
123
+ declare module '@channlize/core' {
124
+ interface ChannlizeEvents {
125
+ 'user.subscribed': { username: string; plan: string };
126
+ }
127
+ }
128
+ ```
129
+
130
+ Without the SDK:
131
+
132
+ ```bash
133
+ curl -X POST https://api.channlize.com/api/v1/notify \
134
+ -H "Authorization: Bearer $CHANNLIZE_API_KEY" \
135
+ -H "Content-Type: application/json" \
136
+ -H "Idempotency-Key: signup-42" \
137
+ -d '{"projectId":"<project id>","event":"user.subscribed","data":{"username":"ada","plan":"Pro"}}'
138
+ ```
139
+
140
+ ### Log tracking
141
+
142
+ Record logs that show up under **Log tracking** in the dashboard (Settings → Log tracking can alert Slack on matching logs).
143
+
144
+ ```typescript
145
+ // Browser (widget key)
146
+ await client.trackEvent('page.viewed', { properties: { path: '/pricing' } });
147
+
148
+ // Server (set serverApiKey on the client)
149
+ await client.trackServerEvent('webhook.received', { severity: 'warning' });
71
150
  ```
72
151
 
73
152
  ### Error Handling
@@ -105,8 +184,9 @@ try {
105
184
 
106
185
  ```typescript
107
186
  interface ChannlizeConfig {
108
- apiKey: string; // Required: Your API key
187
+ apiKey: string; // Required: Your widget key
109
188
  projectId: string; // Required: Your project ID
189
+ serverApiKey?: string; // Server-side only: server API key, for notify / trackServerEvent
110
190
  baseUrl?: string; // Optional: API base URL
111
191
  timeout?: number; // Optional: Request timeout in ms
112
192
  }
@@ -120,6 +200,13 @@ interface ChannlizeConfig {
120
200
  - `getChatSession(sessionId: string): Promise<ChatSession>`
121
201
  - `getChatMessages(sessionId: string, limit?: number, offset?: number): Promise<ChatMessage[]>`
122
202
  - `closeChatSession(sessionId: string): Promise<ChatSession>`
203
+ - `notify(event: string, data?: Record<string, unknown>, options?: NotifyOptions): Promise<NotifyResponse>` — Events (server)
204
+ - `trackEvent(name: string, options?: TrackEventOptions)` — log tracking (browser)
205
+ - `trackServerEvent(name: string, options?)` — log tracking (server)
206
+
207
+ ### createNotifier
208
+
209
+ `createNotifier<TEvents>(config?: NotifierConfig): (event, data?, options?) => Promise<NotifyResponse>` — standalone server-side Events sender (see above).
123
210
 
124
211
  ### Types
125
212
 
package/dist/index.d.mts CHANGED
@@ -1,15 +1,88 @@
1
1
  /**
2
2
  * Core types for Channlize SDK
3
3
  */
4
+ /** Severity for log tracking (`trackEvent` / `trackServerEvent`); Slack alerts use project settings. */
5
+ type EventSeverity = 'info' | 'warning' | 'error';
6
+ /** Options for log tracking (`trackEvent` / `trackServerEvent`). */
7
+ interface TrackEventOptions {
8
+ properties?: Record<string, unknown>;
9
+ severity?: EventSeverity;
10
+ distinctId?: string;
11
+ pageUrl?: string;
12
+ userAgent?: string;
13
+ }
4
14
  interface ChannlizeConfig {
5
- /** API key for authentication */
15
+ /** Widget key used for public SDK endpoints (contact form, chat, browser log tracking) */
6
16
  apiKey: string;
7
17
  /** Base URL for the Channlize API */
8
18
  baseUrl?: string;
9
- /** Project ID */
19
+ /** Project ID (required for server-side `trackServerEvent` and `notify`) */
10
20
  projectId: string;
11
21
  /** Request timeout in milliseconds */
12
22
  timeout?: number;
23
+ /**
24
+ * Organization (server) API key, `ch_live_…`, for `trackServerEvent`
25
+ * (`POST /v1/events`) and `notify` (`POST /v1/notify`, needs the `write`
26
+ * scope). Do not expose in browser bundles.
27
+ */
28
+ serverApiKey?: string;
29
+ }
30
+ /**
31
+ * Events (notify Slack from code). Augment this interface to type event
32
+ * keys and their data across your app:
33
+ *
34
+ * ```ts
35
+ * declare module '@channlize/core' {
36
+ * interface ChannlizeEvents {
37
+ * 'user.subscribed': { username: string; plan: string };
38
+ * }
39
+ * }
40
+ * ```
41
+ *
42
+ * Or pass a map as a type argument: `createNotifier<AppEvents>()`.
43
+ */
44
+ interface ChannlizeEvents {
45
+ }
46
+ /** A declared event key (autocompleted) or any other key. */
47
+ type NotifyEventName<TEvents extends object = ChannlizeEvents> = (keyof TEvents & string) | (string & {});
48
+ /** The declared data for a key, or any object for undeclared keys. */
49
+ type NotifyEventData<TEvents extends object = ChannlizeEvents, K = string> = K extends keyof TEvents ? TEvents[K] : Record<string, unknown>;
50
+ interface NotifyOptions {
51
+ /**
52
+ * Retry-safe sends: a key already used on the project returns the first
53
+ * delivery (`duplicate: true`) and posts nothing. Sent as `Idempotency-Key`.
54
+ */
55
+ idempotencyKey?: string;
56
+ /** Slack channel ID to post to instead of the event's channel, for this call. */
57
+ channel?: string;
58
+ }
59
+ interface NotifyResponse {
60
+ success: boolean;
61
+ /** Delivery ID (see Events → Recent deliveries in the dashboard). */
62
+ id: string;
63
+ event: string;
64
+ /**
65
+ * `queued`: will be posted to Slack. `skipped`: not posted (see `reason`):
66
+ * the event is disabled, is new (saved as a draft to configure), or there
67
+ * is no Slack workspace / channel. With `duplicate`, the first call's status.
68
+ */
69
+ status: 'queued' | 'skipped' | 'sent' | 'failed';
70
+ reason?: string;
71
+ duplicate?: boolean;
72
+ }
73
+ /** `createNotifier` options; each falls back to an environment variable. */
74
+ interface NotifierConfig {
75
+ /**
76
+ * Server API key (`ch_live_…`, write scope). Default:
77
+ * `CHANNLIZE_SERVER_API_KEY`, else `CHANNLIZE_API_KEY`.
78
+ */
79
+ serverApiKey?: string;
80
+ /** Project ID. Default: `CHANNLIZE_PROJECT_ID`. */
81
+ projectId?: string;
82
+ /** API base URL. Default: `CHANNLIZE_BASE_URL`, else `https://api.channlize.com`. */
83
+ baseUrl?: string;
84
+ /** Request timeout in ms (default 10000). */
85
+ timeout?: number;
13
86
  }
14
87
  interface ContactFormData {
15
88
  /** Contact's name */
@@ -81,12 +154,19 @@ interface ApiResponse<T = unknown> {
81
154
  /** Additional metadata */
82
155
  meta?: Record<string, unknown>;
83
156
  }
157
+ /** Response of `POST /public/contact` (api/app/api/public/contact/route.ts). */
84
158
  interface CreateContactResponse {
85
- /** Contact form submission ID */
159
+ /** Whether the submission was accepted */
160
+ success: boolean;
161
+ /** Conversation the submission was filed under */
162
+ conversationId: string;
163
+ /** Human-readable confirmation to show the visitor */
164
+ message: string;
165
+ /** @deprecated Never returned by the API (always undefined). Use `conversationId`. */
86
166
  id: string;
87
- /** Status of the submission */
167
+ /** @deprecated Never returned by the API (always undefined). */
88
168
  status: 'received' | 'processing' | 'delivered';
89
- /** Slack thread URL if available */
169
+ /** @deprecated Never returned by the API (always undefined). */
90
170
  slackThreadUrl?: string;
91
171
  }
92
172
  interface CreateChatSessionResponse {
@@ -122,14 +202,16 @@ declare class RateLimitError extends ChannlizeError {
122
202
 
123
203
  /**
124
204
  * Channlize API Client
125
- * Provides methods to interact with the Channlize platform
205
+ * Provides methods to interact with the Channlize platform.
206
+ *
207
+ * `TEvents` types `notify()` event keys and data (defaults to the
208
+ * augmentable `ChannlizeEvents` interface; any string key is accepted).
126
209
  */
127
- declare class ChannlizeClient {
210
+ declare class ChannlizeClient<TEvents extends object = ChannlizeEvents> {
128
211
  private readonly config;
129
212
  constructor(config: ChannlizeConfig);
130
213
  private validateConfig;
131
214
  private makeRequest;
132
- private handleErrorResponse;
133
215
  /**
134
216
  * Submit a contact form
135
217
  */
@@ -139,7 +221,9 @@ declare class ChannlizeClient {
139
221
  */
140
222
  createChatSession(metadata?: Record<string, unknown>): Promise<CreateChatSessionResponse>;
141
223
  /**
142
- * Send a message in a chat session
224
+ * Send a message in a chat session.
225
+ * When `attachments` are provided the request is sent as multipart/form-data
226
+ * so the files are uploaded alongside the message content.
143
227
  */
144
228
  sendMessage(sessionId: string, content: string, attachments?: File[]): Promise<SendMessageResponse>;
145
229
  /**
@@ -154,6 +238,51 @@ declare class ChannlizeClient {
154
238
  * Close a chat session
155
239
  */
156
240
  closeChatSession(sessionId: string): Promise<ChatSession>;
241
+ /**
242
+ * Log tracking: record a log line from the browser (widget key →
243
+ * `POST /public/events`). Shown under Log tracking in the dashboard.
244
+ */
245
+ trackEvent(name: string, options?: TrackEventOptions): Promise<{
246
+ success: boolean;
247
+ id: string;
248
+ }>;
249
+ /**
250
+ * Log tracking from a trusted server, using the organization API key
251
+ * (`POST /v1/events`). Shown under Log tracking in the dashboard.
252
+ */
253
+ trackServerEvent(name: string, options?: {
254
+ properties?: Record<string, unknown>;
255
+ severity?: EventSeverity;
256
+ }): Promise<{
257
+ success: boolean;
258
+ id: string;
259
+ }>;
260
+ /**
261
+ * Events: post a Slack message from your server when something happens
262
+ * (`POST /v1/notify`). The event key picks the channel and message
263
+ * template configured under Events in the dashboard; `data` fills the
264
+ * template's `{{field}}` placeholders. Needs `serverApiKey` (write scope)
265
+ * and `projectId` — never call it from browser code.
266
+ *
267
+ * An unknown key is saved as a disabled draft and answered with
268
+ * `status: 'skipped'`, so it never throws for a missing setup.
269
+ */
270
+ notify<K extends NotifyEventName<TEvents>>(event: K, data?: NotifyEventData<TEvents, K>, options?: NotifyOptions): Promise<NotifyResponse>;
157
271
  }
158
272
 
159
- export { type ApiResponse, AuthenticationError, ChannlizeClient, type ChannlizeConfig, ChannlizeError, type ChatMessage, type ChatSession, type ContactFormData, type CreateChatSessionResponse, type CreateContactResponse, type FileAttachment, RateLimitError, type SendMessageResponse, ValidationError, ChannlizeClient as default };
273
+ type Notifier<TEvents extends object = ChannlizeEvents> = <K extends NotifyEventName<TEvents>>(event: K, data?: NotifyEventData<TEvents, K>, options?: NotifyOptions) => Promise<NotifyResponse>;
274
+ /**
275
+ * Events: a standalone server-side `notify(event, data)` function. Reads
276
+ * the server key from `CHANNLIZE_SERVER_API_KEY` or `CHANNLIZE_API_KEY`, and
277
+ * `CHANNLIZE_PROJECT_ID`, unless given — when it is called, so creating it
278
+ * at module load never throws.
279
+ *
280
+ * ```ts
281
+ * const notify = createNotifier();
282
+ * await notify('user.subscribed', { username: 'ada', plan: 'Pro' });
283
+ * ```
284
+ */
285
+ declare function createNotifier<TEvents extends object = ChannlizeEvents>(config?: NotifierConfig): Notifier<TEvents>;
286
+
287
+ export { AuthenticationError, ChannlizeClient, ChannlizeError, RateLimitError, ValidationError, createNotifier, ChannlizeClient as default };
288
+ export type { ApiResponse, ChannlizeConfig, ChannlizeEvents, ChatMessage, ChatSession, ContactFormData, CreateChatSessionResponse, CreateContactResponse, EventSeverity, FileAttachment, Notifier, NotifierConfig, NotifyEventData, NotifyEventName, NotifyOptions, NotifyResponse, SendMessageResponse, TrackEventOptions };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,88 @@
1
1
  /**
2
2
  * Core types for Channlize SDK
3
3
  */
4
+ /** Severity for log tracking (`trackEvent` / `trackServerEvent`); Slack alerts use project settings. */
5
+ type EventSeverity = 'info' | 'warning' | 'error';
6
+ /** Options for log tracking (`trackEvent` / `trackServerEvent`). */
7
+ interface TrackEventOptions {
8
+ properties?: Record<string, unknown>;
9
+ severity?: EventSeverity;
10
+ distinctId?: string;
11
+ pageUrl?: string;
12
+ userAgent?: string;
13
+ }
4
14
  interface ChannlizeConfig {
5
- /** API key for authentication */
15
+ /** Widget key used for public SDK endpoints (contact form, chat, browser log tracking) */
6
16
  apiKey: string;
7
17
  /** Base URL for the Channlize API */
8
18
  baseUrl?: string;
9
- /** Project ID */
19
+ /** Project ID (required for server-side `trackServerEvent` and `notify`) */
10
20
  projectId: string;
11
21
  /** Request timeout in milliseconds */
12
22
  timeout?: number;
23
+ /**
24
+ * Organization (server) API key, `ch_live_…`, for `trackServerEvent`
25
+ * (`POST /v1/events`) and `notify` (`POST /v1/notify`, needs the `write`
26
+ * scope). Do not expose in browser bundles.
27
+ */
28
+ serverApiKey?: string;
29
+ }
30
+ /**
31
+ * Events (notify Slack from code). Augment this interface to type event
32
+ * keys and their data across your app:
33
+ *
34
+ * ```ts
35
+ * declare module '@channlize/core' {
36
+ * interface ChannlizeEvents {
37
+ * 'user.subscribed': { username: string; plan: string };
38
+ * }
39
+ * }
40
+ * ```
41
+ *
42
+ * Or pass a map as a type argument: `createNotifier<AppEvents>()`.
43
+ */
44
+ interface ChannlizeEvents {
45
+ }
46
+ /** A declared event key (autocompleted) or any other key. */
47
+ type NotifyEventName<TEvents extends object = ChannlizeEvents> = (keyof TEvents & string) | (string & {});
48
+ /** The declared data for a key, or any object for undeclared keys. */
49
+ type NotifyEventData<TEvents extends object = ChannlizeEvents, K = string> = K extends keyof TEvents ? TEvents[K] : Record<string, unknown>;
50
+ interface NotifyOptions {
51
+ /**
52
+ * Retry-safe sends: a key already used on the project returns the first
53
+ * delivery (`duplicate: true`) and posts nothing. Sent as `Idempotency-Key`.
54
+ */
55
+ idempotencyKey?: string;
56
+ /** Slack channel ID to post to instead of the event's channel, for this call. */
57
+ channel?: string;
58
+ }
59
+ interface NotifyResponse {
60
+ success: boolean;
61
+ /** Delivery ID (see Events → Recent deliveries in the dashboard). */
62
+ id: string;
63
+ event: string;
64
+ /**
65
+ * `queued`: will be posted to Slack. `skipped`: not posted (see `reason`):
66
+ * the event is disabled, is new (saved as a draft to configure), or there
67
+ * is no Slack workspace / channel. With `duplicate`, the first call's status.
68
+ */
69
+ status: 'queued' | 'skipped' | 'sent' | 'failed';
70
+ reason?: string;
71
+ duplicate?: boolean;
72
+ }
73
+ /** `createNotifier` options; each falls back to an environment variable. */
74
+ interface NotifierConfig {
75
+ /**
76
+ * Server API key (`ch_live_…`, write scope). Default:
77
+ * `CHANNLIZE_SERVER_API_KEY`, else `CHANNLIZE_API_KEY`.
78
+ */
79
+ serverApiKey?: string;
80
+ /** Project ID. Default: `CHANNLIZE_PROJECT_ID`. */
81
+ projectId?: string;
82
+ /** API base URL. Default: `CHANNLIZE_BASE_URL`, else `https://api.channlize.com`. */
83
+ baseUrl?: string;
84
+ /** Request timeout in ms (default 10000). */
85
+ timeout?: number;
13
86
  }
14
87
  interface ContactFormData {
15
88
  /** Contact's name */
@@ -81,12 +154,19 @@ interface ApiResponse<T = unknown> {
81
154
  /** Additional metadata */
82
155
  meta?: Record<string, unknown>;
83
156
  }
157
+ /** Response of `POST /public/contact` (api/app/api/public/contact/route.ts). */
84
158
  interface CreateContactResponse {
85
- /** Contact form submission ID */
159
+ /** Whether the submission was accepted */
160
+ success: boolean;
161
+ /** Conversation the submission was filed under */
162
+ conversationId: string;
163
+ /** Human-readable confirmation to show the visitor */
164
+ message: string;
165
+ /** @deprecated Never returned by the API (always undefined). Use `conversationId`. */
86
166
  id: string;
87
- /** Status of the submission */
167
+ /** @deprecated Never returned by the API (always undefined). */
88
168
  status: 'received' | 'processing' | 'delivered';
89
- /** Slack thread URL if available */
169
+ /** @deprecated Never returned by the API (always undefined). */
90
170
  slackThreadUrl?: string;
91
171
  }
92
172
  interface CreateChatSessionResponse {
@@ -122,14 +202,16 @@ declare class RateLimitError extends ChannlizeError {
122
202
 
123
203
  /**
124
204
  * Channlize API Client
125
- * Provides methods to interact with the Channlize platform
205
+ * Provides methods to interact with the Channlize platform.
206
+ *
207
+ * `TEvents` types `notify()` event keys and data (defaults to the
208
+ * augmentable `ChannlizeEvents` interface; any string key is accepted).
126
209
  */
127
- declare class ChannlizeClient {
210
+ declare class ChannlizeClient<TEvents extends object = ChannlizeEvents> {
128
211
  private readonly config;
129
212
  constructor(config: ChannlizeConfig);
130
213
  private validateConfig;
131
214
  private makeRequest;
132
- private handleErrorResponse;
133
215
  /**
134
216
  * Submit a contact form
135
217
  */
@@ -139,7 +221,9 @@ declare class ChannlizeClient {
139
221
  */
140
222
  createChatSession(metadata?: Record<string, unknown>): Promise<CreateChatSessionResponse>;
141
223
  /**
142
- * Send a message in a chat session
224
+ * Send a message in a chat session.
225
+ * When `attachments` are provided the request is sent as multipart/form-data
226
+ * so the files are uploaded alongside the message content.
143
227
  */
144
228
  sendMessage(sessionId: string, content: string, attachments?: File[]): Promise<SendMessageResponse>;
145
229
  /**
@@ -154,6 +238,51 @@ declare class ChannlizeClient {
154
238
  * Close a chat session
155
239
  */
156
240
  closeChatSession(sessionId: string): Promise<ChatSession>;
241
+ /**
242
+ * Log tracking: record a log line from the browser (widget key →
243
+ * `POST /public/events`). Shown under Log tracking in the dashboard.
244
+ */
245
+ trackEvent(name: string, options?: TrackEventOptions): Promise<{
246
+ success: boolean;
247
+ id: string;
248
+ }>;
249
+ /**
250
+ * Log tracking from a trusted server, using the organization API key
251
+ * (`POST /v1/events`). Shown under Log tracking in the dashboard.
252
+ */
253
+ trackServerEvent(name: string, options?: {
254
+ properties?: Record<string, unknown>;
255
+ severity?: EventSeverity;
256
+ }): Promise<{
257
+ success: boolean;
258
+ id: string;
259
+ }>;
260
+ /**
261
+ * Events: post a Slack message from your server when something happens
262
+ * (`POST /v1/notify`). The event key picks the channel and message
263
+ * template configured under Events in the dashboard; `data` fills the
264
+ * template's `{{field}}` placeholders. Needs `serverApiKey` (write scope)
265
+ * and `projectId` — never call it from browser code.
266
+ *
267
+ * An unknown key is saved as a disabled draft and answered with
268
+ * `status: 'skipped'`, so it never throws for a missing setup.
269
+ */
270
+ notify<K extends NotifyEventName<TEvents>>(event: K, data?: NotifyEventData<TEvents, K>, options?: NotifyOptions): Promise<NotifyResponse>;
157
271
  }
158
272
 
159
- export { type ApiResponse, AuthenticationError, ChannlizeClient, type ChannlizeConfig, ChannlizeError, type ChatMessage, type ChatSession, type ContactFormData, type CreateChatSessionResponse, type CreateContactResponse, type FileAttachment, RateLimitError, type SendMessageResponse, ValidationError, ChannlizeClient as default };
273
+ type Notifier<TEvents extends object = ChannlizeEvents> = <K extends NotifyEventName<TEvents>>(event: K, data?: NotifyEventData<TEvents, K>, options?: NotifyOptions) => Promise<NotifyResponse>;
274
+ /**
275
+ * Events: a standalone server-side `notify(event, data)` function. Reads
276
+ * the server key from `CHANNLIZE_SERVER_API_KEY` or `CHANNLIZE_API_KEY`, and
277
+ * `CHANNLIZE_PROJECT_ID`, unless given — when it is called, so creating it
278
+ * at module load never throws.
279
+ *
280
+ * ```ts
281
+ * const notify = createNotifier();
282
+ * await notify('user.subscribed', { username: 'ada', plan: 'Pro' });
283
+ * ```
284
+ */
285
+ declare function createNotifier<TEvents extends object = ChannlizeEvents>(config?: NotifierConfig): Notifier<TEvents>;
286
+
287
+ export { AuthenticationError, ChannlizeClient, ChannlizeError, RateLimitError, ValidationError, createNotifier, ChannlizeClient as default };
288
+ export type { ApiResponse, ChannlizeConfig, ChannlizeEvents, ChatMessage, ChatSession, ContactFormData, CreateChatSessionResponse, CreateContactResponse, EventSeverity, FileAttachment, Notifier, NotifierConfig, NotifyEventData, NotifyEventName, NotifyOptions, NotifyResponse, SendMessageResponse, TrackEventOptions };