/**
* MCP Conversation Tools for GoHighLevel Integration
* Exposes messaging and conversation capabilities to ChatGPT
*/
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { GHLApiClient } from '../clients/ghl-api-client.js';
import {
MCPSendSMSParams,
MCPSendEmailParams,
MCPSearchConversationsParams,
MCPGetConversationParams,
MCPCreateConversationParams,
MCPUpdateConversationParams,
MCPDeleteConversationParams,
MCPGetEmailMessageParams,
MCPGetMessageParams,
MCPUploadMessageAttachmentsParams,
MCPUpdateMessageStatusParams,
MCPAddInboundMessageParams,
MCPAddOutboundCallParams,
MCPGetMessageRecordingParams,
MCPGetMessageTranscriptionParams,
MCPDownloadTranscriptionParams,
MCPCancelScheduledMessageParams,
MCPCancelScheduledEmailParams,
MCPLiveChatTypingParams,
GHLConversation,
GHLMessage,
GHLEmailMessage,
GHLSendMessageResponse,
GHLSearchConversationsResponse,
GHLGetMessagesResponse,
GHLProcessMessageResponse,
GHLCancelScheduledResponse,
GHLMessageRecordingResponse,
GHLMessageTranscriptionResponse,
GHLLiveChatTypingResponse,
GHLUploadFilesResponse
} from '../types/ghl-types.js';
/**
* Conversation Tools Class
* Implements MCP tools for messaging and conversation management
*/
export class ConversationTools {
constructor(private ghlClient: GHLApiClient) {}
/**
* Get all conversation tool definitions for MCP server
*/
getToolDefinitions(): Tool[] {
return [
{
name: 'send_sms',
description: 'Send an SMS message to a contact in GoHighLevel',
inputSchema: {
type: 'object',
properties: {
contactId: {
type: 'string',
description: 'The unique ID of the contact to send SMS to'
},
message: {
type: 'string',
description: 'The SMS message content to send',
maxLength: 1600
},
fromNumber: {
type: 'string',
description: 'Optional: Phone number to send from (must be configured in GHL)'
}
},
required: ['contactId', 'message']
}
},
{
name: 'send_email',
description: 'Send an email message to a contact in GoHighLevel',
inputSchema: {
type: 'object',
properties: {
contactId: {
type: 'string',
description: 'The unique ID of the contact to send email to'
},
subject: {
type: 'string',
description: 'Email subject line'
},
message: {
type: 'string',
description: 'Plain text email content'
},
html: {
type: 'string',
description: 'HTML email content (optional, takes precedence over message)'
},
emailFrom: {
type: 'string',
description: 'Optional: Email address to send from (must be configured in GHL)',
format: 'email'
},
attachments: {
type: 'array',
items: { type: 'string' },
description: 'Optional: Array of attachment URLs'
},
emailCc: {
type: 'array',
items: { type: 'string' },
description: 'Optional: Array of CC email addresses'
},
emailBcc: {
type: 'array',
items: { type: 'string' },
description: 'Optional: Array of BCC email addresses'
}
},
required: ['contactId', 'subject']
}
},
{
name: 'search_conversations',
description: 'Search conversations in GoHighLevel with various filters',
inputSchema: {
type: 'object',
properties: {
contactId: {
type: 'string',
description: 'Filter conversations for a specific contact'
},
query: {
type: 'string',
description: 'Search query to filter conversations'
},
status: {
type: 'string',
enum: ['all', 'read', 'unread', 'starred', 'recents'],
description: 'Filter conversations by read status',
default: 'all'
},
limit: {
type: 'number',
description: 'Maximum number of conversations to return (default: 20, max: 100)',
minimum: 1,
maximum: 100,
default: 20
},
assignedTo: {
type: 'string',
description: 'Filter by user ID assigned to conversations'
}
}
}
},
{
name: 'get_conversation',
description: 'Get detailed conversation information including message history',
inputSchema: {
type: 'object',
properties: {
conversationId: {
type: 'string',
description: 'The unique ID of the conversation to retrieve'
},
limit: {
type: 'number',
description: 'Maximum number of messages to return (default: 20)',
minimum: 1,
maximum: 100,
default: 20
},
messageTypes: {
type: 'array',
items: {
type: 'string',
enum: [
'TYPE_SMS', 'TYPE_EMAIL', 'TYPE_CALL', 'TYPE_FACEBOOK',
'TYPE_INSTAGRAM', 'TYPE_WHATSAPP', 'TYPE_LIVE_CHAT'
]
},
description: 'Filter messages by type (optional)'
}
},
required: ['conversationId']
}
},
{
name: 'create_conversation',
description: 'Create a new conversation with a contact',
inputSchema: {
type: 'object',
properties: {
contactId: {
type: 'string',
description: 'The unique ID of the contact to create conversation with'
}
},
required: ['contactId']
}
},
{
name: 'update_conversation',
description: 'Update conversation properties (star, mark read, etc.)',
inputSchema: {
type: 'object',
properties: {
conversationId: {
type: 'string',
description: 'The unique ID of the conversation to update'
},
starred: {
type: 'boolean',
description: 'Star or unstar the conversation'
},
unreadCount: {
type: 'number',
description: 'Set the unread message count (0 to mark as read)',
minimum: 0
}
},
required: ['conversationId']
}
},
{
name: 'get_recent_messages',
description: 'Get recent messages across all conversations for monitoring',
inputSchema: {
type: 'object',
properties: {
limit: {
type: 'number',
description: 'Maximum number of conversations to check (default: 10)',
minimum: 1,
maximum: 50,
default: 10
},
status: {
type: 'string',
enum: ['all', 'unread'],
description: 'Filter by conversation status',
default: 'unread'
}
}
}
},
{
name: 'delete_conversation',
description: 'Delete a conversation permanently',
inputSchema: {
type: 'object',
properties: {
conversationId: {
type: 'string',
description: 'The unique ID of the conversation to delete'
}
},
required: ['conversationId']
}
},
// MESSAGE MANAGEMENT TOOLS
{
name: 'get_email_message',
description: 'Get detailed email message information by email message ID',
inputSchema: {
type: 'object',
properties: {
emailMessageId: {
type: 'string',
description: 'The unique ID of the email message to retrieve'
}
},
required: ['emailMessageId']
}
},
{
name: 'get_message',
description: 'Get detailed message information by message ID',
inputSchema: {
type: 'object',
properties: {
messageId: {
type: 'string',
description: 'The unique ID of the message to retrieve'
}
},
required: ['messageId']
}
},
{
name: 'upload_message_attachments',
description: 'Upload file attachments for use in messages',
inputSchema: {
type: 'object',
properties: {
conversationId: {
type: 'string',
description: 'The conversation ID to upload attachments for'
},
attachmentUrls: {
type: 'array',
items: { type: 'string' },
description: 'Array of file URLs to upload as attachments'
}
},
required: ['conversationId', 'attachmentUrls']
}
},
{
name: 'update_message_status',
description: 'Update the delivery status of a message',
inputSchema: {
type: 'object',
properties: {
messageId: {
type: 'string',
description: 'The unique ID of the message to update'
},
status: {
type: 'string',
enum: ['delivered', 'failed', 'pending', 'read'],
description: 'New status for the message'
},
error: {
type: 'object',
description: 'Error details if status is failed',
properties: {
code: { type: 'string' },
type: { type: 'string' },
message: { type: 'string' }
}
},
emailMessageId: {
type: 'string',
description: 'Email message ID if updating email status'
},
recipients: {
type: 'array',
items: { type: 'string' },
description: 'Email delivery status for additional recipients'
}
},
required: ['messageId', 'status']
}
},
// MANUAL MESSAGE CREATION TOOLS
{
name: 'add_inbound_message',
description: 'Manually add an inbound message to a conversation',
inputSchema: {
type: 'object',
properties: {
type: {
type: 'string',
enum: ['SMS', 'Email', 'WhatsApp', 'GMB', 'IG', 'FB', 'Custom', 'WebChat', 'Live_Chat', 'Call'],
description: 'Type of inbound message to add'
},
conversationId: {
type: 'string',
description: 'The conversation to add the message to'
},
conversationProviderId: {
type: 'string',
description: 'Conversation provider ID for the message'
},
message: {
type: 'string',
description: 'Message content (for text-based messages)'
},
attachments: {
type: 'array',
items: { type: 'string' },
description: 'Array of attachment URLs'
},
html: {
type: 'string',
description: 'HTML content for email messages'
},
subject: {
type: 'string',
description: 'Subject line for email messages'
},
emailFrom: {
type: 'string',
description: 'From email address'
},
emailTo: {
type: 'string',
description: 'To email address'
},
emailCc: {
type: 'array',
items: { type: 'string' },
description: 'CC email addresses'
},
emailBcc: {
type: 'array',
items: { type: 'string' },
description: 'BCC email addresses'
},
emailMessageId: {
type: 'string',
description: 'Email message ID for threading'
},
altId: {
type: 'string',
description: 'External provider message ID'
},
date: {
type: 'string',
description: 'Date of the message (ISO format)'
},
call: {
type: 'object',
description: 'Call details for call-type messages',
properties: {
to: { type: 'string', description: 'Called number' },
from: { type: 'string', description: 'Caller number' },
status: {
type: 'string',
enum: ['pending', 'completed', 'answered', 'busy', 'no-answer', 'failed', 'canceled', 'voicemail'],
description: 'Call status'
}
}
}
},
required: ['type', 'conversationId', 'conversationProviderId']
}
},
{
name: 'add_outbound_call',
description: 'Manually add an outbound call record to a conversation',
inputSchema: {
type: 'object',
properties: {
conversationId: {
type: 'string',
description: 'The conversation to add the call to'
},
conversationProviderId: {
type: 'string',
description: 'Conversation provider ID for the call'
},
to: {
type: 'string',
description: 'Called phone number'
},
from: {
type: 'string',
description: 'Caller phone number'
},
status: {
type: 'string',
enum: ['pending', 'completed', 'answered', 'busy', 'no-answer', 'failed', 'canceled', 'voicemail'],
description: 'Call completion status'
},
attachments: {
type: 'array',
items: { type: 'string' },
description: 'Array of attachment URLs'
},
altId: {
type: 'string',
description: 'External provider call ID'
},
date: {
type: 'string',
description: 'Date of the call (ISO format)'
}
},
required: ['conversationId', 'conversationProviderId', 'to', 'from', 'status']
}
},
// CALL RECORDING & TRANSCRIPTION TOOLS
{
name: 'get_message_recording',
description: 'Get call recording audio for a message',
inputSchema: {
type: 'object',
properties: {
messageId: {
type: 'string',
description: 'The unique ID of the call message to get recording for'
}
},
required: ['messageId']
}
},
{
name: 'get_message_transcription',
description: 'Get call transcription text for a message',
inputSchema: {
type: 'object',
properties: {
messageId: {
type: 'string',
description: 'The unique ID of the call message to get transcription for'
}
},
required: ['messageId']
}
},
{
name: 'download_transcription',
description: 'Download call transcription as a text file',
inputSchema: {
type: 'object',
properties: {
messageId: {
type: 'string',
description: 'The unique ID of the call message to download transcription for'
}
},
required: ['messageId']
}
},
// SCHEDULING MANAGEMENT TOOLS
{
name: 'cancel_scheduled_message',
description: 'Cancel a scheduled message before it is sent',
inputSchema: {
type: 'object',
properties: {
messageId: {
type: 'string',
description: 'The unique ID of the scheduled message to cancel'
}
},
required: ['messageId']
}
},
{
name: 'cancel_scheduled_email',
description: 'Cancel a scheduled email before it is sent',
inputSchema: {
type: 'object',
properties: {
emailMessageId: {
type: 'string',
description: 'The unique ID of the scheduled email to cancel'
}
},
required: ['emailMessageId']
}
},
// LIVE CHAT TOOLS
{
name: 'live_chat_typing',
description: 'Send typing indicator for live chat conversations',
inputSchema: {
type: 'object',
properties: {
visitorId: {
type: 'string',
description: 'Unique visitor ID for the live chat session'
},
conversationId: {
type: 'string',
description: 'The conversation ID for the live chat'
},
isTyping: {
type: 'boolean',
description: 'Whether the agent is currently typing'
}
},
required: ['visitorId', 'conversationId', 'isTyping']
}
}
];
}
/**
* Execute conversation tool based on tool name and arguments
*/
async executeTool(name: string, args: any): Promise<any> {
switch (name) {
case 'send_sms':
return this.sendSMS(args as MCPSendSMSParams);
case 'send_email':
return this.sendEmail(args as MCPSendEmailParams);
case 'search_conversations':
return this.searchConversations(args as MCPSearchConversationsParams);
case 'get_conversation':
return this.getConversation(args as MCPGetConversationParams);
case 'create_conversation':
return this.createConversation(args as MCPCreateConversationParams);
case 'update_conversation':
return this.updateConversation(args as MCPUpdateConversationParams);
case 'get_recent_messages':
return this.getRecentMessages(args);
case 'delete_conversation':
return this.deleteConversation(args as MCPDeleteConversationParams);
case 'get_email_message':
return this.getEmailMessage(args as MCPGetEmailMessageParams);
case 'get_message':
return this.getMessage(args as MCPGetMessageParams);
case 'upload_message_attachments':
return this.uploadMessageAttachments(args as MCPUploadMessageAttachmentsParams);
case 'update_message_status':
return this.updateMessageStatus(args as MCPUpdateMessageStatusParams);
case 'add_inbound_message':
return this.addInboundMessage(args as MCPAddInboundMessageParams);
case 'add_outbound_call':
return this.addOutboundCall(args as MCPAddOutboundCallParams);
case 'get_message_recording':
return this.getMessageRecording(args as MCPGetMessageRecordingParams);
case 'get_message_transcription':
return this.getMessageTranscription(args as MCPGetMessageTranscriptionParams);
case 'download_transcription':
return this.downloadTranscription(args as MCPDownloadTranscriptionParams);
case 'cancel_scheduled_message':
return this.cancelScheduledMessage(args as MCPCancelScheduledMessageParams);
case 'cancel_scheduled_email':
return this.cancelScheduledEmail(args as MCPCancelScheduledEmailParams);
case 'live_chat_typing':
return this.liveChatTyping(args as MCPLiveChatTypingParams);
default:
throw new Error(`Unknown tool: ${name}`);
}
}
/**
* SEND SMS
*/
private async sendSMS(params: MCPSendSMSParams): Promise<{ success: boolean; messageId: string; conversationId: string; message: string }> {
try {
const response = await this.ghlClient.sendSMS(
params.contactId,
params.message,
params.fromNumber
);
const result = response.data as GHLSendMessageResponse;
return {
success: true,
messageId: result.messageId,
conversationId: result.conversationId,
message: `SMS sent successfully to contact ${params.contactId}`
};
} catch (error) {
throw new Error(`Failed to send SMS: ${error}`);
}
}
/**
* SEND EMAIL
*/
private async sendEmail(params: MCPSendEmailParams): Promise<{ success: boolean; messageId: string; conversationId: string; emailMessageId?: string; message: string }> {
try {
const response = await this.ghlClient.sendEmail(
params.contactId,
params.subject,
params.message,
params.html,
{
emailFrom: params.emailFrom,
emailCc: params.emailCc,
emailBcc: params.emailBcc,
attachments: params.attachments
}
);
const result = response.data as GHLSendMessageResponse;
return {
success: true,
messageId: result.messageId,
conversationId: result.conversationId,
emailMessageId: result.emailMessageId,
message: `Email sent successfully to contact ${params.contactId}`
};
} catch (error) {
throw new Error(`Failed to send email: ${error}`);
}
}
/**
* SEARCH CONVERSATIONS
*/
private async searchConversations(params: MCPSearchConversationsParams): Promise<{ success: boolean; conversations: GHLConversation[]; total: number; message: string }> {
try {
const searchParams = {
locationId: this.ghlClient.getConfig().locationId,
contactId: params.contactId,
query: params.query,
status: params.status || 'all',
limit: params.limit || 20,
assignedTo: params.assignedTo
};
const response = await this.ghlClient.searchConversations(searchParams);
const data = response.data as GHLSearchConversationsResponse;
return {
success: true,
conversations: data.conversations,
total: data.total,
message: `Found ${data.conversations.length} conversations (${data.total} total)`
};
} catch (error) {
throw new Error(`Failed to search conversations: ${error}`);
}
}
/**
* GET CONVERSATION
*/
private async getConversation(params: MCPGetConversationParams): Promise<{ success: boolean; conversation: GHLConversation; messages: GHLMessage[]; hasMoreMessages: boolean; message: string }> {
try {
// Get conversation details
const conversationResponse = await this.ghlClient.getConversation(params.conversationId);
const conversation = conversationResponse.data as GHLConversation;
// Get messages
const messagesResponse = await this.ghlClient.getConversationMessages(
params.conversationId,
{
limit: params.limit || 20,
type: params.messageTypes?.join(',')
}
);
const messagesData = messagesResponse.data as GHLGetMessagesResponse;
return {
success: true,
conversation,
messages: messagesData.messages,
hasMoreMessages: messagesData.nextPage,
message: `Retrieved conversation with ${messagesData.messages.length} messages`
};
} catch (error) {
throw new Error(`Failed to get conversation: ${error}`);
}
}
/**
* CREATE CONVERSATION
*/
private async createConversation(params: MCPCreateConversationParams): Promise<{ success: boolean; conversationId: string; message: string }> {
try {
const response = await this.ghlClient.createConversation({
locationId: this.ghlClient.getConfig().locationId,
contactId: params.contactId
});
const result = response.data;
return {
success: true,
conversationId: result!.id,
message: `Conversation created successfully with contact ${params.contactId}`
};
} catch (error) {
throw new Error(`Failed to create conversation: ${error}`);
}
}
/**
* UPDATE CONVERSATION
*/
private async updateConversation(params: MCPUpdateConversationParams): Promise<{ success: boolean; conversation: GHLConversation; message: string }> {
try {
const updateData = {
locationId: this.ghlClient.getConfig().locationId,
starred: params.starred,
unreadCount: params.unreadCount
};
const response = await this.ghlClient.updateConversation(params.conversationId, updateData);
return {
success: true,
conversation: response.data!,
message: `Conversation updated successfully`
};
} catch (error) {
throw new Error(`Failed to update conversation: ${error}`);
}
}
/**
* GET RECENT MESSAGES
*/
private async getRecentMessages(params: { limit?: number; status?: string }): Promise<{ success: boolean; conversations: any[]; message: string }> {
try {
const status: 'all' | 'read' | 'unread' | 'starred' | 'recents' =
(params.status === 'all' || params.status === 'unread') ? params.status : 'unread';
const searchParams = {
locationId: this.ghlClient.getConfig().locationId,
limit: params.limit || 10,
status,
sortBy: 'last_message_date' as const,
sort: 'desc' as const
};
const response = await this.ghlClient.searchConversations(searchParams);
const data = response.data as GHLSearchConversationsResponse;
// Enhance with recent message details
const enhancedConversations = data.conversations.map(conv => ({
conversationId: conv.id,
contactName: conv.fullName || conv.contactName,
contactEmail: conv.email,
contactPhone: conv.phone,
lastMessageBody: conv.lastMessageBody,
lastMessageType: conv.lastMessageType,
unreadCount: conv.unreadCount,
starred: conv.starred
}));
return {
success: true,
conversations: enhancedConversations,
message: `Retrieved ${enhancedConversations.length} recent conversations`
};
} catch (error) {
throw new Error(`Failed to get recent messages: ${error}`);
}
}
private async deleteConversation(params: MCPDeleteConversationParams): Promise<{ success: boolean; message: string }> {
try {
const response = await this.ghlClient.deleteConversation(params.conversationId);
return {
success: true,
message: `Conversation deleted successfully`
};
} catch (error) {
throw new Error(`Failed to delete conversation: ${error}`);
}
}
private async getEmailMessage(params: MCPGetEmailMessageParams): Promise<{ success: boolean; emailMessage: GHLEmailMessage; message: string }> {
try {
const response = await this.ghlClient.getEmailMessage(params.emailMessageId);
const emailMessage = response.data as GHLEmailMessage;
return {
success: true,
emailMessage,
message: `Retrieved email message with ID ${params.emailMessageId}`
};
} catch (error) {
throw new Error(`Failed to get email message: ${error}`);
}
}
private async getMessage(params: MCPGetMessageParams): Promise<{ success: boolean; messageData: GHLMessage; message: string }> {
try {
const response = await this.ghlClient.getMessage(params.messageId);
const messageData = response.data as GHLMessage;
return {
success: true,
messageData,
message: `Retrieved message with ID ${params.messageId}`
};
} catch (error) {
throw new Error(`Failed to get message: ${error}`);
}
}
private async uploadMessageAttachments(params: MCPUploadMessageAttachmentsParams): Promise<{ success: boolean; uploadedFiles: any; message: string }> {
try {
const uploadData = {
conversationId: params.conversationId,
locationId: this.ghlClient.getConfig().locationId,
attachmentUrls: params.attachmentUrls
};
const response = await this.ghlClient.uploadMessageAttachments(uploadData);
const result = response.data as GHLUploadFilesResponse;
return {
success: true,
uploadedFiles: result.uploadedFiles,
message: `Attachments uploaded successfully to conversation ${params.conversationId}`
};
} catch (error) {
throw new Error(`Failed to upload message attachments: ${error}`);
}
}
private async updateMessageStatus(params: MCPUpdateMessageStatusParams): Promise<{ success: boolean; message: string }> {
try {
const statusData = {
status: params.status as 'delivered' | 'failed' | 'pending' | 'read',
error: params.error,
emailMessageId: params.emailMessageId,
recipients: params.recipients
};
const response = await this.ghlClient.updateMessageStatus(params.messageId, statusData);
return {
success: true,
message: `Message status updated to ${params.status} successfully`
};
} catch (error) {
throw new Error(`Failed to update message status: ${error}`);
}
}
private async addInboundMessage(params: MCPAddInboundMessageParams): Promise<{ success: boolean; messageId: string; conversationId: string; message: string }> {
try {
const messageData = {
type: params.type as 'SMS' | 'Email' | 'WhatsApp' | 'GMB' | 'IG' | 'FB' | 'Custom' | 'WebChat' | 'Live_Chat' | 'Call',
conversationId: params.conversationId,
conversationProviderId: params.conversationProviderId,
message: params.message,
attachments: params.attachments,
html: params.html,
subject: params.subject,
emailFrom: params.emailFrom,
emailTo: params.emailTo,
emailCc: params.emailCc,
emailBcc: params.emailBcc,
emailMessageId: params.emailMessageId,
altId: params.altId,
date: params.date,
call: params.call
};
const response = await this.ghlClient.addInboundMessage(messageData);
const result = response.data as GHLProcessMessageResponse;
return {
success: true,
messageId: result.messageId,
conversationId: result.conversationId,
message: `Inbound message added successfully to conversation ${params.conversationId}`
};
} catch (error) {
throw new Error(`Failed to add inbound message: ${error}`);
}
}
private async addOutboundCall(params: MCPAddOutboundCallParams): Promise<{ success: boolean; messageId: string; conversationId: string; message: string }> {
try {
const callData = {
type: 'Call' as const,
conversationId: params.conversationId,
conversationProviderId: params.conversationProviderId,
attachments: params.attachments,
altId: params.altId,
date: params.date,
call: {
to: params.to,
from: params.from,
status: params.status as 'pending' | 'completed' | 'answered' | 'busy' | 'no-answer' | 'failed' | 'canceled' | 'voicemail'
}
};
const response = await this.ghlClient.addOutboundCall(callData);
const result = response.data as GHLProcessMessageResponse;
return {
success: true,
messageId: result.messageId,
conversationId: result.conversationId,
message: `Outbound call added successfully to conversation ${params.conversationId}`
};
} catch (error) {
throw new Error(`Failed to add outbound call: ${error}`);
}
}
private async getMessageRecording(params: MCPGetMessageRecordingParams): Promise<{ success: boolean; recording: any; contentType: string; message: string }> {
try {
const response = await this.ghlClient.getMessageRecording(params.messageId);
const recording = response.data as GHLMessageRecordingResponse;
return {
success: true,
recording: recording.audioData,
contentType: recording.contentType,
message: `Retrieved call recording for message ${params.messageId}`
};
} catch (error) {
throw new Error(`Failed to get message recording: ${error}`);
}
}
private async getMessageTranscription(params: MCPGetMessageTranscriptionParams): Promise<{ success: boolean; transcriptions: any[]; message: string }> {
try {
const response = await this.ghlClient.getMessageTranscription(params.messageId);
const transcriptionData = response.data as GHLMessageTranscriptionResponse;
return {
success: true,
transcriptions: transcriptionData.transcriptions,
message: `Retrieved call transcription for message ${params.messageId}`
};
} catch (error) {
throw new Error(`Failed to get message transcription: ${error}`);
}
}
private async downloadTranscription(params: MCPDownloadTranscriptionParams): Promise<{ success: boolean; transcription: string; message: string }> {
try {
const response = await this.ghlClient.downloadMessageTranscription(params.messageId);
const transcription = response.data as string;
return {
success: true,
transcription,
message: `Downloaded call transcription for message ${params.messageId}`
};
} catch (error) {
throw new Error(`Failed to download transcription: ${error}`);
}
}
private async cancelScheduledMessage(params: MCPCancelScheduledMessageParams): Promise<{ success: boolean; status: number; message: string }> {
try {
const response = await this.ghlClient.cancelScheduledMessage(params.messageId);
const result = response.data as GHLCancelScheduledResponse;
return {
success: true,
status: result.status,
message: result.message || `Scheduled message cancelled successfully`
};
} catch (error) {
throw new Error(`Failed to cancel scheduled message: ${error}`);
}
}
private async cancelScheduledEmail(params: MCPCancelScheduledEmailParams): Promise<{ success: boolean; status: number; message: string }> {
try {
const response = await this.ghlClient.cancelScheduledEmail(params.emailMessageId);
const result = response.data as GHLCancelScheduledResponse;
return {
success: true,
status: result.status,
message: result.message || `Scheduled email cancelled successfully`
};
} catch (error) {
throw new Error(`Failed to cancel scheduled email: ${error}`);
}
}
private async liveChatTyping(params: MCPLiveChatTypingParams): Promise<{ success: boolean; message: string }> {
try {
const typingData = {
locationId: this.ghlClient.getConfig().locationId,
isTyping: params.isTyping,
visitorId: params.visitorId,
conversationId: params.conversationId
};
const response = await this.ghlClient.liveChatTyping(typingData);
const result = response.data as GHLLiveChatTypingResponse;
return {
success: result.success,
message: `Live chat typing indicator ${params.isTyping ? 'enabled' : 'disabled'} successfully`
};
} catch (error) {
throw new Error(`Failed to send live chat typing indicator: ${error}`);
}
}
}