whatsapp-pi 1.0.24 → 1.0.25
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/package.json +1 -1
- package/src/services/whatsapp.service.ts +38 -0
- package/src/ui/menu.handler.ts +4 -4
- package/whatsapp-pi.ts +41 -1
package/package.json
CHANGED
|
@@ -242,6 +242,44 @@ export class WhatsAppService {
|
|
|
242
242
|
return result;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
private normalizeRecipientJid(jid: string): string {
|
|
246
|
+
if (jid.includes('@')) return jid;
|
|
247
|
+
const digits = jid.startsWith('+') ? jid.slice(1) : jid;
|
|
248
|
+
return `${digits}@s.whatsapp.net`;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async sendMenuMessage(jid: string, text: string) {
|
|
252
|
+
const normalizedJid = this.normalizeRecipientJid(jid);
|
|
253
|
+
|
|
254
|
+
if (!this.socket || this.getStatus() !== 'connected') {
|
|
255
|
+
return {
|
|
256
|
+
success: false,
|
|
257
|
+
error: 'WhatsApp is not connected',
|
|
258
|
+
attempts: 0
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
await this.sendPresence(normalizedJid, 'composing');
|
|
264
|
+
const response = await this.socket.sendMessage(normalizedJid, { text });
|
|
265
|
+
await this.sendPresence(normalizedJid, 'paused');
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
success: true,
|
|
269
|
+
messageId: response?.key?.id,
|
|
270
|
+
attempts: 1
|
|
271
|
+
};
|
|
272
|
+
} catch (error: any) {
|
|
273
|
+
await this.sendPresence(normalizedJid, 'paused');
|
|
274
|
+
console.error(`Failed to send menu message to ${normalizedJid}:`, error);
|
|
275
|
+
return {
|
|
276
|
+
success: false,
|
|
277
|
+
error: error?.message || 'Unknown error',
|
|
278
|
+
attempts: 1
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
245
283
|
async sendPresence(jid: string, presence: 'composing' | 'recording' | 'paused') {
|
|
246
284
|
if (!this.socket || this.getStatus() !== 'connected') return;
|
|
247
285
|
try {
|
package/src/ui/menu.handler.ts
CHANGED
|
@@ -311,7 +311,7 @@ export class MenuHandler {
|
|
|
311
311
|
continue;
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
const result = await this.whatsappService.
|
|
314
|
+
const result = await this.whatsappService.sendMenuMessage(this.toJid(conversation.senderNumber), trimmed);
|
|
315
315
|
if (result.success) {
|
|
316
316
|
await this.recentsService.recordMessage({
|
|
317
317
|
messageId: result.messageId ?? `${Date.now()}`,
|
|
@@ -323,7 +323,7 @@ export class MenuHandler {
|
|
|
323
323
|
});
|
|
324
324
|
ctx.ui.notify(`Sent message to ${displayName}`, 'info');
|
|
325
325
|
} else {
|
|
326
|
-
ctx.ui.notify(`Failed to send message to ${displayName}`, 'error');
|
|
326
|
+
ctx.ui.notify(`Failed to send message to ${displayName}: ${result.error ?? 'Unknown error'}`, 'error');
|
|
327
327
|
}
|
|
328
328
|
return;
|
|
329
329
|
}
|
|
@@ -340,7 +340,7 @@ export class MenuHandler {
|
|
|
340
340
|
continue;
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
const result = await this.whatsappService.
|
|
343
|
+
const result = await this.whatsappService.sendMenuMessage(this.toJid(contact.number), trimmed);
|
|
344
344
|
if (result.success) {
|
|
345
345
|
await this.recentsService.recordMessage({
|
|
346
346
|
messageId: result.messageId ?? `${Date.now()}`,
|
|
@@ -352,7 +352,7 @@ export class MenuHandler {
|
|
|
352
352
|
});
|
|
353
353
|
ctx.ui.notify(`Sent message to ${displayName}`, 'info');
|
|
354
354
|
} else {
|
|
355
|
-
ctx.ui.notify(`Failed to send message to ${displayName}`, 'error');
|
|
355
|
+
ctx.ui.notify(`Failed to send message to ${displayName}: ${result.error ?? 'Unknown error'}`, 'error');
|
|
356
356
|
}
|
|
357
357
|
return;
|
|
358
358
|
}
|
package/whatsapp-pi.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
2
3
|
import { extractMessageContent } from '@whiskeysockets/baileys';
|
|
3
4
|
import { SessionManager } from './src/services/session.manager.js';
|
|
4
5
|
import { WhatsAppService } from './src/services/whatsapp.service.js';
|
|
@@ -99,7 +100,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
99
100
|
.find(entry => entry.type === "custom" && entry.customType === "whatsapp-state");
|
|
100
101
|
|
|
101
102
|
if (savedStateEntry) {
|
|
102
|
-
const data = savedStateEntry
|
|
103
|
+
const data = (savedStateEntry as { data?: any }).data;
|
|
103
104
|
if (data.status) await sessionManager.setStatus(data.status);
|
|
104
105
|
if (Array.isArray(data.allowList)) {
|
|
105
106
|
for (const n of data.allowList) {
|
|
@@ -428,6 +429,45 @@ export default function (pi: ExtensionAPI) {
|
|
|
428
429
|
|
|
429
430
|
});
|
|
430
431
|
|
|
432
|
+
// Register send_wa_message tool (LLM-callable)
|
|
433
|
+
pi.registerTool({
|
|
434
|
+
name: "send_wa_message",
|
|
435
|
+
label: "Send WhatsApp Message",
|
|
436
|
+
description: "Send a WhatsApp message to a contact identified by their JID (e.g. 5511999998888@s.whatsapp.net). Returns a JSON result with success status and messageId or error.",
|
|
437
|
+
promptSnippet: "send_wa_message(jid, message) - Send a WhatsApp message to a contact by JID",
|
|
438
|
+
parameters: Type.Object({
|
|
439
|
+
jid: Type.String({ minLength: 1, description: "WhatsApp JID of the recipient, e.g. 5511999998888@s.whatsapp.net" }),
|
|
440
|
+
message: Type.String({ minLength: 1, description: "Plain-text message content to send" })
|
|
441
|
+
}),
|
|
442
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
443
|
+
if (whatsappService.getStatus() !== 'connected') {
|
|
444
|
+
return {
|
|
445
|
+
isError: true,
|
|
446
|
+
details: undefined,
|
|
447
|
+
content: [{ type: "text" as const, text: JSON.stringify({ success: false, error: "WhatsApp not connected", attempts: 0 }) }]
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const result = await whatsappService.sendMessage(params.jid, params.message);
|
|
452
|
+
|
|
453
|
+
if (result.success) {
|
|
454
|
+
await recentsService.recordMessage({
|
|
455
|
+
messageId: result.messageId!,
|
|
456
|
+
senderNumber: `+${params.jid.split('@')[0]}`,
|
|
457
|
+
text: params.message,
|
|
458
|
+
direction: 'outgoing',
|
|
459
|
+
timestamp: Date.now()
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return {
|
|
464
|
+
isError: !result.success,
|
|
465
|
+
details: undefined,
|
|
466
|
+
content: [{ type: "text" as const, text: JSON.stringify({ success: result.success, messageId: result.messageId, error: result.error, attempts: result.attempts }) }]
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
|
|
431
471
|
// Register commands
|
|
432
472
|
pi.registerCommand("whatsapp", {
|
|
433
473
|
description: "Manage WhatsApp integration",
|