Skip to main content
Glama
Jem-HR
by Jem-HR

send_message_with_buttons

Send WhatsApp messages with interactive reply buttons to collect user responses, enabling quick selection from up to three options with optional header and footer text.

Instructions

Send a message with reply buttons (up to 3).

CONSTRAINTS:

  • Maximum 3 buttons per message

  • Button title: max 20 characters

  • Button ID (callback_data): max 256 characters

  • Header text: max 60 characters (if provided)

  • Footer text: max 60 characters (if provided)

EXAMPLE: { "to": "+1234567890", "text": "Choose an option:", "buttons": [ {"id": "option_1", "title": "Yes"}, {"id": "option_2", "title": "No"}, {"id": "option_3", "title": "Maybe"} ], "header": "Quick Question", "footer": "Select one option" }

Args: to: Phone number (with country code) or WhatsApp ID text: Message body text (main message content) buttons: List of buttons with 'id' and 'title' keys (max 3) header: Optional header text (appears above main text) footer: Optional footer text (appears below buttons) reply_to_message_id: Message ID to reply to

Returns: Dictionary with success status and message ID

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toYes
textYes
buttonsYes
headerNo
footerNo
reply_to_message_idNo

Implementation Reference

  • The main implementation of send_message_with_buttons tool. This async function sends WhatsApp messages with up to 3 reply buttons. It validates constraints (button limits, title/id lengths, header/footer lengths), converts button dictionaries to PyWA Button objects, calls wa_client.send_message(), and returns success/error response with message ID.
    @mcp.tool()
    async def send_message_with_buttons(
        to: str,
        text: str,
        buttons: List[Dict[str, str]],
        header: Optional[str] = None,
        footer: Optional[str] = None,
        *,
        reply_to_message_id: Optional[str] = None,
    ) -> dict:
        """
        Send a message with reply buttons (up to 3).
        
        CONSTRAINTS:
        - Maximum 3 buttons per message
        - Button title: max 20 characters
        - Button ID (callback_data): max 256 characters
        - Header text: max 60 characters (if provided)
        - Footer text: max 60 characters (if provided)
        
        EXAMPLE:
        {
          "to": "+1234567890",
          "text": "Choose an option:",
          "buttons": [
            {"id": "option_1", "title": "Yes"},
            {"id": "option_2", "title": "No"},
            {"id": "option_3", "title": "Maybe"}
          ],
          "header": "Quick Question",
          "footer": "Select one option"
        }
        
        Args:
            to: Phone number (with country code) or WhatsApp ID
            text: Message body text (main message content)
            buttons: List of buttons with 'id' and 'title' keys (max 3)
            header: Optional header text (appears above main text)
            footer: Optional footer text (appears below buttons)
            reply_to_message_id: Message ID to reply to
        
        Returns:
            Dictionary with success status and message ID
        """
        try:
            # Validate constraints
            if len(buttons) > 3:
                return {"success": False, "error": "Maximum 3 buttons allowed"}
            
            if header and len(header) > 60:
                return {"success": False, "error": "Header text must be max 60 characters"}
                
            if footer and len(footer) > 60:
                return {"success": False, "error": "Footer text must be max 60 characters"}
            
            # Convert button dictionaries to PyWA Button objects
            button_objects = []
            for btn in buttons:
                if "id" not in btn or "title" not in btn:
                    return {"success": False, "error": "Each button must have 'id' and 'title' keys"}
                
                if len(btn["title"]) > 20:
                    return {"success": False, "error": f"Button title '{btn['title']}' exceeds 20 characters"}
                    
                if len(btn["id"]) > 256:
                    return {"success": False, "error": f"Button ID '{btn['id']}' exceeds 256 characters"}
                
                button_objects.append(Button(
                    title=btn["title"],
                    callback_data=btn["id"]
                ))
            
            result = wa_client.send_message(
                to=to,
                text=text,
                buttons=button_objects,
                header=header,
                footer=footer,
                reply_to_message_id=reply_to_message_id,
            )
            
            logger.info(f"Message with buttons sent to {to}")
            message_id = getattr(result, 'id', str(result)) if result else None
            return {"success": True, "message_id": message_id}
        except Exception as e:
            logger.error(f"Failed to send message with buttons: {str(e)}")
            return {"success": False, "error": str(e)}
  • The register_interactive_tools function that registers the send_message_with_buttons tool using the @mcp.tool() decorator at line 14. This function is called from the main register_all_tools in __init__.py to register all interactive messaging tools.
    def register_interactive_tools(mcp, wa_client: WhatsApp):
        """Register interactive messaging tools."""
        
        @mcp.tool()
        async def send_message_with_buttons(
            to: str,
            text: str,
            buttons: List[Dict[str, str]],
            header: Optional[str] = None,
            footer: Optional[str] = None,
            *,
            reply_to_message_id: Optional[str] = None,
        ) -> dict:
            """
            Send a message with reply buttons (up to 3).
            
            CONSTRAINTS:
            - Maximum 3 buttons per message
            - Button title: max 20 characters
            - Button ID (callback_data): max 256 characters
            - Header text: max 60 characters (if provided)
            - Footer text: max 60 characters (if provided)
            
            EXAMPLE:
            {
              "to": "+1234567890",
              "text": "Choose an option:",
              "buttons": [
                {"id": "option_1", "title": "Yes"},
                {"id": "option_2", "title": "No"},
                {"id": "option_3", "title": "Maybe"}
              ],
              "header": "Quick Question",
              "footer": "Select one option"
            }
            
            Args:
                to: Phone number (with country code) or WhatsApp ID
                text: Message body text (main message content)
                buttons: List of buttons with 'id' and 'title' keys (max 3)
                header: Optional header text (appears above main text)
                footer: Optional footer text (appears below buttons)
                reply_to_message_id: Message ID to reply to
            
            Returns:
                Dictionary with success status and message ID
            """
            try:
                # Validate constraints
                if len(buttons) > 3:
                    return {"success": False, "error": "Maximum 3 buttons allowed"}
                
                if header and len(header) > 60:
                    return {"success": False, "error": "Header text must be max 60 characters"}
                    
                if footer and len(footer) > 60:
                    return {"success": False, "error": "Footer text must be max 60 characters"}
                
                # Convert button dictionaries to PyWA Button objects
                button_objects = []
                for btn in buttons:
                    if "id" not in btn or "title" not in btn:
                        return {"success": False, "error": "Each button must have 'id' and 'title' keys"}
                    
                    if len(btn["title"]) > 20:
                        return {"success": False, "error": f"Button title '{btn['title']}' exceeds 20 characters"}
                        
                    if len(btn["id"]) > 256:
                        return {"success": False, "error": f"Button ID '{btn['id']}' exceeds 256 characters"}
                    
                    button_objects.append(Button(
                        title=btn["title"],
                        callback_data=btn["id"]
                    ))
                
                result = wa_client.send_message(
                    to=to,
                    text=text,
                    buttons=button_objects,
                    header=header,
                    footer=footer,
                    reply_to_message_id=reply_to_message_id,
                )
                
                logger.info(f"Message with buttons sent to {to}")
                message_id = getattr(result, 'id', str(result)) if result else None
                return {"success": True, "message_id": message_id}
            except Exception as e:
                logger.error(f"Failed to send message with buttons: {str(e)}")
                return {"success": False, "error": str(e)}
  • The register_all_tools function that orchestrates tool registration, calling register_interactive_tools(mcp, wa_client) at line 17 to register the send_message_with_buttons tool and other interactive tools.
    def register_all_tools(mcp, wa_client):
        """Register all available tools with the MCP server."""
        register_messaging_tools(mcp, wa_client)
        register_interactive_tools(mcp, wa_client)
        register_template_tools(mcp, wa_client)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jem-HR/pywa-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server