signal-sdk 0.1.2 → 0.1.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 +18 -8
- package/dist/MultiAccountManager.js +11 -19
- package/dist/SignalBot.js +40 -36
- package/dist/SignalCli.d.ts +23 -319
- package/dist/SignalCli.js +224 -998
- package/dist/__tests__/DeviceManager.test.d.ts +1 -0
- package/dist/__tests__/DeviceManager.test.js +135 -0
- package/dist/__tests__/MultiAccountManager.coverage.test.d.ts +1 -0
- package/dist/__tests__/MultiAccountManager.coverage.test.js +33 -0
- package/dist/__tests__/MultiAccountManager.test.js +3 -3
- package/dist/__tests__/SignalBot.additional.test.js +40 -37
- package/dist/__tests__/SignalBot.coverage.test.d.ts +1 -0
- package/dist/__tests__/SignalBot.coverage.test.js +385 -0
- package/dist/__tests__/SignalBot.test.js +8 -8
- package/dist/__tests__/SignalCli.advanced.test.js +47 -58
- package/dist/__tests__/SignalCli.connections.test.d.ts +1 -0
- package/dist/__tests__/SignalCli.connections.test.js +110 -0
- package/dist/__tests__/SignalCli.e2e.test.js +28 -32
- package/dist/__tests__/SignalCli.events.test.d.ts +1 -0
- package/dist/__tests__/SignalCli.events.test.js +113 -0
- package/dist/__tests__/SignalCli.integration.test.js +6 -5
- package/dist/__tests__/SignalCli.methods.test.js +77 -77
- package/dist/__tests__/SignalCli.parsing.test.js +4 -13
- package/dist/__tests__/SignalCli.simple.test.d.ts +1 -0
- package/dist/__tests__/SignalCli.simple.test.js +77 -0
- package/dist/__tests__/SignalCli.test.js +96 -82
- package/dist/__tests__/config.test.js +19 -29
- package/dist/__tests__/errors.test.js +2 -2
- package/dist/__tests__/retry.test.js +10 -8
- package/dist/__tests__/robustness.test.d.ts +1 -0
- package/dist/__tests__/robustness.test.js +59 -0
- package/dist/__tests__/security.test.d.ts +1 -0
- package/dist/__tests__/security.test.js +50 -0
- package/dist/config.js +3 -3
- package/dist/interfaces.d.ts +18 -0
- package/dist/managers/AccountManager.d.ts +27 -0
- package/dist/managers/AccountManager.js +147 -0
- package/dist/managers/BaseManager.d.ts +9 -0
- package/dist/managers/BaseManager.js +17 -0
- package/dist/managers/ContactManager.d.ts +15 -0
- package/dist/managers/ContactManager.js +123 -0
- package/dist/managers/DeviceManager.d.ts +11 -0
- package/dist/managers/DeviceManager.js +139 -0
- package/dist/managers/GroupManager.d.ts +12 -0
- package/dist/managers/GroupManager.js +78 -0
- package/dist/managers/MessageManager.d.ts +18 -0
- package/dist/managers/MessageManager.js +301 -0
- package/dist/managers/StickerManager.d.ts +8 -0
- package/dist/managers/StickerManager.js +39 -0
- package/dist/retry.js +3 -3
- package/dist/validators.d.ts +9 -0
- package/dist/validators.js +20 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
[](https://github.com/AsamK/signal-cli)
|
|
18
18
|
[](https://www.typescriptlang.org/)
|
|
19
19
|
[](https://nodejs.org/)
|
|
20
|
-
[](./src/__tests__)
|
|
21
21
|
[](https://liberapay.com/devbyben/donate)
|
|
22
22
|
|
|
23
23
|
</div>
|
|
@@ -70,7 +70,8 @@
|
|
|
70
70
|
- **Progress Tracking** - Monitor upload progress
|
|
71
71
|
- **Polls** - Create, vote, and terminate polls
|
|
72
72
|
- **Attachment Retrieval** - Retrieve attachments, avatars, and stickers
|
|
73
|
-
- **Account Management** - Update account settings
|
|
73
|
+
- **Account Management** - Update account settings, PIN, and registration
|
|
74
|
+
- **Note to Self** - Send private notes to your own account
|
|
74
75
|
- **Stories** - View and interact with Signal stories
|
|
75
76
|
- **Group Information** - Retrieve detailed group permissions
|
|
76
77
|
|
|
@@ -213,7 +214,7 @@ bot.on("ready", () => {
|
|
|
213
214
|
});
|
|
214
215
|
|
|
215
216
|
bot.on("message", (message) => {
|
|
216
|
-
console.log(`Received: ${message.text} from ${message.
|
|
217
|
+
console.log(`Received: ${message.text} from ${message.source}`);
|
|
217
218
|
});
|
|
218
219
|
|
|
219
220
|
// Start the bot
|
|
@@ -362,8 +363,8 @@ await bot.start();
|
|
|
362
363
|
|
|
363
364
|
- **Node.js**: >=18.0.0
|
|
364
365
|
- **TypeScript**: 5.8+ with strict mode
|
|
365
|
-
- **Test Coverage**:
|
|
366
|
-
- **Code Coverage**:
|
|
366
|
+
- **Test Coverage**: 393 passing tests across 21 suites
|
|
367
|
+
- **Code Coverage**: 83.54% overall, critical modules at 96-100%
|
|
367
368
|
- **signal-cli**: Compatible with v0.13.23
|
|
368
369
|
|
|
369
370
|
## Testing
|
|
@@ -372,9 +373,9 @@ The SDK has comprehensive test coverage to ensure reliability and quality.
|
|
|
372
373
|
|
|
373
374
|
### Test Statistics
|
|
374
375
|
|
|
375
|
-
- **Total Tests**:
|
|
376
|
-
- **Test Suites**:
|
|
377
|
-
- **Overall Coverage**:
|
|
376
|
+
- **Total Tests**: 393 passing
|
|
377
|
+
- **Test Suites**: 21 suites
|
|
378
|
+
- **Overall Coverage**: 83.54%
|
|
378
379
|
|
|
379
380
|
### Coverage by Module
|
|
380
381
|
|
|
@@ -607,6 +608,15 @@ Compatible with signal-cli v0.13.23 - **100% Feature Coverage**
|
|
|
607
608
|
| | `startChangeNumber` | Start phone number change | ✅ |
|
|
608
609
|
| | `finishChangeNumber` | Complete phone number change | ✅ |
|
|
609
610
|
| | `sendMessageWithProgress` | Enhanced messaging with progress | ✅ |
|
|
611
|
+
| | `sendNoteToSelf` | Send message to own conversation | ✅ |
|
|
612
|
+
| | `unregister` | Unregister account from server | ✅ |
|
|
613
|
+
| **Identities** | `listIdentities` | List known identities | ✅ |
|
|
614
|
+
| | `trustIdentity` | Mark identity as trusted | ✅ |
|
|
615
|
+
| | `getSafetyNumber` | Get safety number for contact | ✅ |
|
|
616
|
+
| | `verifySafetyNumber` | Verify and trust safety number | ✅ |
|
|
617
|
+
| **Multi-Account**| `addAccount` | Add account to manager | ✅ |
|
|
618
|
+
| | `connectAll` | Connect all managed accounts | ✅ |
|
|
619
|
+
| | `getStatus` | Get status for all accounts | ✅ |
|
|
610
620
|
|
|
611
621
|
[Complete API documentation](./docs/api-reference.md)
|
|
612
622
|
|
|
@@ -45,7 +45,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
45
45
|
this.options = options;
|
|
46
46
|
this.logger = new config_1.Logger({
|
|
47
47
|
level: options.verbose ? 'debug' : 'info',
|
|
48
|
-
enableFile: false
|
|
48
|
+
enableFile: false,
|
|
49
49
|
});
|
|
50
50
|
this.logger.info('MultiAccountManager initialized');
|
|
51
51
|
}
|
|
@@ -65,7 +65,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
65
65
|
const signalConfig = {
|
|
66
66
|
signalCliPath: this.options.signalCliPath,
|
|
67
67
|
verbose: this.options.verbose,
|
|
68
|
-
...config
|
|
68
|
+
...config,
|
|
69
69
|
};
|
|
70
70
|
const instance = new SignalCli_1.SignalCli(account, undefined, signalConfig);
|
|
71
71
|
// Forward events from this instance
|
|
@@ -75,7 +75,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
75
75
|
account,
|
|
76
76
|
instance,
|
|
77
77
|
connected: false,
|
|
78
|
-
lastActivity: Date.now()
|
|
78
|
+
lastActivity: Date.now(),
|
|
79
79
|
};
|
|
80
80
|
this.accounts.set(account, managedAccount);
|
|
81
81
|
this.emit('accountAdded', account);
|
|
@@ -186,7 +186,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
186
186
|
*/
|
|
187
187
|
async connectAll() {
|
|
188
188
|
this.logger.info('Connecting all accounts');
|
|
189
|
-
const promises = Array.from(this.accounts.keys()).map(account => this.connect(account).catch(error => {
|
|
189
|
+
const promises = Array.from(this.accounts.keys()).map((account) => this.connect(account).catch((error) => {
|
|
190
190
|
this.logger.error(`Failed to connect ${account}:`, error);
|
|
191
191
|
}));
|
|
192
192
|
await Promise.all(promises);
|
|
@@ -197,7 +197,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
197
197
|
*/
|
|
198
198
|
async disconnectAll() {
|
|
199
199
|
this.logger.info('Disconnecting all accounts');
|
|
200
|
-
const promises = Array.from(this.accounts.keys()).map(account => this.disconnect(account).catch(error => {
|
|
200
|
+
const promises = Array.from(this.accounts.keys()).map((account) => this.disconnect(account).catch((error) => {
|
|
201
201
|
this.logger.error(`Failed to disconnect ${account}:`, error);
|
|
202
202
|
}));
|
|
203
203
|
await Promise.all(promises);
|
|
@@ -235,14 +235,14 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
235
235
|
account: managedAccount.account,
|
|
236
236
|
connected: managedAccount.connected,
|
|
237
237
|
lastActivity: managedAccount.lastActivity,
|
|
238
|
-
uptime: Date.now() - managedAccount.lastActivity
|
|
238
|
+
uptime: Date.now() - managedAccount.lastActivity,
|
|
239
239
|
};
|
|
240
240
|
}
|
|
241
241
|
// Return status for all accounts
|
|
242
242
|
const status = {
|
|
243
243
|
totalAccounts: this.accounts.size,
|
|
244
244
|
connectedAccounts: 0,
|
|
245
|
-
accounts: []
|
|
245
|
+
accounts: [],
|
|
246
246
|
};
|
|
247
247
|
for (const [account, managed] of this.accounts) {
|
|
248
248
|
if (managed.connected) {
|
|
@@ -252,7 +252,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
252
252
|
account,
|
|
253
253
|
connected: managed.connected,
|
|
254
254
|
lastActivity: managed.lastActivity,
|
|
255
|
-
uptime: Date.now() - managed.lastActivity
|
|
255
|
+
uptime: Date.now() - managed.lastActivity,
|
|
256
256
|
});
|
|
257
257
|
}
|
|
258
258
|
return status;
|
|
@@ -264,16 +264,8 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
264
264
|
*/
|
|
265
265
|
setupEventForwarding(account, instance) {
|
|
266
266
|
// Forward all events with account prefix
|
|
267
|
-
const events = [
|
|
268
|
-
|
|
269
|
-
'receipt',
|
|
270
|
-
'typing',
|
|
271
|
-
'reaction',
|
|
272
|
-
'error',
|
|
273
|
-
'connected',
|
|
274
|
-
'disconnected'
|
|
275
|
-
];
|
|
276
|
-
events.forEach(event => {
|
|
267
|
+
const events = ['message', 'receipt', 'typing', 'reaction', 'error', 'connected', 'disconnected'];
|
|
268
|
+
events.forEach((event) => {
|
|
277
269
|
instance.on(event, (...args) => {
|
|
278
270
|
// Emit with account information
|
|
279
271
|
this.emit(event, account, ...args);
|
|
@@ -281,7 +273,7 @@ class MultiAccountManager extends events_1.EventEmitter {
|
|
|
281
273
|
this.emit('accountEvent', {
|
|
282
274
|
account,
|
|
283
275
|
event,
|
|
284
|
-
data: args
|
|
276
|
+
data: args,
|
|
285
277
|
});
|
|
286
278
|
// Update last activity
|
|
287
279
|
const managedAccount = this.accounts.get(account);
|
package/dist/SignalBot.js
CHANGED
|
@@ -78,7 +78,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
78
78
|
commandsExecuted: 0,
|
|
79
79
|
startTime: Date.now(),
|
|
80
80
|
lastActivity: Date.now(),
|
|
81
|
-
activeUsers: 0
|
|
81
|
+
activeUsers: 0,
|
|
82
82
|
};
|
|
83
83
|
this.setupDefaultCommands();
|
|
84
84
|
}
|
|
@@ -93,7 +93,8 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
93
93
|
const tempFilePath = path.join(process.cwd(), tempFileName);
|
|
94
94
|
const file = fs.createWriteStream(tempFilePath);
|
|
95
95
|
const client = imageUrl.startsWith('https:') ? https : http;
|
|
96
|
-
client
|
|
96
|
+
client
|
|
97
|
+
.get(imageUrl, (response) => {
|
|
97
98
|
if (response.statusCode !== 200) {
|
|
98
99
|
fs.unlink(tempFilePath, () => { }); // Clean up on error
|
|
99
100
|
reject(new Error(`Failed to download image: ${response.statusCode}`));
|
|
@@ -108,7 +109,8 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
108
109
|
fs.unlink(tempFilePath, () => { }); // Clean up on error
|
|
109
110
|
reject(err);
|
|
110
111
|
});
|
|
111
|
-
})
|
|
112
|
+
})
|
|
113
|
+
.on('error', (err) => {
|
|
112
114
|
fs.unlink(tempFilePath, () => { }); // Clean up on error
|
|
113
115
|
reject(err);
|
|
114
116
|
});
|
|
@@ -124,7 +126,8 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
124
126
|
return new Promise((resolve, reject) => {
|
|
125
127
|
const downloadWithRedirect = (url, maxRedirects = 5) => {
|
|
126
128
|
const client = url.startsWith('https:') ? https : http;
|
|
127
|
-
client
|
|
129
|
+
client
|
|
130
|
+
.get(url, (response) => {
|
|
128
131
|
// Handle redirections (3xx status codes)
|
|
129
132
|
if (response.statusCode && response.statusCode >= 300 && response.statusCode < 400) {
|
|
130
133
|
if (maxRedirects <= 0) {
|
|
@@ -137,7 +140,9 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
137
140
|
return;
|
|
138
141
|
}
|
|
139
142
|
// Resolve relative URLs
|
|
140
|
-
const finalUrl = redirectUrl.startsWith('http')
|
|
143
|
+
const finalUrl = redirectUrl.startsWith('http')
|
|
144
|
+
? redirectUrl
|
|
145
|
+
: new URL(redirectUrl, url).href;
|
|
141
146
|
this.log(`🔄 Following redirect to: ${finalUrl}`, 'DEBUG');
|
|
142
147
|
downloadWithRedirect(finalUrl, maxRedirects - 1);
|
|
143
148
|
return;
|
|
@@ -162,7 +167,8 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
162
167
|
fs.unlink(tempFilePath, () => { }); // Clean up on error
|
|
163
168
|
reject(err);
|
|
164
169
|
});
|
|
165
|
-
})
|
|
170
|
+
})
|
|
171
|
+
.on('error', (err) => {
|
|
166
172
|
reject(err);
|
|
167
173
|
});
|
|
168
174
|
};
|
|
@@ -189,7 +195,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
189
195
|
recipient,
|
|
190
196
|
message,
|
|
191
197
|
attachments: [tempFilePath],
|
|
192
|
-
cleanup: [tempFilePath] // Mark files for cleanup after sending
|
|
198
|
+
cleanup: [tempFilePath], // Mark files for cleanup after sending
|
|
193
199
|
});
|
|
194
200
|
this.processActionQueue();
|
|
195
201
|
}
|
|
@@ -319,7 +325,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
319
325
|
this.log('- Stopping Signal Bot...');
|
|
320
326
|
this.isRunning = false;
|
|
321
327
|
// Clear all active timers
|
|
322
|
-
this.activeTimers.forEach(timer => clearTimeout(timer));
|
|
328
|
+
this.activeTimers.forEach((timer) => clearTimeout(timer));
|
|
323
329
|
this.activeTimers = [];
|
|
324
330
|
this.signalCli.disconnect();
|
|
325
331
|
this.emit('stopped');
|
|
@@ -329,7 +335,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
329
335
|
this.log('- Gracefully shutting down Signal Bot...');
|
|
330
336
|
this.isRunning = false;
|
|
331
337
|
// Clear all active timers
|
|
332
|
-
this.activeTimers.forEach(timer => clearTimeout(timer));
|
|
338
|
+
this.activeTimers.forEach((timer) => clearTimeout(timer));
|
|
333
339
|
this.activeTimers = [];
|
|
334
340
|
try {
|
|
335
341
|
await this.signalCli.gracefulShutdown();
|
|
@@ -376,7 +382,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
376
382
|
getStats() {
|
|
377
383
|
return {
|
|
378
384
|
...this.stats,
|
|
379
|
-
activeUsers: this.userCooldowns.size
|
|
385
|
+
activeUsers: this.userCooldowns.size,
|
|
380
386
|
};
|
|
381
387
|
}
|
|
382
388
|
/**
|
|
@@ -404,11 +410,11 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
404
410
|
description: 'Displays available commands',
|
|
405
411
|
handler: async (message, args) => {
|
|
406
412
|
const userCommands = Array.from(this.commands.values())
|
|
407
|
-
.filter(cmd => !cmd.adminOnly || message.isFromAdmin)
|
|
408
|
-
.map(cmd => `${this.config.settings.commandPrefix}${cmd.name} - ${cmd.description}`)
|
|
413
|
+
.filter((cmd) => !cmd.adminOnly || message.isFromAdmin)
|
|
414
|
+
.map((cmd) => `${this.config.settings.commandPrefix}${cmd.name} - ${cmd.description}`)
|
|
409
415
|
.join('\n');
|
|
410
416
|
return `Signal Bot Commands\n\n${userCommands}\n\n${message.isFromAdmin ? '| You have admin privileges' : ''}`;
|
|
411
|
-
}
|
|
417
|
+
},
|
|
412
418
|
});
|
|
413
419
|
// Stats command
|
|
414
420
|
this.addCommand({
|
|
@@ -417,12 +423,12 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
417
423
|
handler: async () => {
|
|
418
424
|
const stats = this.getStats();
|
|
419
425
|
const uptime = this.formatUptime(Date.now() - stats.startTime);
|
|
420
|
-
return `Bot Statistics\n\n` +
|
|
426
|
+
return (`Bot Statistics\n\n` +
|
|
421
427
|
`1. Messages Received: ${stats.messagesReceived}\n` +
|
|
422
428
|
`2. Commands Executed: ${stats.commandsExecuted}\n` +
|
|
423
429
|
`3. Uptime: ${uptime}\n` +
|
|
424
|
-
`4. Active Users: ${stats.activeUsers}
|
|
425
|
-
}
|
|
430
|
+
`4. Active Users: ${stats.activeUsers}`);
|
|
431
|
+
},
|
|
426
432
|
});
|
|
427
433
|
// Ping command
|
|
428
434
|
this.addCommand({
|
|
@@ -431,7 +437,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
431
437
|
handler: async (message) => {
|
|
432
438
|
const responseTime = Date.now() - message.timestamp;
|
|
433
439
|
return `Pong! Response time: ${responseTime}ms`;
|
|
434
|
-
}
|
|
440
|
+
},
|
|
435
441
|
});
|
|
436
442
|
// Info command (admin only)
|
|
437
443
|
this.addCommand({
|
|
@@ -439,13 +445,13 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
439
445
|
description: 'Detailed bot information (admin)',
|
|
440
446
|
adminOnly: true,
|
|
441
447
|
handler: async () => {
|
|
442
|
-
return `Bot Information\n\n` +
|
|
448
|
+
return (`Bot Information\n\n` +
|
|
443
449
|
`- Number: ${this.config.phoneNumber}\n` +
|
|
444
450
|
`- Group: ${this.config.group ? this.config.group.name : 'N/A'}\n` +
|
|
445
451
|
`- Admins: ${this.config.admins.length}\n` +
|
|
446
452
|
`- Commands: ${this.commands.size}\n` +
|
|
447
|
-
`- Prefix: ${this.config.settings.commandPrefix}
|
|
448
|
-
}
|
|
453
|
+
`- Prefix: ${this.config.settings.commandPrefix}`);
|
|
454
|
+
},
|
|
449
455
|
});
|
|
450
456
|
}
|
|
451
457
|
async setupBotGroup() {
|
|
@@ -462,7 +468,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
462
468
|
}
|
|
463
469
|
// Search for an existing group
|
|
464
470
|
const groups = await this.signalCli.listGroups();
|
|
465
|
-
const existingGroup = groups.find(group => group.name === this.config.group.name && group.isMember);
|
|
471
|
+
const existingGroup = groups.find((group) => group.name === this.config.group.name && group.isMember);
|
|
466
472
|
if (existingGroup) {
|
|
467
473
|
// Try different possible field names for the group ID
|
|
468
474
|
const groupData = existingGroup;
|
|
@@ -471,7 +477,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
471
477
|
this.log(`- Existing group found: ${this.config.group.name} (${possibleGroupId})`);
|
|
472
478
|
// Check if all admins are in the group and add them if not
|
|
473
479
|
const currentMembers = existingGroup.members?.map((m) => m.number || m) || [];
|
|
474
|
-
const missingAdmins = this.config.admins.filter(admin => !currentMembers.includes(admin));
|
|
480
|
+
const missingAdmins = this.config.admins.filter((admin) => !currentMembers.includes(admin));
|
|
475
481
|
// Prepare update options
|
|
476
482
|
const updateOptions = {};
|
|
477
483
|
if (missingAdmins.length > 0) {
|
|
@@ -517,10 +523,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
517
523
|
}
|
|
518
524
|
// Create a new group only if none exists
|
|
519
525
|
this.log(`- Creating group: ${this.config.group.name}`);
|
|
520
|
-
const initialMembers = [
|
|
521
|
-
...this.config.admins,
|
|
522
|
-
...(this.config.group.initialMembers || [])
|
|
523
|
-
].filter((member, index, array) => array.indexOf(member) === index);
|
|
526
|
+
const initialMembers = [...this.config.admins, ...(this.config.group.initialMembers || [])].filter((member, index, array) => array.indexOf(member) === index);
|
|
524
527
|
try {
|
|
525
528
|
const newGroup = await this.signalCli.createGroup(this.config.group.name, initialMembers);
|
|
526
529
|
const newGroupData = newGroup;
|
|
@@ -531,7 +534,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
531
534
|
const configOptions = {
|
|
532
535
|
description: this.config.group.description,
|
|
533
536
|
permissionAddMember: 'ONLY_ADMINS',
|
|
534
|
-
permissionEditDetails: 'ONLY_ADMINS'
|
|
537
|
+
permissionEditDetails: 'ONLY_ADMINS',
|
|
535
538
|
};
|
|
536
539
|
if (avatarPath) {
|
|
537
540
|
configOptions.avatar = avatarPath;
|
|
@@ -556,7 +559,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
556
559
|
this.log(` 2. Add the bot number (${this.config.phoneNumber}) to the group`, 'INFO');
|
|
557
560
|
this.log(` 3. Add all admins to the group: ${this.config.admins.join(', ')}`, 'INFO');
|
|
558
561
|
this.log(` 4. Restart the bot`, 'INFO');
|
|
559
|
-
this.log(` Available groups: ${groups.map(g => g.name).join(', ')}`, 'INFO');
|
|
562
|
+
this.log(` Available groups: ${groups.map((g) => g.name).join(', ')}`, 'INFO');
|
|
560
563
|
// Don't use a fallback group - this is misleading behavior
|
|
561
564
|
throw new Error(`Group "${this.config.group.name}" does not exist and cannot be created automatically. Please create it manually as described above.`);
|
|
562
565
|
}
|
|
@@ -617,7 +620,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
617
620
|
text: messageData.envelope.dataMessage.message || '',
|
|
618
621
|
timestamp: messageData.envelope.timestamp,
|
|
619
622
|
groupInfo: messageData.envelope.dataMessage.groupInfo,
|
|
620
|
-
isFromAdmin: this.isAdmin(messageData.envelope.sourceNumber || messageData.envelope.source)
|
|
623
|
+
isFromAdmin: this.isAdmin(messageData.envelope.sourceNumber || messageData.envelope.source),
|
|
621
624
|
};
|
|
622
625
|
// Ignore own messages
|
|
623
626
|
if (parsedMessage.source === this.config.phoneNumber) {
|
|
@@ -697,8 +700,9 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
697
700
|
}
|
|
698
701
|
}
|
|
699
702
|
async sendCommandResponse(message, response) {
|
|
700
|
-
const recipient = message.groupInfo
|
|
701
|
-
|
|
703
|
+
const recipient = message.groupInfo
|
|
704
|
+
? message.groupInfo.id || message.groupInfo.groupId || message.source
|
|
705
|
+
: message.source;
|
|
702
706
|
await this.sendMessage(recipient, response);
|
|
703
707
|
}
|
|
704
708
|
isOnCooldown(userId) {
|
|
@@ -707,7 +711,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
707
711
|
return false;
|
|
708
712
|
const now = Date.now();
|
|
709
713
|
const cooldownMs = (this.config.settings.cooldownSeconds || 2) * 1000;
|
|
710
|
-
return
|
|
714
|
+
return now - lastCommand < cooldownMs;
|
|
711
715
|
}
|
|
712
716
|
async processActionQueue() {
|
|
713
717
|
if (this.isProcessingQueue || this.actionQueue.length === 0) {
|
|
@@ -727,13 +731,13 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
727
731
|
case 'sendMessageWithAttachment':
|
|
728
732
|
this.log(`Executing sendMessageWithAttachment to ${action.recipient} with ${action.attachments.length} file(s)...`, 'DEBUG');
|
|
729
733
|
await this.signalCli.sendMessage(action.recipient, action.message, {
|
|
730
|
-
attachments: action.attachments
|
|
734
|
+
attachments: action.attachments,
|
|
731
735
|
});
|
|
732
736
|
// Wait a bit for signal-cli to finish processing the files before cleanup
|
|
733
737
|
// signal-cli responds immediately but continues processing files in background
|
|
734
738
|
if (action.cleanup && action.cleanup.length > 0) {
|
|
735
739
|
const cleanupTimer = setTimeout(() => {
|
|
736
|
-
action.cleanup.forEach(filePath => {
|
|
740
|
+
action.cleanup.forEach((filePath) => {
|
|
737
741
|
this.cleanupTempFile(filePath);
|
|
738
742
|
});
|
|
739
743
|
// Remove timer from active list
|
|
@@ -752,7 +756,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
752
756
|
break;
|
|
753
757
|
}
|
|
754
758
|
// Wait a bit between actions to be safe
|
|
755
|
-
await new Promise(resolve => {
|
|
759
|
+
await new Promise((resolve) => {
|
|
756
760
|
const timer = setTimeout(resolve, 250);
|
|
757
761
|
if (timer.unref)
|
|
758
762
|
timer.unref();
|
|
@@ -762,7 +766,7 @@ class SignalBot extends events_1.EventEmitter {
|
|
|
762
766
|
this.log(`ERROR: Failed to execute action ${action.type}: ${error?.message || error}`, 'ERROR');
|
|
763
767
|
// Clean up temporary files even on error
|
|
764
768
|
if (action.type === 'sendMessageWithAttachment' && action.cleanup && action.cleanup.length > 0) {
|
|
765
|
-
action.cleanup.forEach(filePath => {
|
|
769
|
+
action.cleanup.forEach((filePath) => {
|
|
766
770
|
this.cleanupTempFile(filePath);
|
|
767
771
|
});
|
|
768
772
|
}
|