import { GHLClient } from '../client'; import { GHLContact, CreateContactDTO, UpdateContactDTO, GHLPaginatedResponse } from '@/types/ghl'; export class ContactsService { constructor(private client: GHLClient) {} // Get all contacts with pagination async getAll(params?: { limit?: number; offset?: number; query?: string; locationId?: string; }): Promise> { const searchParams: Record = { locationId: params?.locationId || this.client.locationID, limit: String(params?.limit || 20), }; if (params?.offset) searchParams.startAfterId = String(params.offset); if (params?.query) searchParams.query = params.query; // v1 API returns { contacts: [...], meta: {...} } const response = await this.client.get<{ contacts: GHLContact[]; meta: any }>('/contacts/', searchParams); // Normalize to { data: [...], meta: {...} } format return { data: response.contacts || [], meta: response.meta, }; } // Get a single contact by ID async getById(contactId: string): Promise { // v1 API returns { contact: {...} } const response = await this.client.get<{ contact: GHLContact }>(`/contacts/${contactId}`); return response.contact; } // Create a new contact async create(data: CreateContactDTO): Promise { return this.client.post('/contacts/', { ...data, locationId: this.client.locationID, }); } // Update an existing contact async update(contactId: string, data: UpdateContactDTO): Promise { return this.client.put(`/contacts/${contactId}`, data); } // Delete a contact async delete(contactId: string): Promise { await this.client.delete(`/contacts/${contactId}`); } // Search contacts async search(query: string, limit = 20): Promise> { return this.getAll({ query, limit }); } // Add tags to a contact async addTags(contactId: string, tags: string[]): Promise { return this.client.post(`/contacts/${contactId}/tags`, { tags }); } // Remove tags from a contact async removeTags(contactId: string, tags: string[]): Promise { return this.client.delete(`/contacts/${contactId}/tags`); } // Add contact to a workflow async addToWorkflow(contactId: string, workflowId: string): Promise { await this.client.post(`/contacts/${contactId}/workflow/${workflowId}`, {}); } // Remove contact from a workflow async removeFromWorkflow(contactId: string, workflowId: string): Promise { await this.client.delete(`/contacts/${contactId}/workflow/${workflowId}`); } // Get contact by email async getByEmail(email: string): Promise { const result = await this.search(email, 1); return result.data?.[0] || null; } // Get contact by phone async getByPhone(phone: string): Promise { const result = await this.search(phone, 1); return result.data?.[0] || null; } // Bulk create contacts async bulkCreate(contacts: CreateContactDTO[]): Promise<{ created: number; errors: any[] }> { const results = { created: 0, errors: [] as any[] }; for (const contact of contacts) { try { await this.create(contact); results.created++; } catch (error) { results.errors.push({ contact, error }); } } return results; } // Update contact's custom field value async updateCustomField(contactId: string, fieldKey: string, value: any): Promise { return this.update(contactId, { customFields: [{ key: fieldKey, value }] } as any); } }