Skip to main content
Glama
by wsapi-chat
messaging.ts15.3 kB
import type { ToolHandler } from '../server.js'; import { wsapiClient } from '../client/index.js'; import { createLogger } from '../utils/logger.js'; import { validateInput, sendTextMessageSchema, sendImageMessageSchema, sendVideoMessageSchema, sendLinkMessageSchema, sendReactionMessageSchema, editMessageSchema, deleteMessageSchema, markMessageAsReadSchema, starMessageSchema, type SendTextMessageInput, type SendImageMessageInput, type SendVideoMessageInput, type SendLinkMessageInput, type SendReactionMessageInput, } from '../validation/schemas.js'; const logger = createLogger('messaging-tools'); // Send text message tool export const sendTextMessage: ToolHandler = { name: 'whatsapp_send_text', description: 'Send a text message to a WhatsApp contact or group. Supports mentions and replies.', inputSchema: { type: 'object', properties: { to: { type: 'string', description: 'Recipient phone number (with @s.whatsapp.net) or group ID (with @g.us)', }, text: { type: 'string', description: 'Message text content (max 4096 characters)', }, mentions: { type: 'array', items: { type: 'string' }, description: 'List of phone numbers to mention in the message', optional: true, }, replyTo: { type: 'string', description: 'ID of the message being replied to', optional: true, }, isForwarded: { type: 'boolean', description: 'Whether the message should be marked as forwarded', optional: true, }, }, required: ['to', 'text'], }, handler: async (args: any) => { const input = validateInput(sendTextMessageSchema, args) as SendTextMessageInput; logger.info('Sending text message', { to: input.to, textLength: input.text.length }); const result = await wsapiClient.post('/messages/text', input); logger.info('Text message sent successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Text message sent successfully', }; }, }; // Send image message tool export const sendImageMessage: ToolHandler = { name: 'whatsapp_send_image', description: 'Send an image message to a WhatsApp contact or group. Can send from URL or base64.', inputSchema: { type: 'object', properties: { to: { type: 'string', description: 'Recipient phone number (with @s.whatsapp.net) or group ID (with @g.us)', }, imageBase64: { type: 'string', description: 'Base64 encoded image data (alternative to imageURL)', optional: true, }, imageURL: { type: 'string', description: 'URL of the image to send (alternative to imageBase64)', optional: true, }, mimeType: { type: 'string', enum: ['image/jpeg', 'image/png', 'image/webp', 'image/gif'], description: 'MIME type of the image', }, caption: { type: 'string', description: 'Caption for the image (max 1024 characters)', optional: true, }, mentions: { type: 'array', items: { type: 'string' }, description: 'List of phone numbers to mention in the caption', optional: true, }, replyTo: { type: 'string', description: 'ID of the message being replied to', optional: true, }, isForwarded: { type: 'boolean', description: 'Whether the message should be marked as forwarded', optional: true, }, viewOnce: { type: 'boolean', description: 'Whether the image should be sent as view-once', optional: true, }, }, required: ['to', 'mimeType'], }, handler: async (args: any) => { const input = validateInput(sendImageMessageSchema, args) as SendImageMessageInput; logger.info('Sending image message', { to: input.to, mimeType: input.mimeType, hasCaption: !!input.caption, viewOnce: input.viewOnce, }); const result = await wsapiClient.post('/messages/image', input); logger.info('Image message sent successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Image message sent successfully', }; }, }; // Send video message tool export const sendVideoMessage: ToolHandler = { name: 'whatsapp_send_video', description: 'Send a video message to a WhatsApp contact or group. Can send from URL or base64.', inputSchema: { type: 'object', properties: { to: { type: 'string', description: 'Recipient phone number (with @s.whatsapp.net) or group ID (with @g.us)', }, videoBase64: { type: 'string', description: 'Base64 encoded video data (alternative to videoURL)', optional: true, }, videoURL: { type: 'string', description: 'URL of the video to send (alternative to videoBase64)', optional: true, }, mimeType: { type: 'string', enum: ['video/mp4', 'video/3gp', 'video/mov', 'video/avi'], description: 'MIME type of the video', }, caption: { type: 'string', description: 'Caption for the video (max 1024 characters)', optional: true, }, viewOnce: { type: 'boolean', description: 'Whether the video should be sent as view-once', optional: true, }, mentions: { type: 'array', items: { type: 'string' }, description: 'List of phone numbers to mention in the caption', optional: true, }, replyTo: { type: 'string', description: 'ID of the message being replied to', optional: true, }, isForwarded: { type: 'boolean', description: 'Whether the message should be marked as forwarded', optional: true, }, }, required: ['to', 'mimeType'], }, handler: async (args: any) => { const input = validateInput(sendVideoMessageSchema, args) as SendVideoMessageInput; logger.info('Sending video message', { to: input.to, mimeType: input.mimeType, hasCaption: !!input.caption, viewOnce: input.viewOnce, }); const result = await wsapiClient.post('/messages/video', input); logger.info('Video message sent successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Video message sent successfully', }; }, }; // Send link message tool export const sendLinkMessage: ToolHandler = { name: 'whatsapp_send_link', description: 'Send a link message with optional preview to a WhatsApp contact or group.', inputSchema: { type: 'object', properties: { to: { type: 'string', description: 'Recipient phone number (with @s.whatsapp.net) or group ID (with @g.us)', }, text: { type: 'string', description: 'Message text content (max 4096 characters)', }, url: { type: 'string', description: 'URL to include in the message', }, title: { type: 'string', description: 'Title for the link preview (max 500 characters)', optional: true, }, description: { type: 'string', description: 'Description for the link preview (max 1000 characters)', optional: true, }, jpegThumbnail: { type: 'string', description: 'Base64 encoded JPEG thumbnail for the link preview', optional: true, }, mentions: { type: 'array', items: { type: 'string' }, description: 'List of phone numbers to mention in the message', optional: true, }, replyTo: { type: 'string', description: 'ID of the message being replied to', optional: true, }, isForwarded: { type: 'boolean', description: 'Whether the message should be marked as forwarded', optional: true, }, }, required: ['to', 'text', 'url'], }, handler: async (args: any) => { const input = validateInput(sendLinkMessageSchema, args) as SendLinkMessageInput; logger.info('Sending link message', { to: input.to, url: input.url, hasTitle: !!input.title, hasDescription: !!input.description, }); const result = await wsapiClient.post('/messages/link', input); logger.info('Link message sent successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Link message sent successfully', }; }, }; // Send reaction message tool export const sendReactionMessage: ToolHandler = { name: 'whatsapp_send_reaction', description: 'Send a reaction (emoji) to a specific message.', inputSchema: { type: 'object', properties: { messageId: { type: 'string', description: 'ID of the message to react to', }, to: { type: 'string', description: 'Chat ID where the message is located', }, senderId: { type: 'string', description: 'ID of the original message sender', }, reaction: { type: 'string', description: 'Emoji reaction to send (max 10 characters)', }, }, required: ['messageId', 'to', 'senderId', 'reaction'], }, handler: async (args: any) => { const input = validateInput(sendReactionMessageSchema, args) as SendReactionMessageInput; logger.info('Sending reaction', { messageId: input.messageId, to: input.to, reaction: input.reaction, }); const result = await wsapiClient.post(`/messages/${input.messageId}/reaction`, { to: input.to, senderId: input.senderId, reaction: input.reaction, }); logger.info('Reaction sent successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Reaction sent successfully', }; }, }; // Edit message tool export const editMessage: ToolHandler = { name: 'whatsapp_edit_message', description: 'Edit a previously sent text message.', inputSchema: { type: 'object', properties: { messageId: { type: 'string', description: 'ID of the message to edit', }, to: { type: 'string', description: 'Chat ID where the message is located', }, text: { type: 'string', description: 'New text content for the message (max 4096 characters)', }, }, required: ['messageId', 'to', 'text'], }, handler: async (args: any) => { const input = validateInput(editMessageSchema, args); logger.info('Editing message', { messageId: input.messageId, to: input.to, textLength: input.text.length, }); const result = await wsapiClient.put(`/messages/${input.messageId}/text`, { to: input.to, text: input.text, }); logger.info('Message edited successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Message edited successfully', }; }, }; // Delete message tool export const deleteMessage: ToolHandler = { name: 'whatsapp_delete_message', description: 'Delete a message for all participants in the chat.', inputSchema: { type: 'object', properties: { messageId: { type: 'string', description: 'ID of the message to delete', }, chatId: { type: 'string', description: 'Chat ID where the message is located', }, senderId: { type: 'string', description: 'ID of the message sender', }, }, required: ['messageId', 'chatId', 'senderId'], }, handler: async (args: any) => { const input = validateInput(deleteMessageSchema, args); logger.info('Deleting message', { messageId: input.messageId, chatId: input.chatId, }); await wsapiClient.put(`/messages/${input.messageId}/delete`, { chatId: input.chatId, senderId: input.senderId, }); logger.info('Message deleted successfully', { messageId: input.messageId }); return { success: true, message: 'Message deleted successfully', }; }, }; // Mark message as read tool export const markMessageAsRead: ToolHandler = { name: 'whatsapp_mark_message_read', description: 'Mark a message as read.', inputSchema: { type: 'object', properties: { messageId: { type: 'string', description: 'ID of the message to mark as read', }, chatId: { type: 'string', description: 'Chat ID where the message is located', }, senderId: { type: 'string', description: 'ID of the message sender', }, receiptType: { type: 'string', enum: ['delivered', 'sender', 'read', 'played'], description: 'Type of receipt to send', }, }, required: ['messageId', 'chatId', 'senderId', 'receiptType'], }, handler: async (args: any) => { const input = validateInput(markMessageAsReadSchema, args); logger.info('Marking message as read', { messageId: input.messageId, chatId: input.chatId, receiptType: input.receiptType, }); await wsapiClient.put(`/messages/${input.messageId}/read`, { chatId: input.chatId, senderId: input.senderId, receiptType: input.receiptType, }); logger.info('Message marked as read successfully', { messageId: input.messageId }); return { success: true, message: 'Message marked as read successfully', }; }, }; // Star message tool export const starMessage: ToolHandler = { name: 'whatsapp_star_message', description: 'Star or unstar a message.', inputSchema: { type: 'object', properties: { messageId: { type: 'string', description: 'ID of the message to star', }, chatId: { type: 'string', description: 'Chat ID where the message is located', }, senderId: { type: 'string', description: 'ID of the message sender', }, }, required: ['messageId', 'chatId', 'senderId'], }, handler: async (args: any) => { const input = validateInput(starMessageSchema, args); logger.info('Starring message', { messageId: input.messageId, chatId: input.chatId, }); await wsapiClient.put(`/messages/${input.messageId}/star`, { chatId: input.chatId, senderId: input.senderId, }); logger.info('Message starred successfully', { messageId: input.messageId }); return { success: true, message: 'Message starred successfully', }; }, }; // Import advanced messaging tools import { advancedMessagingTools } from './messaging-advanced.js'; // Export all messaging tools export const messagingTools = { sendTextMessage, sendImageMessage, sendVideoMessage, sendLinkMessage, sendReactionMessage, editMessage, deleteMessage, markMessageAsRead, starMessage, ...advancedMessagingTools, };

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/wsapi-chat/wsapi-mcp'

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