@vielhuber/wahelper 1.5.7 → 1.5.9
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 +7 -0
- package/package.json +1 -1
- package/wahelper-daemon.js +50 -1
- package/wahelper.js +43 -3
package/README.md
CHANGED
|
@@ -55,6 +55,10 @@ npx wahelper \
|
|
|
55
55
|
--action "fetch_messages" \
|
|
56
56
|
--limit 42
|
|
57
57
|
|
|
58
|
+
# view a single message by id
|
|
59
|
+
--action "view_message" \
|
|
60
|
+
--id "ABCDEF1234567890"
|
|
61
|
+
|
|
58
62
|
# send message to user
|
|
59
63
|
--action "send_user" \
|
|
60
64
|
--number "xxxxxxxxxxxx" \
|
|
@@ -79,6 +83,9 @@ $wahelper = new wahelper();
|
|
|
79
83
|
// fetch messages
|
|
80
84
|
$wahelper->fetchMessages(device: 'xxxxxxxxxxxx', limit: 42);
|
|
81
85
|
|
|
86
|
+
// view a single message by id
|
|
87
|
+
$wahelper->viewMessage(device: 'xxxxxxxxxxxx', id: 'ABCDEF1234567890');
|
|
88
|
+
|
|
82
89
|
// send message to user
|
|
83
90
|
$wahelper->sendUser(
|
|
84
91
|
device: 'xxxxxxxxxxxx',
|
package/package.json
CHANGED
package/wahelper-daemon.js
CHANGED
|
@@ -129,9 +129,14 @@ export default class wahelperDaemon {
|
|
|
129
129
|
content TEXT,
|
|
130
130
|
media_data TEXT,
|
|
131
131
|
media_filename TEXT,
|
|
132
|
-
timestamp INTEGER
|
|
132
|
+
timestamp INTEGER,
|
|
133
|
+
\`read\` INTEGER NOT NULL DEFAULT 0
|
|
133
134
|
);
|
|
134
135
|
`);
|
|
136
|
+
let cols = this.db.prepare('PRAGMA table_info(messages)').all();
|
|
137
|
+
if (!cols.some(c => c.name === 'read')) {
|
|
138
|
+
this.db.exec('ALTER TABLE messages ADD COLUMN `read` INTEGER NOT NULL DEFAULT 0');
|
|
139
|
+
}
|
|
135
140
|
} catch (error) {
|
|
136
141
|
this.log('⛔ Error initing database: ' + error.message + ' (code: ' + error.code + ')');
|
|
137
142
|
}
|
|
@@ -394,6 +399,42 @@ export default class wahelperDaemon {
|
|
|
394
399
|
this.dbLock = false;
|
|
395
400
|
}
|
|
396
401
|
|
|
402
|
+
async markMessagesRead(updates) {
|
|
403
|
+
if (!Array.isArray(updates) || updates.length === 0) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
// WAMessageStatus.READ === 4
|
|
407
|
+
let ids = updates
|
|
408
|
+
.filter(u => u?.update?.status === 4)
|
|
409
|
+
.map(u => u?.key?.id)
|
|
410
|
+
.filter(id => typeof id === 'string' && id.length > 0);
|
|
411
|
+
if (ids.length === 0) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
while (this.dbLock) {
|
|
415
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
416
|
+
}
|
|
417
|
+
this.dbLock = true;
|
|
418
|
+
try {
|
|
419
|
+
if (this.dbIsOpen === false) {
|
|
420
|
+
this.initDatabase();
|
|
421
|
+
}
|
|
422
|
+
let stmt = this.db.prepare('UPDATE messages SET `read` = 1 WHERE id = ? AND `read` = 0');
|
|
423
|
+
let touched = 0;
|
|
424
|
+
for (let id of ids) {
|
|
425
|
+
let res = stmt.run(id);
|
|
426
|
+
if (res && res.changes > 0) touched++;
|
|
427
|
+
}
|
|
428
|
+
if (touched > 0) {
|
|
429
|
+
this.log('marked ' + touched + '/' + ids.length + ' messages as read');
|
|
430
|
+
}
|
|
431
|
+
} catch (error) {
|
|
432
|
+
this.log('⛔ markMessagesRead failed: ' + error.message);
|
|
433
|
+
} finally {
|
|
434
|
+
this.dbLock = false;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
397
438
|
async sendMessageToUser(number = null, message = null, attachments = null) {
|
|
398
439
|
if (!this.connected || !this.sock) {
|
|
399
440
|
throw new Error('not_connected');
|
|
@@ -502,6 +543,14 @@ export default class wahelperDaemon {
|
|
|
502
543
|
await this.storeDataToDatabase(obj);
|
|
503
544
|
});
|
|
504
545
|
|
|
546
|
+
this.sock.ev.on('messages.update', async updates => {
|
|
547
|
+
try {
|
|
548
|
+
await this.markMessagesRead(updates);
|
|
549
|
+
} catch (error) {
|
|
550
|
+
this.log('⛔ messages.update handler failed: ' + error.message);
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
505
554
|
this.sock.ev.on('creds.update', saveCreds);
|
|
506
555
|
|
|
507
556
|
this.sock.ev.on('connection.update', async update => {
|
package/wahelper.js
CHANGED
|
@@ -55,10 +55,11 @@ export default class wahelper {
|
|
|
55
55
|
this.args.device === undefined ||
|
|
56
56
|
(this.args.action === 'send_user' && (this.args.number === undefined || this.args.message === undefined)) ||
|
|
57
57
|
(this.args.action === 'send_group' && (this.args.name === undefined || this.args.message === undefined)) ||
|
|
58
|
+
(this.args.action === 'view_message' && (this.args.id === undefined || this.args.id === '')) ||
|
|
58
59
|
(this.args.action === 'fetch_messages' &&
|
|
59
60
|
this.args.limit !== undefined &&
|
|
60
61
|
typeof this.args.limit !== 'number') ||
|
|
61
|
-
!['fetch_messages', 'send_user', 'send_group'].includes(this.args.action)
|
|
62
|
+
!['fetch_messages', 'view_message', 'send_user', 'send_group'].includes(this.args.action)
|
|
62
63
|
) {
|
|
63
64
|
console.error('input missing or unknown action!');
|
|
64
65
|
this.log('⛔input missing or unknown action!');
|
|
@@ -106,6 +107,9 @@ export default class wahelper {
|
|
|
106
107
|
if (this.args.action === 'fetch_messages') {
|
|
107
108
|
response = await this.fetchMessages(this.args.limit);
|
|
108
109
|
}
|
|
110
|
+
if (this.args.action === 'view_message') {
|
|
111
|
+
response = await this.viewMessage(this.args.id);
|
|
112
|
+
}
|
|
109
113
|
if (this.args.action === 'send_user') {
|
|
110
114
|
response = await this.sendMessageToUser(this.args.number, this.args.message, this.args.attachments);
|
|
111
115
|
}
|
|
@@ -129,7 +133,7 @@ export default class wahelper {
|
|
|
129
133
|
let messages = this.db
|
|
130
134
|
.prepare(
|
|
131
135
|
`
|
|
132
|
-
SELECT id, \`from\`, \`to\`, content, media_filename, timestamp
|
|
136
|
+
SELECT id, \`from\`, \`to\`, content, media_filename, timestamp, \`read\`
|
|
133
137
|
FROM messages
|
|
134
138
|
ORDER BY timestamp DESC
|
|
135
139
|
${limit !== null ? 'LIMIT ' + limit : ''}
|
|
@@ -155,6 +159,37 @@ export default class wahelper {
|
|
|
155
159
|
return null;
|
|
156
160
|
}
|
|
157
161
|
|
|
162
|
+
async viewMessage(id = null) {
|
|
163
|
+
// lookup directly from database — no connection to daemon needed
|
|
164
|
+
try {
|
|
165
|
+
let message =
|
|
166
|
+
this.db
|
|
167
|
+
.prepare(
|
|
168
|
+
`
|
|
169
|
+
SELECT id, \`from\`, \`to\`, content, media_filename, timestamp, \`read\`
|
|
170
|
+
FROM messages
|
|
171
|
+
WHERE id = ?
|
|
172
|
+
LIMIT 1
|
|
173
|
+
`
|
|
174
|
+
)
|
|
175
|
+
.get(id) || null;
|
|
176
|
+
if (message === null) {
|
|
177
|
+
console.log('Message not found: ' + id);
|
|
178
|
+
this.write({ success: false, message: 'message_not_found', data: null }, true);
|
|
179
|
+
return { content: [{ type: 'text', text: 'Message not found: ' + id }], structuredContent: null };
|
|
180
|
+
}
|
|
181
|
+
console.log('Fetched message ' + id + ' from database.');
|
|
182
|
+
this.write({ success: true, message: 'message_fetched', data: message }, true);
|
|
183
|
+
return {
|
|
184
|
+
content: [{ type: 'text', text: 'Fetched message ' + id }],
|
|
185
|
+
structuredContent: message
|
|
186
|
+
};
|
|
187
|
+
} catch (error) {
|
|
188
|
+
this.log('⛔ Error fetching message from database: ' + error.message + ' (code: ' + error.code + ')');
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
158
193
|
async sendMessageToUser(number = null, message = null, attachments = null) {
|
|
159
194
|
let jid = this.formatNumber(number) + '@s.whatsapp.net';
|
|
160
195
|
this.log('begin send message to user ' + jid);
|
|
@@ -452,9 +487,14 @@ export default class wahelper {
|
|
|
452
487
|
content TEXT,
|
|
453
488
|
media_data TEXT,
|
|
454
489
|
media_filename TEXT,
|
|
455
|
-
timestamp INTEGER
|
|
490
|
+
timestamp INTEGER,
|
|
491
|
+
\`read\` INTEGER NOT NULL DEFAULT 0
|
|
456
492
|
);
|
|
457
493
|
`);
|
|
494
|
+
let cols = this.db.prepare('PRAGMA table_info(messages)').all();
|
|
495
|
+
if (!cols.some(c => c.name === 'read')) {
|
|
496
|
+
this.db.exec('ALTER TABLE messages ADD COLUMN `read` INTEGER NOT NULL DEFAULT 0');
|
|
497
|
+
}
|
|
458
498
|
} catch (error) {
|
|
459
499
|
this.log('⛔ Error initing database: ' + error.message + ' (code: ' + error.code + ')');
|
|
460
500
|
}
|