Skip to main content
Glama
contacts.ts6.59 kB
import { AxiosInstance } from 'axios'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { ActiveCampaignContact } from '../types/index.js'; export class ContactTools { constructor(private apiClient: AxiosInstance) {} // Definir as ferramentas de contatos getTools(): Tool[] { return [ { name: 'get_contact_by_email', description: 'Busca um contato no ActiveCampaign pelo email', inputSchema: { type: 'object', properties: { email: { type: 'string', description: 'Email do contato a ser buscado', }, }, required: ['email'], }, }, { name: 'get_contact_by_id', description: 'Busca um contato no ActiveCampaign pelo ID', inputSchema: { type: 'object', properties: { contactId: { type: 'string', description: 'ID do contato a ser buscado', }, }, required: ['contactId'], }, }, { name: 'search_contacts', description: 'Busca contatos no ActiveCampaign com filtros', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Termo de busca (nome, email, etc.)', }, limit: { type: 'number', description: 'Limite de resultados (padrão: 20)', default: 20, }, }, required: ['query'], }, }, ]; } // Executar ferramenta de contato async executeTool(name: string, args: any) { switch (name) { case 'get_contact_by_email': return await this.getContactByEmail(args?.email as string); case 'get_contact_by_id': return await this.getContactById(args?.contactId as string); case 'search_contacts': return await this.searchContacts(args?.query as string, args?.limit as number); default: throw new Error(`Ferramenta de contato desconhecida: ${name}`); } } private async getContactByEmail(email: string) { try { const response = await this.apiClient.get('/api/3/contacts', { params: { email: email, include: 'fieldValues,tags,contactLists', }, }); const contacts = response.data.contacts; if (!contacts || contacts.length === 0) { return { content: [ { type: 'text', text: `Nenhum contato encontrado com o email: ${email}`, }, ], }; } const contact = await this.formatContactData(contacts[0]); return { content: [ { type: 'text', text: JSON.stringify(contact, null, 2), }, ], }; } catch (error) { throw new Error(`Erro ao buscar contato por email: ${error instanceof Error ? error.message : 'Erro desconhecido'}`); } } private async getContactById(contactId: string) { try { const response = await this.apiClient.get(`/api/3/contacts/${contactId}`, { params: { include: 'fieldValues,tags,contactLists', }, }); const contact = await this.formatContactData(response.data.contact); return { content: [ { type: 'text', text: JSON.stringify(contact, null, 2), }, ], }; } catch (error) { throw new Error(`Erro ao buscar contato por ID: ${error instanceof Error ? error.message : 'Erro desconhecido'}`); } } private async searchContacts(query: string, limit: number = 20) { try { const response = await this.apiClient.get('/api/3/contacts', { params: { search: query, limit: limit, include: 'fieldValues,tags,contactLists', }, }); const contacts = response.data.contacts || []; const formattedContacts = await Promise.all( contacts.map((contact: any) => this.formatContactData(contact)) ); return { content: [ { type: 'text', text: JSON.stringify({ total: contacts.length, contacts: formattedContacts, }, null, 2), }, ], }; } catch (error) { throw new Error(`Erro ao buscar contatos: ${error instanceof Error ? error.message : 'Erro desconhecido'}`); } } private async formatContactData(rawContact: any): Promise<ActiveCampaignContact> { const contact: ActiveCampaignContact = { id: rawContact.id, email: rawContact.email, firstName: rawContact.firstName || '', lastName: rawContact.lastName || '', phone: rawContact.phone || '', cdate: rawContact.cdate, udate: rawContact.udate, }; // Buscar valores de campos customizados if (rawContact.fieldValues) { try { const fieldsResponse = await this.apiClient.get('/api/3/fields'); const fields = fieldsResponse.data.fields || []; contact.fieldValues = rawContact.fieldValues.map((fv: any) => { const field = fields.find((f: any) => f.id === fv.field); return { field: field ? field.title : fv.field, value: fv.value, }; }); } catch (error) { console.error('Erro ao buscar campos customizados:', error); } } // Buscar tags if (rawContact.tags) { try { const tagsResponse = await this.apiClient.get('/api/3/tags'); const allTags = tagsResponse.data.tags || []; contact.tags = rawContact.tags.map((tagId: string) => { const tag = allTags.find((t: any) => t.id === tagId); return tag ? tag.tag : tagId; }); } catch (error) { console.error('Erro ao buscar tags:', error); } } // Buscar listas if (rawContact.contactLists) { try { const listsResponse = await this.apiClient.get('/api/3/lists'); const allLists = listsResponse.data.lists || []; contact.lists = rawContact.contactLists.map((cl: any) => { const list = allLists.find((l: any) => l.id === cl.list); return { list: list ? list.name : cl.list, status: cl.status, }; }); } catch (error) { console.error('Erro ao buscar listas:', error); } } return contact; } }

Implementation Reference

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/mmarqueti/activecampaign-mcp-server'

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