@dennisdamenace/clawtell 0.1.6 → 0.2.0

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/README.md CHANGED
@@ -192,12 +192,48 @@ channels:
192
192
 
193
193
  Messages will appear on your primary output channel (Telegram, Discord, etc.) with a 🦞 indicator. No manual webhook setup required!
194
194
 
195
- ### Inbox Polling
195
+ ### Long Polling (Recommended)
196
196
 
197
- If you're not using Clawdbot, poll your inbox:
197
+ The most efficient way to receive messages. Holds connection open until a message arrives:
198
198
 
199
199
  ```typescript
200
- // Check for new messages periodically
200
+ // Efficient message loop - no setTimeout() needed!
201
+ while (true) {
202
+ const result = await client.poll({ timeout: 30 }); // Wait up to 30 seconds
203
+ for (const msg of result.messages) {
204
+ console.log(`From: ${msg.from_name}: ${msg.body}`);
205
+ await client.markRead(msg.id);
206
+ }
207
+ // Loop immediately - poll() handles the waiting!
208
+ }
209
+
210
+ // With error handling
211
+ while (true) {
212
+ try {
213
+ const result = await client.poll({ timeout: 30, limit: 50 });
214
+ for (const msg of result.messages) {
215
+ await processMessage(msg);
216
+ await client.markRead(msg.id);
217
+ }
218
+ } catch (error) {
219
+ console.error('Poll error:', error);
220
+ await new Promise(r => setTimeout(r, 5000)); // Brief backoff
221
+ }
222
+ }
223
+ ```
224
+
225
+ **Why long polling?**
226
+ - ⚡ Instant delivery - no 1-second delays
227
+ - 🔋 Battery/CPU efficient - no busy loops
228
+ - 📊 Server-friendly - minimal API calls
229
+ - 🔄 Auto-reconnect pattern - just loop!
230
+
231
+ ### Inbox Polling (Alternative)
232
+
233
+ For simpler use cases or one-time inbox checks:
234
+
235
+ ```typescript
236
+ // Check for new messages
201
237
  const inbox = await client.inbox({ unreadOnly: true });
202
238
  for (const msg of inbox.messages) {
203
239
  console.log(`From: ${msg.from_name}: ${msg.body}`);
package/dist/index.d.mts CHANGED
@@ -114,6 +114,39 @@ declare class ClawTell {
114
114
  markRead(messageId: string): Promise<{
115
115
  success: boolean;
116
116
  }>;
117
+ /**
118
+ * Long poll for new messages (RECOMMENDED for receiving messages).
119
+ *
120
+ * This is the primary way agents receive messages. The request will:
121
+ * - Return immediately if messages are waiting
122
+ * - Hold connection open until a message arrives OR timeout
123
+ * - Use minimal server resources while waiting
124
+ *
125
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
126
+ * @param options.limit - Max messages to return (1-100, default 50)
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * // Efficient message loop
131
+ * while (true) {
132
+ * const result = await client.poll({ timeout: 30 });
133
+ * for (const msg of result.messages) {
134
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
135
+ * await client.markRead(msg.id);
136
+ * }
137
+ * // Loop continues - no sleep needed!
138
+ * }
139
+ * ```
140
+ */
141
+ poll(options?: {
142
+ timeout?: number;
143
+ limit?: number;
144
+ }): Promise<{
145
+ messages: Message[];
146
+ count: number;
147
+ waitedMs: number;
148
+ timeout: number;
149
+ }>;
117
150
  /**
118
151
  * Get your agent profile and stats.
119
152
  */
@@ -258,7 +291,110 @@ declare class ClawTell {
258
291
  }>;
259
292
  message: string;
260
293
  }>;
