added support for querying and sending group chats

This commit is contained in:
Luke Harries
2025-03-30 16:33:41 +01:00
parent c148462421
commit bce07ef3b9
3 changed files with 54 additions and 58 deletions

View File

@@ -9,6 +9,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"reflect" "reflect"
"strings"
"syscall" "syscall"
"time" "time"
@@ -178,24 +179,39 @@ type SendMessageResponse struct {
// SendMessageRequest represents the request body for the send message API // SendMessageRequest represents the request body for the send message API
type SendMessageRequest struct { type SendMessageRequest struct {
Phone string `json:"phone"` Recipient string `json:"recipient"`
Message string `json:"message"` Message string `json:"message"`
} }
// Function to send a WhatsApp message // Function to send a WhatsApp message
func sendWhatsAppMessage(client *whatsmeow.Client, phone, message string) (bool, string) { func sendWhatsAppMessage(client *whatsmeow.Client, recipient string, message string) (bool, string) {
if !client.IsConnected() { if !client.IsConnected() {
return false, "Not connected to WhatsApp" return false, "Not connected to WhatsApp"
} }
// Create JID for recipient // Create JID for recipient
recipientJID := types.JID{ var recipientJID types.JID
User: phone, var err error
// Check if recipient is a JID
isJID := strings.Contains(recipient, "@")
if isJID {
// Parse the JID string
recipientJID, err = types.ParseJID(recipient)
if err != nil {
return false, fmt.Sprintf("Error parsing JID: %v", err)
}
} else {
// Create JID from phone number
recipientJID = types.JID{
User: recipient,
Server: "s.whatsapp.net", // For personal chats Server: "s.whatsapp.net", // For personal chats
} }
}
// Send the message // Send the message
_, err := client.SendMessage(context.Background(), recipientJID, &waProto.Message{ _, err = client.SendMessage(context.Background(), recipientJID, &waProto.Message{
Conversation: proto.String(message), Conversation: proto.String(message),
}) })
@@ -203,7 +219,7 @@ func sendWhatsAppMessage(client *whatsmeow.Client, phone, message string) (bool,
return false, fmt.Sprintf("Error sending message: %v", err) return false, fmt.Sprintf("Error sending message: %v", err)
} }
return true, fmt.Sprintf("Message sent to %s", phone) return true, fmt.Sprintf("Message sent to %s", recipient)
} }
// Start a REST API server to expose the WhatsApp client functionality // Start a REST API server to expose the WhatsApp client functionality
@@ -225,13 +241,13 @@ func startRESTServer(client *whatsmeow.Client, port int) {
} }
// Validate request // Validate request
if req.Phone == "" || req.Message == "" { if req.Recipient == "" || req.Message == "" {
http.Error(w, "Phone and message are required", http.StatusBadRequest) http.Error(w, "Recipient and message are required", http.StatusBadRequest)
return return
} }
// Send the message // Send the message
success, message := sendWhatsAppMessage(client, req.Phone, req.Message) success, message := sendWhatsAppMessage(client, req.Recipient, req.Message)
fmt.Println("Message sent", success, message) fmt.Println("Message sent", success, message)
// Set response headers // Set response headers
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View File

@@ -150,17 +150,29 @@ def get_message_context(
return context return context
@mcp.tool() @mcp.tool()
def send_message(phone_number: str, message: str) -> Dict[str, Any]: def send_message(
"""Send a WhatsApp message to the specified phone number. message: str,
recipient: str
) -> Dict[str, Any]:
"""Send a WhatsApp message to a person or group. For group chats use the JID.
Args: Args:
phone_number: The recipient's phone number, with country code but no + or other symbols
message: The message text to send message: The message text to send
recipient: The recipient - either a phone number with country code but no + or other symbols,
or a JID (e.g., "123456789@s.whatsapp.net" or a group JID like "123456789@g.us")
Returns: Returns:
A dictionary containing success status and a status message A dictionary containing success status and a status message
""" """
success, status_message = whatsapp_send_message(phone_number, message) # Validate input
if not recipient:
return {
"success": False,
"message": "Recipient must be provided"
}
# Call the whatsapp_send_message function with the unified recipient parameter
success, status_message = whatsapp_send_message(message, recipient)
return { return {
"success": success, "success": success,
"message": status_message "message": status_message

View File

@@ -662,57 +662,25 @@ def get_direct_chat_by_contact(sender_phone_number: str) -> Optional[Chat]:
if 'conn' in locals(): if 'conn' in locals():
conn.close() conn.close()
def send_message(phone_number: str, message: str) -> Tuple[bool, str]: def send_message(message: str, recipient: str) -> Tuple[bool, str]:
"""Send a WhatsApp message to the specified phone number. """Send a WhatsApp message to the specified recipient. For group messages use the JID.
Args: Args:
phone_number (str): The recipient's phone number, with country code but no + or other symbols message: The message text to send
message (str): The message text to send recipient: The recipient - either a phone number with country code but no + or other symbols,
or a JID (e.g., "123456789@s.whatsapp.net" or a group JID like "123456789@g.us").
Returns: Returns:
Tuple[bool, str]: A tuple containing success status and a status message Tuple[bool, str]: A tuple containing success status and a status message
""" """
try: try:
# Validate input
if not recipient:
return False, "Recipient must be provided"
url = f"{WHATSAPP_API_BASE_URL}/send" url = f"{WHATSAPP_API_BASE_URL}/send"
payload = { payload = {
"phone": phone_number, "recipient": recipient,
"message": message
}
response = requests.post(url, json=payload)
# Check if the request was successful
if response.status_code == 200:
result = response.json()
return result.get("success", False), result.get("message", "Unknown response")
else:
return False, f"Error: HTTP {response.status_code} - {response.text}"
except requests.RequestException as e:
return False, f"Request error: {str(e)}"
except json.JSONDecodeError:
return False, f"Error parsing response: {response.text}"
except Exception as e:
return False, f"Unexpected error: {str(e)}"
def send_group_message(group_jid: str, message: str) -> Tuple[bool, str]:
"""Send a WhatsApp message to the specified group.
Args:
group_jid (str): The JID of the group to send the message to (must end with @g.us)
message (str): The message text to send
Returns:
Tuple[bool, str]: A tuple containing success status and a status message
"""
try:
# Validate that this looks like a group JID
if not group_jid.endswith("@g.us"):
return False, "Invalid group JID format. Group JIDs must end with @g.us"
url = f"{WHATSAPP_API_BASE_URL}/send-group"
payload = {
"jid": group_jid,
"message": message "message": message
} }