- Build complete Next.js CRM for commercial real estate - Add authentication with JWT sessions and role-based access - Add GoHighLevel API integration for contacts, conversations, opportunities - Add AI-powered Control Center with tool calling - Add Setup page with onboarding checklist (/setup) - Add sidebar navigation with Setup menu item - Fix type errors in onboarding API, GHL services, and control center tools - Add Prisma schema with SQLite for local development - Add UI components with clay morphism design system Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import { GHLClient } from '../client';
|
|
import { GHLWorkflow } from '@/types/ghl';
|
|
|
|
export interface WorkflowSearchParams {
|
|
locationId?: string;
|
|
status?: 'active' | 'inactive' | 'all';
|
|
}
|
|
|
|
export class WorkflowsService {
|
|
constructor(private client: GHLClient) {}
|
|
|
|
// Get all workflows
|
|
async getAll(params?: WorkflowSearchParams): Promise<GHLWorkflow[]> {
|
|
const searchParams: Record<string, string> = {
|
|
locationId: params?.locationId || this.client.locationID,
|
|
};
|
|
|
|
const response = await this.client.get('/workflows/', searchParams);
|
|
return (response as any).workflows || [];
|
|
}
|
|
|
|
// Get a workflow by ID
|
|
async getById(workflowId: string): Promise<GHLWorkflow> {
|
|
return this.client.get(`/workflows/${workflowId}`);
|
|
}
|
|
|
|
// Add a contact to a workflow (trigger the workflow for them)
|
|
async addContactToWorkflow(workflowId: string, contactId: string): Promise<void> {
|
|
await this.client.post(`/contacts/${contactId}/workflow/${workflowId}`, {});
|
|
}
|
|
|
|
// Remove a contact from a workflow
|
|
async removeContactFromWorkflow(workflowId: string, contactId: string): Promise<void> {
|
|
await this.client.delete(`/contacts/${contactId}/workflow/${workflowId}`);
|
|
}
|
|
|
|
// Get active workflows
|
|
async getActive(): Promise<GHLWorkflow[]> {
|
|
const all = await this.getAll();
|
|
return all.filter(w => w.status === 'active');
|
|
}
|
|
|
|
// Get workflow by name
|
|
async getByName(name: string): Promise<GHLWorkflow | undefined> {
|
|
const all = await this.getAll();
|
|
return all.find(w => w.name.toLowerCase() === name.toLowerCase());
|
|
}
|
|
|
|
// Trigger a workflow for multiple contacts
|
|
async triggerForContacts(workflowId: string, contactIds: string[]): Promise<{
|
|
success: string[];
|
|
failed: { contactId: string; error: string }[];
|
|
}> {
|
|
const result = { success: [] as string[], failed: [] as { contactId: string; error: string }[] };
|
|
|
|
for (const contactId of contactIds) {
|
|
try {
|
|
await this.addContactToWorkflow(workflowId, contactId);
|
|
result.success.push(contactId);
|
|
} catch (error) {
|
|
result.failed.push({
|
|
contactId,
|
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
});
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|