signal-sdk 0.0.1 → 0.0.3

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
@@ -59,6 +59,29 @@ npm install
59
59
 
60
60
  [Detailed installation guide](./docs/installation.md)
61
61
 
62
+ ### Device Linking
63
+
64
+ Before using the SDK, you need to link a device to your Signal account:
65
+
66
+ ```bash
67
+ # Using npx (recommended)
68
+ npx signal-sdk connect
69
+
70
+ # Or with a custom device name
71
+ npx signal-sdk connect "My Bot Device"
72
+
73
+ # Or using npm script after installation
74
+ cd node_modules/signal-sdk
75
+ npm run connect
76
+ ```
77
+
78
+ This command will:
79
+ 1. šŸ”— Generate a QR code in your terminal
80
+ 2. šŸ“± Display instructions for scanning with your Signal app
81
+ 3. āœ… Complete the device linking process
82
+
83
+ **Note:** You only need to do this once per device. After linking, your device will be permanently connected to your Signal account.
84
+
62
85
  ### Basic Usage
63
86
 
64
87
  ```javascript
@@ -5,7 +5,7 @@ export declare class SignalCli extends EventEmitter {
5
5
  private account?;
6
6
  private cliProcess;
7
7
  private requestPromises;
8
- constructor(signalCliPath?: string, account?: string);
8
+ constructor(accountOrPath?: string, account?: string);
9
9
  connect(): Promise<void>;
10
10
  disconnect(): void;
11
11
  gracefulShutdown(): Promise<void>;
package/dist/SignalCli.js CHANGED
@@ -40,10 +40,25 @@ const qrcodeTerminal = __importStar(require("qrcode-terminal"));
40
40
  const events_1 = require("events");
41
41
  const path = __importStar(require("path"));
42
42
  class SignalCli extends events_1.EventEmitter {
43
- constructor(signalCliPath, account) {
43
+ constructor(accountOrPath, account) {
44
44
  super();
45
45
  this.cliProcess = null;
46
46
  this.requestPromises = new Map();
47
+ let signalCliPath;
48
+ let phoneNumber;
49
+ // Smart parameter detection
50
+ if (typeof accountOrPath === 'string') {
51
+ if (accountOrPath.startsWith('+')) {
52
+ // First parameter is a phone number
53
+ phoneNumber = accountOrPath;
54
+ signalCliPath = undefined;
55
+ }
56
+ else {
57
+ // First parameter is a path, second is phone number
58
+ signalCliPath = accountOrPath;
59
+ phoneNumber = account;
60
+ }
61
+ }
47
62
  // Determine the correct signal-cli path based on platform
48
63
  let defaultPath;
49
64
  if (process.platform === 'win32') {
@@ -54,7 +69,7 @@ class SignalCli extends events_1.EventEmitter {
54
69
  defaultPath = path.join(__dirname, '..', 'bin', 'bin', 'signal-cli');
55
70
  }
56
71
  this.signalCliPath = signalCliPath || defaultPath;
57
- this.account = account;
72
+ this.account = phoneNumber;
58
73
  }
59
74
  async connect() {
60
75
  const args = this.account ? ['-a', this.account, 'jsonRpc'] : ['jsonRpc'];
@@ -73,8 +88,33 @@ class SignalCli extends events_1.EventEmitter {
73
88
  });
74
89
  this.cliProcess.on('error', (err) => this.emit('error', err));
75
90
  return new Promise((resolve, reject) => {
76
- this.cliProcess?.stdout?.once('data', () => resolve());
77
- this.cliProcess?.once('error', (err) => reject(err));
91
+ // Set a timeout to resolve the promise even if no data is received
92
+ const connectTimeout = setTimeout(() => {
93
+ // Test if the process is still alive and responsive
94
+ if (this.cliProcess && !this.cliProcess.killed) {
95
+ resolve();
96
+ }
97
+ else {
98
+ reject(new Error('signal-cli process failed to start'));
99
+ }
100
+ }, 2000); // Wait 2 seconds max
101
+ // If we get data quickly, resolve immediately
102
+ this.cliProcess?.stdout?.once('data', () => {
103
+ clearTimeout(connectTimeout);
104
+ resolve();
105
+ });
106
+ // If there's an error, reject
107
+ this.cliProcess?.once('error', (err) => {
108
+ clearTimeout(connectTimeout);
109
+ reject(err);
110
+ });
111
+ // If the process exits immediately, that's an error
112
+ this.cliProcess?.once('close', (code) => {
113
+ clearTimeout(connectTimeout);
114
+ if (code !== 0) {
115
+ reject(new Error(`signal-cli exited with code ${code}`));
116
+ }
117
+ });
78
118
  });
79
119
  }
80
120
  disconnect() {
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "signal-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A comprehensive TypeScript SDK for Signal CLI with native JSON-RPC support, providing high-performance messaging, bot framework, and full signal-cli integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "signal-sdk": "scripts/cli.js"
9
+ },
7
10
  "files": [
8
11
  "dist/",
12
+ "scripts/",
9
13
  "README.md",
10
14
  "LICENSE"
11
15
  ],
@@ -13,6 +17,7 @@
13
17
  "build": "tsc",
14
18
  "test": "jest",
15
19
  "postinstall": "node scripts/install.js",
20
+ "connect": "node scripts/connect.js",
16
21
  "signal:connect": "node examples/sdk/00-device-linking.js",
17
22
  "example:basic": "node examples/sdk/01-basic-usage.js",
18
23
  "example:quick-start": "node examples/sdk/02-quick-start.js",
package/scripts/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Signal SDK - CLI Tool
5
+ *
6
+ * Command-line interface for Signal SDK operations
7
+ */
8
+
9
+ const { spawn } = require('child_process');
10
+ const path = require('path');
11
+
12
+ function showHelp() {
13
+ console.log('Signal SDK - Command Line Interface');
14
+ console.log('===================================\n');
15
+ console.log('Usage:');
16
+ console.log(' npx signal-sdk <command> [options]\n');
17
+ console.log('Commands:');
18
+ console.log(' connect [device-name] Link a new device with QR code');
19
+ console.log(' help Show this help message\n');
20
+ console.log('Examples:');
21
+ console.log(' npx signal-sdk connect');
22
+ console.log(' npx signal-sdk connect "My Bot Device"');
23
+ console.log(' npx signal-sdk help\n');
24
+ console.log('For more information, visit: https://github.com/benoitpetit/signal-sdk');
25
+ }
26
+
27
+ function runCommand(scriptName, args = []) {
28
+ const scriptPath = path.join(__dirname, `${scriptName}.js`);
29
+ const child = spawn('node', [scriptPath, ...args], {
30
+ stdio: 'inherit',
31
+ cwd: process.cwd()
32
+ });
33
+
34
+ child.on('exit', (code) => {
35
+ process.exit(code || 0);
36
+ });
37
+
38
+ child.on('error', (error) => {
39
+ console.error('Error running command:', error.message);
40
+ process.exit(1);
41
+ });
42
+ }
43
+
44
+ // Parse command line arguments
45
+ const [,, command, ...args] = process.argv;
46
+
47
+ switch (command) {
48
+ case 'connect':
49
+ runCommand('connect', args);
50
+ break;
51
+
52
+ case 'help':
53
+ case '--help':
54
+ case '-h':
55
+ showHelp();
56
+ break;
57
+
58
+ default:
59
+ if (!command) {
60
+ console.log('Signal SDK - No command specified\n');
61
+ showHelp();
62
+ } else {
63
+ console.log(`Signal SDK - Unknown command: ${command}\n`);
64
+ showHelp();
65
+ process.exit(1);
66
+ }
67
+ break;
68
+ }
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Signal SDK - Device Connection Script
5
+ *
6
+ * This script allows you to link a new device to an existing Signal account
7
+ * by generating and displaying a QR code that can be scanned with your phone.
8
+ *
9
+ * Usage:
10
+ * node scripts/connect.js [device-name]
11
+ *
12
+ * Examples:
13
+ * node scripts/connect.js
14
+ * node scripts/connect.js "My Bot Device"
15
+ * npx signal-sdk connect
16
+ * npx signal-sdk connect "My Custom Device"
17
+ */
18
+
19
+ const { SignalCli } = require('../dist/SignalCli');
20
+
21
+ async function connectDevice() {
22
+ console.log('šŸ”— Signal SDK - Device Connection');
23
+ console.log('==================================\n');
24
+
25
+ // Get device name from command line arguments
26
+ const deviceName = process.argv[2] || 'Signal SDK Device';
27
+
28
+ console.log(`šŸ“± Device name: ${deviceName}`);
29
+ console.log('ā³ Generating QR code for device linking...\n');
30
+
31
+ // Initialize the SDK without an account (for linking)
32
+ const signalCli = new SignalCli();
33
+
34
+ try {
35
+ // Start device linking with QR code output to console
36
+ const linkingResult = await signalCli.deviceLink({
37
+ name: deviceName,
38
+ qrCodeOutput: 'console'
39
+ });
40
+
41
+ if (linkingResult.success) {
42
+ if (linkingResult.isLinked) {
43
+ console.log('āœ… Device successfully linked!');
44
+ console.log(`šŸ“± Device name: ${linkingResult.deviceName}`);
45
+ console.log('\nšŸŽ‰ You can now use this device to send and receive Signal messages.');
46
+ console.log('\nšŸ’” Next steps:');
47
+ console.log(' 1. Import SignalCli in your Node.js project');
48
+ console.log(' 2. Initialize with your phone number');
49
+ console.log(' 3. Start sending and receiving messages');
50
+ console.log('\nšŸ“– Example usage:');
51
+ console.log(' const { SignalCli } = require("signal-sdk");');
52
+ console.log(' const signalCli = new SignalCli(undefined, "+YourPhoneNumber");');
53
+ console.log(' await signalCli.connect();');
54
+ } else {
55
+ console.log('šŸ“‹ QR code generated successfully!');
56
+ console.log('šŸ“± Scan the QR code above with your Signal app to link this device.');
57
+ console.log('\nšŸ“ Instructions:');
58
+ console.log(' 1. Open Signal on your phone');
59
+ console.log(' 2. Go to Settings > Linked devices');
60
+ console.log(' 3. Tap "Link new device"');
61
+ console.log(' 4. Scan the QR code displayed above');
62
+ console.log('\nā³ Waiting for device linking...');
63
+ console.log(' (This process may take a few moments)');
64
+ }
65
+ } else {
66
+ console.error('āŒ Device linking failed');
67
+ if (linkingResult.error) {
68
+ console.error(` Error: ${linkingResult.error}`);
69
+ }
70
+ console.error('\nšŸ”§ Troubleshooting:');
71
+ console.error(' • Make sure signal-cli is properly installed');
72
+ console.error(' • Check your internet connection');
73
+ console.error(' • Ensure your Signal app is up to date');
74
+ console.error(' • Try running the command again');
75
+ process.exit(1);
76
+ }
77
+ } catch (error) {
78
+ console.error('āŒ Fatal error during device linking:', error.message);
79
+ console.error('\nšŸ”§ Common solutions:');
80
+ console.error(' • Install signal-cli: https://github.com/AsamK/signal-cli');
81
+ console.error(' • Make sure Java is installed and accessible');
82
+ console.error(' • Check that signal-cli is in your PATH');
83
+ console.error(' • Verify your internet connection');
84
+ process.exit(1);
85
+ }
86
+ }
87
+
88
+ // Handle graceful shutdown
89
+ process.on('SIGINT', () => {
90
+ console.log('\n\nā¹ļø Device linking cancelled by user.');
91
+ process.exit(0);
92
+ });
93
+
94
+ process.on('SIGTERM', () => {
95
+ console.log('\n\nā¹ļø Device linking terminated.');
96
+ process.exit(0);
97
+ });
98
+
99
+ // Display help if requested
100
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
101
+ console.log('Signal SDK - Device Connection Script');
102
+ console.log('=====================================\n');
103
+ console.log('Usage:');
104
+ console.log(' node scripts/connect.js [device-name]');
105
+ console.log(' npx signal-sdk connect [device-name]\n');
106
+ console.log('Arguments:');
107
+ console.log(' device-name Optional name for the linked device (default: "Signal SDK Device")\n');
108
+ console.log('Examples:');
109
+ console.log(' node scripts/connect.js');
110
+ console.log(' node scripts/connect.js "My Bot Device"');
111
+ console.log(' npx signal-sdk connect');
112
+ console.log(' npx signal-sdk connect "My Custom Device"\n');
113
+ console.log('This script generates a QR code that you can scan with your Signal app');
114
+ console.log('to link a new device for use with the Signal SDK.');
115
+ process.exit(0);
116
+ }
117
+
118
+ // Run the connection process
119
+ connectDevice();
@@ -0,0 +1,64 @@
1
+ const axios = require('axios');
2
+ const tar = require('tar');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const VERSION = '0.13.17';
7
+ const BASE_URL = `https://github.com/AsamK/signal-cli/releases/download/v${VERSION}`;
8
+
9
+ const platform = process.platform;
10
+
11
+ async function install() {
12
+ let url;
13
+ if (platform === 'linux') {
14
+ url = `${BASE_URL}/signal-cli-${VERSION}-Linux-native.tar.gz`;
15
+ } else {
16
+ url = `${BASE_URL}/signal-cli-${VERSION}.tar.gz`;
17
+ }
18
+
19
+ console.log(`Downloading signal-cli from ${url}`);
20
+
21
+ const response = await axios({
22
+ url,
23
+ method: 'GET',
24
+ responseType: 'stream'
25
+ });
26
+
27
+ const binDir = path.join(__dirname, '..', 'bin');
28
+ if (!fs.existsSync(binDir)) {
29
+ fs.mkdirSync(binDir, { recursive: true });
30
+ }
31
+
32
+ response.data.pipe(tar.x({ C: binDir, strip: 1 }));
33
+
34
+ console.log('signal-cli downloaded and extracted successfully.');
35
+
36
+ // Set executable permissions on Unix/Linux systems
37
+ if (platform !== 'win32') {
38
+ const signalCliExecutable = path.join(binDir, 'bin', 'signal-cli');
39
+ if (fs.existsSync(signalCliExecutable)) {
40
+ try {
41
+ fs.chmodSync(signalCliExecutable, '755');
42
+ console.log('Set executable permissions for signal-cli');
43
+ } catch (error) {
44
+ console.warn('Could not set executable permissions:', error.message);
45
+ }
46
+ }
47
+ }
48
+
49
+ if (platform === 'win32') {
50
+ console.log('Windows detected. Make sure you have Java installed and signal-cli.bat is executable.');
51
+ console.log('signal-cli.bat is located at: ' + path.join(binDir, 'bin', 'signal-cli.bat'));
52
+ } else if (platform === 'linux') {
53
+ console.log('Linux detected. signal-cli executable is ready.');
54
+ console.log('signal-cli is located at: ' + path.join(binDir, 'bin', 'signal-cli'));
55
+ } else {
56
+ console.log('Please ensure you have Java installed on your system for signal-cli to work.');
57
+ console.log('signal-cli is located at: ' + path.join(binDir, 'bin', 'signal-cli'));
58
+ }
59
+ }
60
+
61
+ install().catch(error => {
62
+ console.error('Failed to install signal-cli:', error);
63
+ process.exit(1);
64
+ });