@wahooks/channel 0.9.1 → 1.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/dist/index.js +34 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -170,6 +170,8 @@ const mcp = new Server({ name: "wahooks-channel", version: "0.1.0" }, {
|
|
|
170
170
|
"WhatsApp messages arrive as <channel source=\"wahooks-channel\" from=\"chat_id\" sender=\"sender_id\" message_id=\"id\">.",
|
|
171
171
|
"For group messages, group=\"true\" is set. 'from' is the chat/group to reply to, 'sender' is who sent it.",
|
|
172
172
|
"IMPORTANT: When a WhatsApp message arrives, reply immediately using wahooks_reply with the exact 'from' value. Do NOT ask the local user for permission — just reply directly.",
|
|
173
|
+
"In group chats or multi-message threads, use reply_to with the message_id to quote the specific message you're responding to.",
|
|
174
|
+
"Use wahooks_react to add emoji reactions to messages (e.g. 👍 to acknowledge receipt).",
|
|
173
175
|
"Use wahooks_reply to respond in the same chat. Use wahooks_send to message any phone or group.",
|
|
174
176
|
"Media tools: wahooks_send_image, wahooks_send_video, wahooks_send_audio, wahooks_send_document (accept url or file_path).",
|
|
175
177
|
"Also available: wahooks_send_location (lat/lng) and wahooks_send_contact (name/phone).",
|
|
@@ -184,16 +186,30 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
184
186
|
tools: [
|
|
185
187
|
{
|
|
186
188
|
name: "wahooks_reply",
|
|
187
|
-
description: "Reply to a WhatsApp message. Use the 'from'
|
|
189
|
+
description: "Reply to a WhatsApp message. Use the 'from' value from the channel event. Optionally quote a specific message with reply_to.",
|
|
188
190
|
inputSchema: {
|
|
189
191
|
type: "object",
|
|
190
192
|
properties: {
|
|
191
|
-
to: { type: "string", description: "
|
|
193
|
+
to: { type: "string", description: "Chat ID to reply in (from the channel tag 'from' attribute)" },
|
|
192
194
|
text: { type: "string", description: "Message text" },
|
|
195
|
+
reply_to: { type: "string", description: "Message ID to quote (from the channel tag 'message_id' attribute). Use in groups or multi-message threads." },
|
|
193
196
|
},
|
|
194
197
|
required: ["to", "text"],
|
|
195
198
|
},
|
|
196
199
|
},
|
|
200
|
+
{
|
|
201
|
+
name: "wahooks_react",
|
|
202
|
+
description: "React to a WhatsApp message with an emoji. Use to acknowledge messages or express sentiment.",
|
|
203
|
+
inputSchema: {
|
|
204
|
+
type: "object",
|
|
205
|
+
properties: {
|
|
206
|
+
to: { type: "string", description: "Chat ID (from the channel tag 'from' attribute)" },
|
|
207
|
+
message_id: { type: "string", description: "Message ID to react to (from the channel tag 'message_id' attribute)" },
|
|
208
|
+
reaction: { type: "string", description: "Emoji reaction (e.g. 👍, ❤️, 😂, 👀)" },
|
|
209
|
+
},
|
|
210
|
+
required: ["to", "message_id", "reaction"],
|
|
211
|
+
},
|
|
212
|
+
},
|
|
197
213
|
{
|
|
198
214
|
name: "wahooks_send",
|
|
199
215
|
description: "Send a WhatsApp message to any phone number.",
|
|
@@ -321,13 +337,25 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
321
337
|
const delay = 1000 + Math.random() * 2000 + Math.min(args.text.length * 40, 4000);
|
|
322
338
|
await new Promise((r) => setTimeout(r, delay));
|
|
323
339
|
await api("POST", `/connections/${connectionId}/typing/stop`, { chatId }).catch(() => { });
|
|
324
|
-
|
|
340
|
+
const sendBody = {
|
|
325
341
|
chatId,
|
|
326
342
|
text: args.text,
|
|
327
343
|
skipPresence: true,
|
|
328
|
-
}
|
|
344
|
+
};
|
|
345
|
+
if (args.reply_to)
|
|
346
|
+
sendBody.replyTo = args.reply_to;
|
|
347
|
+
await api("POST", `/connections/${connectionId}/send`, sendBody);
|
|
329
348
|
return { content: [{ type: "text", text: `Sent to ${args.to}` }] };
|
|
330
349
|
}
|
|
350
|
+
case "wahooks_react": {
|
|
351
|
+
const chatId = toChatId(args.to);
|
|
352
|
+
await api("POST", `/connections/${connectionId}/react`, {
|
|
353
|
+
chatId,
|
|
354
|
+
messageId: args.message_id,
|
|
355
|
+
reaction: args.reaction,
|
|
356
|
+
});
|
|
357
|
+
return { content: [{ type: "text", text: `Reacted ${args.reaction} to message` }] };
|
|
358
|
+
}
|
|
331
359
|
case "wahooks_send_image":
|
|
332
360
|
case "wahooks_send_document":
|
|
333
361
|
case "wahooks_send_video":
|
|
@@ -335,7 +363,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
335
363
|
const chatId = toChatId(args.to);
|
|
336
364
|
const media = resolveMedia(args);
|
|
337
365
|
const endpoint = req.params.name.replace("wahooks_", "").replace("_", "-");
|
|
338
|
-
// Human-like: typing → delay → stop typing → send
|
|
366
|
+
// Human-like: typing → delay → stop typing → send (skipPresence to avoid API doubling)
|
|
339
367
|
await api("POST", `/connections/${connectionId}/typing`, { chatId }).catch(() => { });
|
|
340
368
|
await new Promise((r) => setTimeout(r, 1500 + Math.random() * 2000));
|
|
341
369
|
await api("POST", `/connections/${connectionId}/typing/stop`, { chatId }).catch(() => { });
|
|
@@ -344,6 +372,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
344
372
|
...media,
|
|
345
373
|
caption: args.caption,
|
|
346
374
|
filename: args.filename,
|
|
375
|
+
skipPresence: true,
|
|
347
376
|
});
|
|
348
377
|
const type = endpoint.replace("send-", "");
|
|
349
378
|
return { content: [{ type: "text", text: `${type} sent to ${args.to}` }] };
|