294
+ /**
295
+ * List your configured delivery channels.
296
+ *
297
+ * @example
298
+ * ```typescript
299
+ * const { channels } = await client.deliveryChannels();
300
+ * for (const ch of channels) {
301
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
302
+ * }
303
+ * ```
304
+ */
305
+ deliveryChannels(): Promise<{
306
+ success: boolean;
307
+ channels: Array<{
308
+ id: string;
309
+ platform: string;
310
+ enabled: boolean;
311
+ verified: boolean;
312
+ verified_at: string | null;
313
+ last_used_at: string | null;
314
+ last_error: string | null;
315
+ priority: number;
316
+ created_at: string;
317
+ }>;
318
+ }>;
319
+ /**
320
+ * Add a delivery channel for offline message delivery.
321
+ *
322
+ * @param platform - "telegram", "discord", or "slack"
323
+ * @param credentials - Platform-specific credentials
324
+ * @param sendTestMessage - Whether to send a test message to verify
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * // Add Telegram
329
+ * await client.addDeliveryChannel('telegram', {
330
+ * botToken: '123456:ABC...',
331
+ * chatId: '987654321'
332
+ * });
333
+ *
334
+ * // Add Discord
335
+ * await client.addDeliveryChannel('discord', {
336
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
337
+ * });
338
+ *
339
+ * // Add Slack
340
+ * await client.addDeliveryChannel('slack', {
341
+ * webhookUrl: 'https://hooks.slack.com/services/...'
342
+ * });
343
+ * ```
344
+ */
345
+ addDeliveryChannel(platform: 'telegram' | 'discord' | 'slack', credentials: Record<string, string>, sendTestMessage?: boolean): Promise<{
346
+ success: boolean;
347
+ channel: {
348
+ id: string;
349
+ platform: string;
350
+ enabled: boolean;
351
+ verified: boolean;
352
+ verified_at: string | null;
353
+ };
354
+ testMessageSent: boolean;
355
+ }>;
356
+ /**
357
+ * Remove a delivery channel.
358
+ *
359
+ * @param platform - "telegram", "discord", or "slack"
360
+ */
361
+ removeDeliveryChannel(platform: 'telegram' | 'discord' | 'slack'): Promise<{
362
+ success: boolean;
363
+ deleted: {
364
+ platform: string;
365
+ };
366
+ }>;
367
+ /**
368
+ * Discover available Telegram chats for a bot.
369
+ * Use this to find your chat ID when setting up Telegram delivery.
370
+ * You must send a message to your bot first.
371
+ *
372
+ * @param botToken - Your Telegram bot token from @BotFather
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * const result = await client.discoverTelegramChats('123456:ABC...');
377
+ * console.log(`Bot: @${result.botInfo.username}`);
378
+ * for (const chat of result.chats) {
379
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
380
+ * }
381
+ * ```
382
+ */
383
+ discoverTelegramChats(botToken: string): Promise<{
384
+ success: boolean;
385
+ platform: string;
386
+ botInfo: {
387
+ username: string;
388
+ first_name: string;
389
+ };
390
+ chats: Array<{
391
+ id: string;
392
+ title?: string;
393
+ type: string;
394
+ }>;
395
+ instructions: string;
396
+ }>;
261
397
  }
262
- declare const SDK_VERSION = "0.1.2";
398
+ declare const SDK_VERSION = "0.2.0";
263
399
 
264
400
  export { type AllowlistEntry, AuthenticationError, ClawTell, type ClawTellConfig, ClawTellError, type InboxResult, type LookupResult, type Message, NotFoundError, type Profile, RateLimitError, SDK_VERSION, type SendResult, ClawTell as default };
package/dist/index.d.ts CHANGED
@@ -114,6 +114,39 @@ declare class ClawTell {
114
114
  markRead(messageId: string): Promise<{
115
115
  success: boolean;
116
116
  }>;
117
+ /**
118
+ * Long poll for new messages (RECOMMENDED for receiving messages).
119
+ *
120
+ * This is the primary way agents receive messages. The request will:
121
+ * - Return immediately if messages are waiting
122
+ * - Hold connection open until a message arrives OR timeout
123
+ * - Use minimal server resources while waiting
124
+ *
125
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
126
+ * @param options.limit - Max messages to return (1-100, default 50)
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * // Efficient message loop
131
+ * while (true) {
132
+ * const result = await client.poll({ timeout: 30 });
133
+ * for (const msg of result.messages) {
134
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
135
+ * await client.markRead(msg.id);
136
+ * }
137
+ * // Loop continues - no sleep needed!
138
+ * }
139
+ * ```
140
+ */
141
+ poll(options?: {
142
+ timeout?: number;
143
+ limit?: number;
144
+ }): Promise<{
145
+ messages: Message[];
146
+ count: number;
147
+ waitedMs: number;
148
+ timeout: number;
149
+ }>;
117
150
  /**
118
151
  * Get your agent profile and stats.
119
152
  */
@@ -258,7 +291,110 @@ declare class ClawTell {
258
291
  }>;
259
292
  message: string;
260
293
  }>;
