signal-sdk 0.0.9 → 0.1.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
@@ -16,7 +16,9 @@
16
16
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
17
17
  [![signal-cli](https://img.shields.io/badge/signal--cli-v0.13.22-blue.svg)](https://github.com/AsamK/signal-cli)
18
18
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.8+-blue.svg)](https://www.typescriptlang.org/)
19
- [![Node.js](https://img.shields.io/badge/Node.js-16+-green.svg)](https://nodejs.org/)
19
+ [![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
20
+ [![Tests](https://img.shields.io/badge/tests-225%20passing-brightgreen.svg)](./src/__tests__)
21
+ [![Coverage](https://img.shields.io/badge/coverage-57.52%25-yellow.svg)](./src/__tests__)
20
22
  [![Donate on Liberapay](https://img.shields.io/badge/Liberapay-Donate-yellow.svg)](https://liberapay.com/devbyben/donate)
21
23
 
22
24
  </div>
@@ -25,11 +27,15 @@
25
27
 
26
28
  ### Core Capabilities
27
29
 
28
- - **JSON-RPC Communication** - Direct communication with signal-cli daemon via JSON-RPC
29
- - **TypeScript Support** - Complete type definitions with full IntelliSense support
30
+ - **JSON-RPC Communication** - Direct communication with signal-cli daemon
31
+ - **TypeScript Support** - Complete type definitions with IntelliSense
30
32
  - **Message Management** - Send, receive, and manage Signal messages
31
- - **Real-time Events** - Listen to incoming messages and notifications
32
- - **Production Ready** - Robust error handling and connection management
33
+ - **Real-time Events** - Event-driven architecture for incoming messages
34
+ - **Enterprise-Grade** - Robust error handling and retry logic
35
+ - **Type-Safe Validation** - Comprehensive input validation
36
+ - **Retry Mechanism** - Exponential backoff with configurable policies
37
+ - **Structured Logging** - Multi-level logging system
38
+ - **Configuration Management** - Centralized configuration with validation
33
39
 
34
40
  ### SignalBot Framework
35
41
 
@@ -43,18 +49,23 @@
43
49
  ### Advanced Features
44
50
 
45
51
  - **File Attachments** - Send and receive files, images, and media
46
- - **Group Operations** - Create, manage, and configure groups
47
- - **Contact Management** - Add, update, remove, and manage contacts
48
- - **Message Reactions** - React to messages with emoji reactions
52
+ - **Group Operations** - Create and manage groups with detailed information
53
+ - **Contact Management** - Manage contacts with export/import capabilities
54
+ - **Message Reactions** - React to messages with emoji
49
55
  - **Typing Indicators** - Send and receive typing notifications
50
56
  - **Read Receipts** - Track message delivery and read status
51
57
  - **Profile Management** - Update profile information and avatars
52
- - **Payment Notifications** - Send payment receipts and notifications
53
- - **Custom Sticker Packs** - Upload and manage custom sticker packs
54
- - **User Status Checking** - Verify Signal registration status
55
- - **Rate Limit Recovery** - Handle and recover from rate limiting
58
+ - **Payment Notifications** - Send payment notifications
59
+ - **Sticker Packs** - Upload and manage custom sticker packs
60
+ - **User Status** - Verify Signal registration status
61
+ - **Rate Limiting** - Handle and recover from rate limits
56
62
  - **Phone Number Changes** - Change registered phone numbers
57
- - **Progress Tracking** - Monitor upload progress for large files
63
+ - **Progress Tracking** - Monitor upload progress
64
+ - **Polls** - Create, vote, and terminate polls
65
+ - **Attachment Retrieval** - Retrieve attachments, avatars, and stickers
66
+ - **Account Management** - Update account settings
67
+ - **Stories** - View and interact with Signal stories
68
+ - **Group Information** - Retrieve detailed group permissions
58
69
 
59
70
  ## Quick Start
60
71
 
@@ -66,7 +77,7 @@ npm install signal-sdk
66
77
 
67
78
  ### Prerequisites
68
79
 
69
- 1. **Node.js** (version 16 or later)
80
+ 1. **Node.js** (version 18 or later)
70
81
  2. **Java Runtime Environment** (required by signal-cli)
71
82
 
72
83
  **Note:** signal-cli binaries are included with the SDK - no separate installation required.
@@ -117,13 +128,13 @@ This command will:
117
128
  const { SignalCli } = require("signal-sdk");
118
129
 
119
130
  // Initialize SignalCli with phone number
120
- const signal = new SignalCli("+1234567890");
131
+ const signal = new SignalCli("+33111111111");
121
132
 
122
133
  // Connect to signal-cli daemon
123
134
  await signal.connect();
124
135
 
125
136
  // Send a message
126
- await signal.sendMessage("+0987654321", "Hello from Signal CLI SDK!");
137
+ await signal.sendMessage("+33222222222", "Hello from Signal SDK!");
127
138
 
128
139
  // Listen for incoming messages
129
140
  signal.on("message", (message) => {
@@ -134,6 +145,35 @@ signal.on("message", (message) => {
134
145
  await signal.gracefulShutdown();
135
146
  ```
136
147
 
148
+ ### Advanced Configuration
149
+
150
+ ```javascript
151
+ const { SignalCli, Logger } = require("signal-sdk");
152
+
153
+ // Configure with advanced settings
154
+ const config = {
155
+ retryConfig: {
156
+ maxAttempts: 3,
157
+ initialDelay: 1000,
158
+ maxDelay: 10000,
159
+ backoffMultiplier: 2,
160
+ },
161
+ rateLimiter: {
162
+ maxConcurrent: 5,
163
+ minInterval: 200,
164
+ },
165
+ logger: new Logger("info"),
166
+ };
167
+
168
+ const signal = new SignalCli("+33111111111", undefined, config);
169
+
170
+ await signal.connect();
171
+
172
+ // SDK automatically retries on failures, respects rate limits,
173
+ // validates inputs, and logs operations
174
+ await signal.sendMessage("+33222222222", "Reliable messaging!");
175
+ ```
176
+
137
177
  ### Create a Bot
138
178
 
139
179
  ```javascript
@@ -141,8 +181,8 @@ const { SignalBot } = require("signal-sdk");
141
181
 
142
182
  // Initialize bot with configuration
143
183
  const bot = new SignalBot({
144
- phoneNumber: "+1234567890",
145
- admins: ["+0987654321"],
184
+ phoneNumber: "+33111111111",
185
+ admins: ["+33222222222"],
146
186
  group: {
147
187
  name: "My Bot Group",
148
188
  description: "A group managed by my bot",
@@ -221,10 +261,10 @@ Your bot will automatically:
221
261
 
222
262
  ```javascript
223
263
  const { SignalCli } = require("signal-sdk");
224
- const signal = new SignalCli("+1234567890");
264
+ const signal = new SignalCli("+33111111111");
225
265
 
226
266
  await signal.connect();
227
- await signal.sendMessage("+0987654321", "Hello World!");
267
+ await signal.sendMessage("+33222222222", "Hello World!");
228
268
  await signal.gracefulShutdown();
229
269
  ```
230
270
 
@@ -232,12 +272,12 @@ await signal.gracefulShutdown();
232
272
 
233
273
  ```javascript
234
274
  // Send file with message
235
- await signal.sendMessage("+0987654321", "Here's the document:", {
275
+ await signal.sendMessage("+33222222222", "Here's the document:", {
236
276
  attachments: ["./path/to/document.pdf"],
237
277
  });
238
278
 
239
279
  // Send multiple files
240
- await signal.sendMessage("+0987654321", "Photos from today:", {
280
+ await signal.sendMessage("+33222222222", "Photos from today:", {
241
281
  attachments: ["./photo1.jpg", "./photo2.jpg"],
242
282
  });
243
283
  ```
@@ -247,8 +287,8 @@ await signal.sendMessage("+0987654321", "Photos from today:", {
247
287
  ```javascript
248
288
  // Create a new group
249
289
  const group = await signal.createGroup("My Group", [
250
- "+0987654321",
251
- "+1122334455",
290
+ "+33222222222",
291
+ "+33333333333",
252
292
  ]);
253
293
  console.log("Group ID:", group.groupId);
254
294
 
@@ -268,8 +308,8 @@ await signal.updateGroup(group.groupId, {
268
308
  const { SignalBot } = require("signal-sdk");
269
309
 
270
310
  const bot = new SignalBot({
271
- phoneNumber: "+1234567890",
272
- admins: ["+0987654321"],
311
+ phoneNumber: "+33111111111",
312
+ admins: ["+33222222222"],
273
313
  });
274
314
 
275
315
  // Add weather command
@@ -291,8 +331,57 @@ bot.on("groupMemberJoined", async (event) => {
291
331
  await bot.start();
292
332
  ```
293
333
 
334
+ ## Quality & Reliability
335
+
336
+ ### Code Quality
337
+
338
+ - **TypeScript Strict Mode** - Full type safety with strict compilation
339
+ - **Complete Type Coverage** - Type definitions for all APIs
340
+ - **Input Validation** - Comprehensive validation throughout
341
+ - **Error Handling** - Robust error classes and management
342
+ - **Retry Logic** - Exponential backoff with configurable policies
343
+ - **Configuration Management** - Validated configuration system
344
+
345
+ ### Enterprise Features
346
+
347
+ - **Automatic Retries** - Configurable retry policies with exponential backoff
348
+ - **Rate Limiting** - Built-in rate limiter to prevent throttling
349
+ - **Structured Logging** - Multi-level logging system
350
+ - **Input Sanitization** - Automatic sanitization of inputs
351
+ - **E.164 Validation** - Strict international phone number validation
352
+ - **Connection Management** - Graceful connection handling
353
+
354
+ ### Technical Specifications
355
+
356
+ - **Node.js**: >=18.0.0
357
+ - **TypeScript**: 5.8+ with strict mode
358
+ - **Test Coverage**: 225 passing tests across 9 suites
359
+ - **Code Coverage**: 57.52% overall, critical modules at 96-100%
360
+ - **signal-cli**: Compatible with v0.13.22
361
+
294
362
  ## Testing
295
363
 
364
+ The SDK has comprehensive test coverage to ensure reliability and quality.
365
+
366
+ ### Test Statistics
367
+
368
+ - **Total Tests**: 225 passing
369
+ - **Test Suites**: 9 suites
370
+ - **Overall Coverage**: 57.52%
371
+
372
+ ### Coverage by Module
373
+
374
+ | Module | Statements | Branches | Functions | Lines | Status |
375
+ |--------|-----------|----------|-----------|-------|--------|
376
+ | **validators.ts** | 100% | 100% | 100% | 100% | ✅ Perfect |
377
+ | **config.ts** | 100% | 97.22% | 100% | 100% | ✅ Excellent |
378
+ | **errors.ts** | 100% | 100% | 100% | 100% | ✅ Perfect |
379
+ | **retry.ts** | 96.15% | 85.71% | 100% | 97.95% | ✅ Excellent |
380
+ | **SignalCli.ts** | 68.68% | 55.46% | 65.9% | 72.7% | ✅ Good |
381
+ | **SignalBot.ts** | 24.33% | 16.94% | 29.68% | 24.59% | ⚠️ In Progress |
382
+
383
+ ### Running Tests
384
+
296
385
  ```bash
297
386
  # Run all tests
298
387
  npm test
@@ -300,8 +389,25 @@ npm test
300
389
  # Run specific test suite
301
390
  npm test -- --testNamePattern="SignalCli"
302
391
 
303
- # Run with coverage
392
+ # Run with coverage report
304
393
  npm run test:coverage
394
+
395
+ # Run tests in watch mode
396
+ npm test -- --watch
397
+ ```
398
+
399
+ ### Test Suites
400
+
401
+ 1. **validators.test.ts** - Input validation (100% coverage)
402
+ 2. **config.test.ts** - Configuration management (100% coverage)
403
+ 3. **errors.test.ts** - Error handling (100% coverage)
404
+ 4. **retry.test.ts** - Retry logic (96% coverage)
405
+ 5. **SignalCli.test.ts** - Core CLI functionality
406
+ 6. **SignalCli.integration.test.ts** - Integration scenarios
407
+ 7. **SignalCli.methods.test.ts** - API methods (31 tests)
408
+ 8. **SignalBot.test.ts** - Bot framework
409
+ 9. **SignalBot.additional.test.ts** - Extended bot features
410
+
305
411
  ```
306
412
 
307
413
  ## Development
@@ -331,9 +437,9 @@ npm test
331
437
  Create a `.env` file in your project root:
332
438
 
333
439
  ```env
334
- SIGNAL_PHONE_NUMBER="+1234567890"
335
- SIGNAL_ADMIN_NUMBER="+0987654321"
336
- SIGNAL_RECIPIENT_NUMBER="+1122334455"
440
+ SIGNAL_PHONE_NUMBER="+33111111111"
441
+ SIGNAL_ADMIN_NUMBER="+33222222222"
442
+ SIGNAL_RECIPIENT_NUMBER="+33333333333"
337
443
  SIGNAL_GROUP_NAME="My Bot Group"
338
444
  ```
339
445
 
@@ -348,7 +454,7 @@ const signal = new SignalCli(configPath, phoneNumber);
348
454
  // phoneNumber: Your registered Signal phone number (required)
349
455
 
350
456
  // Example with custom config path
351
- const signal = new SignalCli("/custom/signal-cli/config", "+1234567890");
457
+ const signal = new SignalCli("/custom/signal-cli/config", "+33111111111");
352
458
  ```
353
459
 
354
460
  ### SignalBot Configuration
@@ -357,8 +463,8 @@ const signal = new SignalCli("/custom/signal-cli/config", "+1234567890");
357
463
  const { SignalBot } = require("signal-sdk");
358
464
 
359
465
  const bot = new SignalBot({
360
- phoneNumber: "+1234567890", // Required: Your Signal phone number
361
- admins: ["+0987654321"], // Required: Admin phone numbers
466
+ phoneNumber: "+33111111111", // Required: Your Signal phone number
467
+ admins: ["+33222222222"], // Required: Admin phone numbers
362
468
  group: {
363
469
  name: "My Bot Group", // Group name
364
470
  description: "Managed by my bot", // Group description
@@ -403,15 +509,15 @@ const bot = new SignalBot({
403
509
 
404
510
  ```bash
405
511
  # Register your phone number with Signal first
406
- signal-cli -a +1234567890 register
407
- signal-cli -a +1234567890 verify CODE_FROM_SMS
512
+ signal-cli -a +33111111111 register
513
+ signal-cli -a +33111111111 verify CODE_FROM_SMS
408
514
  ```
409
515
 
410
516
  4. **Connection timeout**
411
517
 
412
518
  ```bash
413
519
  # Test signal-cli directly
414
- signal-cli -a +1234567890 send +0987654321 "Test message"
520
+ signal-cli -a +33111111111 send +33222222222 "Test message"
415
521
  ```
416
522
 
417
523
  5. **Permission denied on config directory**
@@ -459,29 +565,39 @@ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) fi
459
565
 
460
566
  Compatible with signal-cli v0.13.22 - **100% Feature Coverage**
461
567
 
462
- | Category | Method | Description | Status |
463
- | ------------- | -------------------------- | ---------------------------------- | ------ |
464
- | **Messaging** | `send` | Send text messages and attachments | ✅ |
465
- | | `sendReaction` | React to messages with emoji | ✅ |
466
- | | `sendTyping` | Send typing indicators | ✅ |
467
- | | `sendReceipt` | Send read receipts | ✅ |
468
- | | `sendPaymentNotification` | Send payment notifications | ✅ |
469
- | **Groups** | `createGroup` | Create new groups | ✅ |
470
- | | `updateGroup` | Update group settings | ✅ |
471
- | | `listGroups` | List all groups | ✅ |
472
- | | `quitGroup` | Leave a group | ✅ |
473
- | **Contacts** | `listContacts` | List all contacts | ✅ |
474
- | | `updateContact` | Update contact information | ✅ |
475
- | | `removeContact` | Remove contacts with options | ✅ |
476
- | | `block` / `unblock` | Block/unblock contacts | ✅ |
477
- | | `getUserStatus` | Check registration status | ✅ |
478
- | **Stickers** | `listStickerPacks` | List sticker packs | ✅ |
479
- | | `addStickerPack` | Install sticker packs | ✅ |
480
- | | `uploadStickerPack` | Upload custom sticker packs | ✅ |
481
- | **Advanced** | `submitRateLimitChallenge` | Handle rate limiting | ✅ |
482
- | | `startChangeNumber` | Start phone number change | ✅ |
483
- | | `finishChangeNumber` | Complete phone number change | ✅ |
484
- | | `sendMessageWithProgress` | Enhanced messaging with progress | ✅ |
568
+ | Category | Method | Description | Status |
569
+ | --------------- | -------------------------- | ---------------------------------- | ------ |
570
+ | **Messaging** | `send` | Send text messages and attachments | ✅ |
571
+ | | `sendReaction` | React to messages with emoji | ✅ |
572
+ | | `sendTyping` | Send typing indicators | ✅ |
573
+ | | `sendReceipt` | Send read receipts | ✅ |
574
+ | | `sendPaymentNotification` | Send payment notifications | ✅ |
575
+ | | `sendPollCreate` | Create polls in conversations | ✅ |
576
+ | | `sendPollVote` | Vote on existing polls | ✅ |
577
+ | | `sendPollTerminate` | Terminate a poll | ✅ |
578
+ | **Groups** | `createGroup` | Create new groups | ✅ |
579
+ | | `updateGroup` | Update group settings | ✅ |
580
+ | | `listGroups` | List all groups | ✅ |
581
+ | | `listGroupsDetailed` | List groups with detailed info | ✅ |
582
+ | | `quitGroup` | Leave a group | ✅ |
583
+ | **Contacts** | `listContacts` | List all contacts | ✅ |
584
+ | | `updateContact` | Update contact information | ✅ |
585
+ | | `removeContact` | Remove contacts with options | ✅ |
586
+ | | `sendContacts` | Export/send contact data | ✅ |
587
+ | | `block` / `unblock` | Block/unblock contacts | ✅ |
588
+ | | `getUserStatus` | Check registration status | ✅ |
589
+ | **Account** | `updateAccount` | Update account settings | ✅ |
590
+ | | `listAccountsDetailed` | List accounts with detailed info | ✅ |
591
+ | **Attachments** | `getAttachment` | Retrieve attachment by ID | ✅ |
592
+ | | `getAvatar` | Retrieve avatar by ID | ✅ |
593
+ | | `getSticker` | Retrieve sticker by ID | ✅ |
594
+ | **Stickers** | `listStickerPacks` | List sticker packs | ✅ |
595
+ | | `addStickerPack` | Install sticker packs | ✅ |
596
+ | | `uploadStickerPack` | Upload custom sticker packs | ✅ |
597
+ | **Advanced** | `submitRateLimitChallenge` | Handle rate limiting | ✅ |
598
+ | | `startChangeNumber` | Start phone number change | ✅ |
599
+ | | `finishChangeNumber` | Complete phone number change | ✅ |
600
+ | | `sendMessageWithProgress` | Enhanced messaging with progress | ✅ |
485
601
 
486
602
  [Complete API documentation](./docs/api-reference.md)
487
603
 
@@ -1,11 +1,17 @@
1
- import { Message, Contact, GroupUpdateOptions, SendMessageOptions, ContactUpdateOptions, AccountConfiguration, Device, ReceiptType, StickerPack, IdentityKey, LinkingOptions, LinkingResult, MessageRequestResponseType, SendResponse, GroupInfo, RemoveContactOptions, UserStatusResult, PaymentNotificationData, StickerPackManifest, StickerPackUploadResult, RateLimitChallengeResult, ChangeNumberSession, UploadProgress } from './interfaces';
1
+ import { Message, Contact, GroupUpdateOptions, SendMessageOptions, ContactUpdateOptions, AccountConfiguration, Device, ReceiptType, StickerPack, IdentityKey, LinkingOptions, LinkingResult, MessageRequestResponseType, SendResponse, GroupInfo, RemoveContactOptions, UserStatusResult, PaymentNotificationData, StickerPackManifest, StickerPackUploadResult, RateLimitChallengeResult, ChangeNumberSession, UploadProgress, PollCreateOptions, PollVoteOptions, PollTerminateOptions, GetAttachmentOptions, GetAvatarOptions, GetStickerOptions, UpdateAccountOptions, AccountUpdateResult, SendContactsOptions, ListGroupsOptions } from './interfaces';
2
2
  import { EventEmitter } from 'events';
3
+ import { SignalCliConfig } from './config';
3
4
  export declare class SignalCli extends EventEmitter {
4
5
  private signalCliPath;
5
6
  private account?;
6
7
  private cliProcess;
7
8
  private requestPromises;
8
- constructor(accountOrPath?: string, account?: string);
9
+ private config;
10
+ private logger;
11
+ private rateLimiter;
12
+ private reconnectAttempts;
13
+ private maxReconnectAttempts;
14
+ constructor(accountOrPath?: string, account?: string, config?: SignalCliConfig);
9
15
  connect(): Promise<void>;
10
16
  disconnect(): void;
11
17
  gracefulShutdown(): Promise<void>;
@@ -132,4 +138,68 @@ export declare class SignalCli extends EventEmitter {
132
138
  sendMessageWithProgress(recipient: string, message: string, options?: SendMessageOptions & {
133
139
  onProgress?: (progress: UploadProgress) => void;
134
140
  }): Promise<SendResponse>;
141
+ /**
142
+ * Send a poll create message to a recipient or group.
143
+ * @param options Poll creation options
144
+ * @returns Send response with timestamp
145
+ */
146
+ sendPollCreate(options: PollCreateOptions): Promise<SendResponse>;
147
+ /**
148
+ * Send a poll vote message to vote on a poll.
149
+ * @param recipient Recipient or group ID
150
+ * @param options Poll vote options
151
+ * @returns Send response with timestamp
152
+ */
153
+ sendPollVote(recipient: string, options: PollVoteOptions): Promise<SendResponse>;
154
+ /**
155
+ * Send a poll terminate message to close a poll.
156
+ * @param recipient Recipient or group ID
157
+ * @param options Poll terminate options
158
+ * @returns Send response with timestamp
159
+ */
160
+ sendPollTerminate(recipient: string, options: PollTerminateOptions): Promise<SendResponse>;
161
+ /**
162
+ * Update account information (device name, username, privacy settings).
163
+ * @param options Account update options
164
+ * @returns Account update result
165
+ */
166
+ updateAccount(options: UpdateAccountOptions): Promise<AccountUpdateResult>;
167
+ /**
168
+ * Get raw attachment data as base64 string.
169
+ * @param options Attachment retrieval options
170
+ * @returns Base64 encoded attachment data
171
+ */
172
+ getAttachment(options: GetAttachmentOptions): Promise<string>;
173
+ /**
174
+ * Get raw avatar data as base64 string.
175
+ * @param options Avatar retrieval options
176
+ * @returns Base64 encoded avatar data
177
+ */
178
+ getAvatar(options: GetAvatarOptions): Promise<string>;
179
+ /**
180
+ * Get raw sticker data as base64 string.
181
+ * @param options Sticker retrieval options
182
+ * @returns Base64 encoded sticker data
183
+ */
184
+ getSticker(options: GetStickerOptions): Promise<string>;
185
+ /**
186
+ * Send contacts synchronization message to linked devices.
187
+ * @param options Contacts sync options
188
+ */
189
+ sendContacts(options?: SendContactsOptions): Promise<void>;
190
+ /**
191
+ * List groups with optional filtering and details.
192
+ * @param options List groups options
193
+ * @returns Array of group information
194
+ */
195
+ listGroupsDetailed(options?: ListGroupsOptions): Promise<GroupInfo[]>;
196
+ /**
197
+ * List all local accounts.
198
+ * @returns Array of account phone numbers
199
+ */
200
+ listAccountsDetailed(): Promise<Array<{
201
+ number: string;
202
+ name?: string;
203
+ uuid?: string;
204
+ }>>;
135
205
  }