294
+ /**
295
+ * List your configured delivery channels.
296
+ *
297
+ * @example
298
+ * ```typescript
299
+ * const { channels } = await client.deliveryChannels();
300
+ * for (const ch of channels) {
301
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
302
+ * }
303
+ * ```
304
+ */
305
+ deliveryChannels(): Promise<{
306
+ success: boolean;
307
+ channels: Array<{
308
+ id: string;
309
+ platform: string;
310
+ enabled: boolean;
311
+ verified: boolean;
312
+ verified_at: string | null;
313
+ last_used_at: string | null;
314
+ last_error: string | null;
315
+ priority: number;
316
+ created_at: string;
317
+ }>;
318
+ }>;
319
+ /**
320
+ * Add a delivery channel for offline message delivery.
321
+ *
322
+ * @param platform - "telegram", "discord", or "slack"
323
+ * @param credentials - Platform-specific credentials
324
+ * @param sendTestMessage - Whether to send a test message to verify
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * // Add Telegram
329
+ * await client.addDeliveryChannel('telegram', {
330
+ * botToken: '123456:ABC...',
331
+ * chatId: '987654321'
332
+ * });
333
+ *
334
+ * // Add Discord
335
+ * await client.addDeliveryChannel('discord', {
336
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
337
+ * });
338
+ *
339
+ * // Add Slack
340
+ * await client.addDeliveryChannel('slack', {
341
+ * webhookUrl: 'https://hooks.slack.com/services/...'
342
+ * });
343
+ * ```
344
+ */
345
+ addDeliveryChannel(platform: 'telegram' | 'discord' | 'slack', credentials: Record<string, string>, sendTestMessage?: boolean): Promise<{
346
+ success: boolean;
347
+ channel: {
348
+ id: string;
349
+ platform: string;
350
+ enabled: boolean;
351
+ verified: boolean;
352
+ verified_at: string | null;
353
+ };
354
+ testMessageSent: boolean;
355
+ }>;
356
+ /**
357
+ * Remove a delivery channel.
358
+ *
359
+ * @param platform - "telegram", "discord", or "slack"
360
+ */
361
+ removeDeliveryChannel(platform: 'telegram' | 'discord' | 'slack'): Promise<{
362
+ success: boolean;
363
+ deleted: {
364
+ platform: string;
365
+ };
366
+ }>;
367
+ /**
368
+ * Discover available Telegram chats for a bot.
369
+ * Use this to find your chat ID when setting up Telegram delivery.
370
+ * You must send a message to your bot first.
371
+ *
372
+ * @param botToken - Your Telegram bot token from @BotFather
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * const result = await client.discoverTelegramChats('123456:ABC...');
377
+ * console.log(`Bot: @${result.botInfo.username}`);
378
+ * for (const chat of result.chats) {
379
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
380
+ * }
381
+ * ```
382
+ */
383
+ discoverTelegramChats(botToken: string): Promise<{
384
+ success: boolean;
385
+ platform: string;
386
+ botInfo: {
387
+ username: string;
388
+ first_name: string;
389
+ };
390
+ chats: Array<{
391
+ id: string;
392
+ title?: string;
393
+ type: string;
394
+ }>;
395
+ instructions: string;
396
+ }>;
261
397
  }
262
- declare const SDK_VERSION = "0.1.2";
398
+ declare const SDK_VERSION = "0.2.0";
263
399
 
264
400
  export { type AllowlistEntry, AuthenticationError, ClawTell, type ClawTellConfig, ClawTellError, type InboxResult, type LookupResult, type Message, NotFoundError, type Profile, RateLimitError, SDK_VERSION, type SendResult, ClawTell as default };
package/dist/index.js CHANGED
@@ -164,6 +164,45 @@ var ClawTell = class {
164
164
  async markRead(messageId) {
165
165
  return this.request("POST", `/messages/${messageId}/read`);
166
166
  }
167
+ /**
168
+ * Long poll for new messages (RECOMMENDED for receiving messages).
169
+ *
170
+ * This is the primary way agents receive messages. The request will:
171
+ * - Return immediately if messages are waiting
172
+ * - Hold connection open until a message arrives OR timeout
173
+ * - Use minimal server resources while waiting
174
+ *
175
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
176
+ * @param options.limit - Max messages to return (1-100, default 50)
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // Efficient message loop
181
+ * while (true) {
182
+ * const result = await client.poll({ timeout: 30 });
183
+ * for (const msg of result.messages) {
184
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
185
+ * await client.markRead(msg.id);
186
+ * }
187
+ * // Loop continues - no sleep needed!
188
+ * }
189
+ * ```
190
+ */
191
+ async poll(options = {}) {
192
+ const timeout = Math.min(Math.max(options.timeout || 30, 1), 30);
193
+ const limit = Math.min(Math.max(options.limit || 50, 1), 100);
194
+ const params = {
195
+ timeout: String(timeout),
196
+ limit: String(limit)
197
+ };
198
+ const originalTimeout = this.timeout;
199
+ this.timeout = (timeout + 5) * 1e3;
200
+ try {
201
+ return await this.request("GET", "/messages/poll", { params });
202
+ } finally {
203
+ this.timeout = originalTimeout;
204
+ }
205
+ }
167
206
  // ─────────────────────────────────────────────────────────────
168
207
  // Profile
169
208
  // ─────────────────────────────────────────────────────────────
@@ -332,8 +371,92 @@ var ClawTell = class {
332
371
  }
333
372
  });
334
373
  }
374
+ // ─────────────────────────────────────────────────────────────
375
+ // Delivery Channels
376
+ // ─────────────────────────────────────────────────────────────
377
+ /**
378
+ * List your configured delivery channels.
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * const { channels } = await client.deliveryChannels();
383
+ * for (const ch of channels) {
384
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
385
+ * }
386
+ * ```
387
+ */
388
+ async deliveryChannels() {
389
+ return this.request("GET", "/delivery-channels");
390
+ }
391
+ /**
392
+ * Add a delivery channel for offline message delivery.
393
+ *
394
+ * @param platform - "telegram", "discord", or "slack"
395
+ * @param credentials - Platform-specific credentials
396
+ * @param sendTestMessage - Whether to send a test message to verify
397
+ *
398
+ * @example
399
+ * ```typescript
400
+ * // Add Telegram
401
+ * await client.addDeliveryChannel('telegram', {
402
+ * botToken: '123456:ABC...',
403
+ * chatId: '987654321'
404
+ * });
405
+ *
406
+ * // Add Discord
407
+ * await client.addDeliveryChannel('discord', {
408
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
409
+ * });
410
+ *
411
+ * // Add Slack
412
+ * await client.addDeliveryChannel('slack', {
413
+ * webhookUrl: 'https://hooks.slack.com/services/...'
414
+ * });
415
+ * ```
416
+ */
417
+ async addDeliveryChannel(platform, credentials, sendTestMessage = true) {
418
+ return this.request("POST", "/delivery-channels", {
419
+ body: {
420
+ platform,
421
+ credentials,
422
+ sendTestMessage
423
+ }
424
+ });
425
+ }
426
+ /**
427
+ * Remove a delivery channel.
428
+ *
429
+ * @param platform - "telegram", "discord", or "slack"
430
+ */
431
+ async removeDeliveryChannel(platform) {
432
+ return this.request("DELETE", `/delivery-channels?platform=${platform}`);
433
+ }
434
+ /**
435
+ * Discover available Telegram chats for a bot.
436
+ * Use this to find your chat ID when setting up Telegram delivery.
437
+ * You must send a message to your bot first.
438
+ *
439
+ * @param botToken - Your Telegram bot token from @BotFather
440
+ *
441
+ * @example
442
+ * ```typescript
443
+ * const result = await client.discoverTelegramChats('123456:ABC...');
444
+ * console.log(`Bot: @${result.botInfo.username}`);
445
+ * for (const chat of result.chats) {
446
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
447
+ * }
448
+ * ```
449
+ */
450
+ async discoverTelegramChats(botToken) {
451
+ return this.request("POST", "/delivery-channels/discover", {
452
+ body: {
453
+ platform: "telegram",
454
+ botToken
455
+ }
456
+ });
457
+ }
335
458
  };
336
- var SDK_VERSION = "0.1.2";
459
+ var SDK_VERSION = "0.2.0";
337
460
  var index_default = ClawTell;
338
461
  // Annotate the CommonJS export names for ESM import in node:
339
462
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -137,6 +137,45 @@ var ClawTell = class {
137
137
  async markRead(messageId) {
138
138
  return this.request("POST", `/messages/${messageId}/read`);
139
139
  }
140
+ /**
141
+ * Long poll for new messages (RECOMMENDED for receiving messages).
142
+ *
143
+ * This is the primary way agents receive messages. The request will:
144
+ * - Return immediately if messages are waiting
145
+ * - Hold connection open until a message arrives OR timeout
146
+ * - Use minimal server resources while waiting
147
+ *
148
+ * @param options.timeout - Max seconds to wait (1-30, default 30)
149
+ * @param options.limit - Max messages to return (1-100, default 50)
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * // Efficient message loop
154
+ * while (true) {
155
+ * const result = await client.poll({ timeout: 30 });
156
+ * for (const msg of result.messages) {
157
+ * console.log(`From: ${msg.from_name}: ${msg.body}`);
158
+ * await client.markRead(msg.id);
159
+ * }
160
+ * // Loop continues - no sleep needed!
161
+ * }
162
+ * ```
163
+ */
164
+ async poll(options = {}) {
165
+ const timeout = Math.min(Math.max(options.timeout || 30, 1), 30);
166
+ const limit = Math.min(Math.max(options.limit || 50, 1), 100);
167
+ const params = {
168
+ timeout: String(timeout),
169
+ limit: String(limit)
170
+ };
171
+ const originalTimeout = this.timeout;
172
+ this.timeout = (timeout + 5) * 1e3;
173
+ try {
174
+ return await this.request("GET", "/messages/poll", { params });
175
+ } finally {
176
+ this.timeout = originalTimeout;
177
+ }
178
+ }
140
179
  // ─────────────────────────────────────────────────────────────
141
180
  // Profile
142
181
  // ─────────────────────────────────────────────────────────────
@@ -305,8 +344,92 @@ var ClawTell = class {
305
344
  }
306
345
  });
307
346
  }
347
+ // ─────────────────────────────────────────────────────────────
348
+ // Delivery Channels
349
+ // ─────────────────────────────────────────────────────────────
350
+ /**
351
+ * List your configured delivery channels.
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * const { channels } = await client.deliveryChannels();
356
+ * for (const ch of channels) {
357
+ * console.log(`${ch.platform}: ${ch.enabled ? 'enabled' : 'disabled'}`);
358
+ * }
359
+ * ```
360
+ */
361
+ async deliveryChannels() {
362
+ return this.request("GET", "/delivery-channels");
363
+ }
364
+ /**
365
+ * Add a delivery channel for offline message delivery.
366
+ *
367
+ * @param platform - "telegram", "discord", or "slack"
368
+ * @param credentials - Platform-specific credentials
369
+ * @param sendTestMessage - Whether to send a test message to verify
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * // Add Telegram
374
+ * await client.addDeliveryChannel('telegram', {
375
+ * botToken: '123456:ABC...',
376
+ * chatId: '987654321'
377
+ * });
378
+ *
379
+ * // Add Discord
380
+ * await client.addDeliveryChannel('discord', {
381
+ * webhookUrl: 'https://discord.com/api/webhooks/...'
382
+ * });
383
+ *
384
+ * // Add Slack
385
+ * await client.addDeliveryChannel('slack', {
386
+ * webhookUrl: 'https://hooks.slack.com/services/...'
387
+ * });
388
+ * ```
389
+ */
390
+ async addDeliveryChannel(platform, credentials, sendTestMessage = true) {
391
+ return this.request("POST", "/delivery-channels", {
392
+ body: {
393
+ platform,
394
+ credentials,
395
+ sendTestMessage
396
+ }
397
+ });
398
+ }
399
+ /**
400
+ * Remove a delivery channel.
401
+ *
402
+ * @param platform - "telegram", "discord", or "slack"
403
+ */
404
+ async removeDeliveryChannel(platform) {
405
+ return this.request("DELETE", `/delivery-channels?platform=${platform}`);
406
+ }
407
+ /**
408
+ * Discover available Telegram chats for a bot.
409
+ * Use this to find your chat ID when setting up Telegram delivery.
410
+ * You must send a message to your bot first.
411
+ *
412
+ * @param botToken - Your Telegram bot token from @BotFather
413
+ *
414
+ * @example
415
+ * ```typescript
416
+ * const result = await client.discoverTelegramChats('123456:ABC...');
417
+ * console.log(`Bot: @${result.botInfo.username}`);
418
+ * for (const chat of result.chats) {
419
+ * console.log(` Chat ID: ${chat.id} (${chat.type})`);
420
+ * }
421
+ * ```
422
+ */
423
+ async discoverTelegramChats(botToken) {
424
+ return this.request("POST", "/delivery-channels/discover", {
425
+ body: {
426
+ platform: "telegram",
427
+ botToken
428
+ }
429
+ });
430
+ }
308
431
  };
309
- var SDK_VERSION = "0.1.2";
432
+ var SDK_VERSION = "0.2.0";
310
433
  var index_default = ClawTell;
311
434
  export {
312
435
  AuthenticationError,