/** * Follow Up Boss Integration for WORKWAY * * Real estate CRM integration for lead management, contact tracking, * and deal pipeline automation. Designed for real estate workflows - * lead capture, nurturing sequences, and showing follow-ups. * * @example * ```typescript * import { FollowUpBoss } from '@workwayco/integrations/follow-up-boss'; * * const fub = new FollowUpBoss({ * apiKey: 'fka_xxxxx', * systemName: 'MyApp', * systemKey: 'my-system-key', * }); * * // Create a new lead from inquiry * await fub.createLead({ * firstName: 'John', * lastName: 'Smith', * emails: ['john@example.com'], * phones: ['555-555-5555'], * source: 'Website', * message: 'Looking for homes under $500k', * }); * * // Get today's follow-ups * const tasks = await fub.getTodaysTasks(); * ``` */ import { ActionResult, type ActionCapabilities } from '@workwayco/sdk'; import { BaseAPIClient } from '../core/index.js'; /** * Follow Up Boss configuration */ export interface FollowUpBossConfig { /** API Key (from Admin → API screen) */ apiKey: string; /** System name for X-System header */ systemName: string; /** System key for X-System-Key header */ systemKey: string; /** Optional: Override API endpoint (for testing) */ apiUrl?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; } /** * Follow Up Boss person (contact/lead) */ export interface FUBPerson { id: number; created: string; updated: string; firstName: string; lastName: string; stage: FUBStage; source: string; sourceUrl?: string; contacted: boolean; price?: number; assignedTo?: number; assignedUserId?: number; collaborators?: number[]; tags?: string[]; emails?: FUBEmail[]; phones?: FUBPhone[]; addresses?: FUBAddress[]; background?: string; claims?: string; lastActivity?: string; assignedPondId?: number; } /** * Contact stages in Follow Up Boss */ export type FUBStage = 'Lead' | 'Active' | 'Past Client' | 'Inactive' | 'Trash'; /** * Email object */ export interface FUBEmail { value: string; type?: 'home' | 'work' | 'other'; isPrimary?: boolean; } /** * Phone object */ export interface FUBPhone { value: string; type?: 'home' | 'work' | 'mobile' | 'fax' | 'other'; isPrimary?: boolean; } /** * Address object */ export interface FUBAddress { street?: string; city?: string; state?: string; code?: string; country?: string; type?: 'home' | 'work' | 'mailing' | 'property' | 'other'; } /** * Follow Up Boss deal */ export interface FUBDeal { id: number; created: string; updated: string; name: string; stage: string; stageId: number; pipelineId: number; price?: number; closeDate?: string; closedWon?: boolean; assignedUserId?: number; people?: number[]; properties?: FUBProperty[]; customFields?: Record; } /** * Property associated with a deal */ export interface FUBProperty { street?: string; city?: string; state?: string; code?: string; mlsNumber?: string; price?: number; type?: 'buyer' | 'seller' | 'rental' | 'other'; } /** * Follow Up Boss task */ export interface FUBTask { id: number; created: string; updated: string; name: string; dueDate: string; completed: boolean; completedAt?: string; assignedUserId: number; personId?: number; dealId?: number; description?: string; } /** * Follow Up Boss note */ export interface FUBNote { id: number; created: string; updated: string; personId: number; subject?: string; body: string; isHtml: boolean; userId: number; } /** * Follow Up Boss appointment */ export interface FUBAppointment { id: number; created: string; updated: string; title: string; description?: string; startTime: string; endTime: string; assignedUserId: number; personId?: number; dealId?: number; location?: string; outcomeId?: number; } /** * Follow Up Boss user */ export interface FUBUser { id: number; email: string; firstName: string; lastName: string; role: string; active: boolean; } /** * Event for lead submission */ export interface FUBEvent { source: string; system: string; type: string; message?: string; description?: string; person: { firstName?: string; lastName?: string; emails?: Array<{ value: string; }>; phones?: Array<{ value: string; }>; tags?: string[]; source?: string; }; property?: { street?: string; city?: string; state?: string; code?: string; mlsNumber?: string; price?: number; type?: string; forRent?: boolean; url?: string; }; } /** * Webhook event from Follow Up Boss */ export interface FUBWebhookEvent { event: 'peopleCreated' | 'peopleUpdated' | 'peopleDeleted' | 'peopleTagsCreated' | 'peopleTagsDeleted' | 'notesCreated' | 'notesUpdated' | 'notesDeleted' | 'tasksCreated' | 'tasksUpdated' | 'tasksDeleted'; data: Record; timestamp: string; } /** * Paginated response */ export interface FUBPaginatedResponse { people?: T[]; deals?: T[]; tasks?: T[]; notes?: T[]; appointments?: T[]; users?: T[]; _metadata: { collection: string; offset: number; limit: number; total: number; }; } export interface ListPeopleOptions { /** Filter by stage */ stage?: FUBStage; /** Filter by source */ source?: string; /** Filter by tag */ tag?: string; /** Filter by assigned user */ assignedUserId?: number; /** Sort field */ sort?: string; /** Results limit (default: 25, max: 100) */ limit?: number; /** Offset for pagination */ offset?: number; } export interface CreatePersonOptions { firstName: string; lastName?: string; emails?: string[]; phones?: string[]; stage?: FUBStage; source?: string; tags?: string[]; assignedUserId?: number; background?: string; price?: number; } export interface UpdatePersonOptions { firstName?: string; lastName?: string; emails?: string[]; phones?: string[]; stage?: FUBStage; source?: string; tags?: string[]; assignedUserId?: number; background?: string; price?: number; } export interface CreateLeadOptions { firstName: string; lastName?: string; emails?: string[]; phones?: string[]; source: string; message?: string; tags?: string[]; propertyStreet?: string; propertyCity?: string; propertyState?: string; propertyMls?: string; propertyPrice?: number; propertyType?: 'buyer' | 'seller' | 'rental'; } export interface CreateNoteOptions { personId: number; body: string; subject?: string; isHtml?: boolean; } export interface CreateTaskOptions { name: string; dueDate: string; assignedUserId: number; personId?: number; dealId?: number; description?: string; } export interface ListTasksOptions { /** Filter by completed status */ completed?: boolean; /** Filter by assigned user */ assignedUserId?: number; /** Filter by person */ personId?: number; /** Filter tasks due before this date */ dueBefore?: string; /** Filter tasks due after this date */ dueAfter?: string; /** Results limit */ limit?: number; /** Offset */ offset?: number; } export interface CreateDealOptions { name: string; pipelineId: number; stageId: number; price?: number; closeDate?: string; assignedUserId?: number; people?: number[]; properties?: FUBProperty[]; } export interface ListDealsOptions { /** Filter by pipeline */ pipelineId?: number; /** Filter by stage */ stageId?: number; /** Filter by assigned user */ assignedUserId?: number; /** Filter by person */ personId?: number; /** Results limit */ limit?: number; /** Offset */ offset?: number; } /** * Follow Up Boss API Client * * Real estate CRM for lead management, contact tracking, and deal pipelines. */ export declare class FollowUpBoss extends BaseAPIClient { private readonly systemName; private readonly systemKey; /** * Action capabilities for workflow SDK integration */ static readonly capabilities: ActionCapabilities; constructor(config: FollowUpBossConfig); /** * Override request to add system headers and use Basic Auth */ protected request(method: string, path: string, body?: unknown): Promise; /** * List people (contacts/leads) */ listPeople(options?: ListPeopleOptions): Promise>; /** * Get a person by ID */ getPerson(personId: number): Promise>; /** * Create a new person (contact) */ createPerson(options: CreatePersonOptions): Promise>; /** * Update a person */ updatePerson(personId: number, options: UpdatePersonOptions): Promise>; /** * Create a new lead via the Events API * * This is the preferred method for submitting new leads from external sources. * It triggers Follow Up Boss's lead routing and automation rules. */ createLead(options: CreateLeadOptions): Promise>; /** * Get new leads from the last N days * * Zuhandenheit: "New leads that need attention" not "filter by created date" */ getNewLeads(days?: number): Promise>; /** * Get leads that haven't been contacted yet * * Zuhandenheit: "Leads waiting for first contact" not "filter by contacted flag" */ getUncontactedLeads(): Promise>; /** * Get hot leads (high price, recent activity) * * Zuhandenheit: "Leads likely to convert" not "filter by price and date" */ getHotLeads(minPrice?: number): Promise>; /** * Create a note on a contact */ createNote(options: CreateNoteOptions): Promise>; /** * List notes for a contact */ listNotes(personId: number, limit?: number): Promise>; /** * Create a task */ createTask(options: CreateTaskOptions): Promise>; /** * List tasks */ listTasks(options?: ListTasksOptions): Promise>; /** * Complete a task */ completeTask(taskId: number): Promise>; /** * Get tasks due today * * Zuhandenheit: "What needs attention today" not "filter by due date" */ getTodaysTasks(userId?: number): Promise>; /** * Get overdue tasks * * Zuhandenheit: "Tasks that slipped through" not "filter by past due date" */ getOverdueTasks(userId?: number): Promise>; /** * Create a deal */ createDeal(options: CreateDealOptions): Promise>; /** * List deals */ listDeals(options?: ListDealsOptions): Promise>; /** * Get a deal by ID */ getDeal(dealId: number): Promise>; /** * Update deal stage */ updateDealStage(dealId: number, stageId: number): Promise>; /** * Close a deal as won */ closeDealWon(dealId: number, closeDate?: string): Promise>; /** * Get current user (me) */ getMe(): Promise>; /** * List users in the account */ listUsers(): Promise>; /** * Verify webhook signature * * Follow Up Boss webhooks use a simple shared secret verification */ static verifyWebhook(payload: string, signature: string, secret: string): boolean; /** * Parse webhook payload */ static parseWebhook(payload: string): FUBWebhookEvent; } /** * Convert Follow Up Boss person to StandardContact */ export declare function toStandardContact(person: FUBPerson): { id: string; name: string; email: string | undefined; phone: string | undefined; source: "follow-up-boss"; raw: FUBPerson; }; /** * Convert Follow Up Boss task to StandardTask */ export declare function toStandardTask(task: FUBTask): { id: string; title: string; description: string | undefined; status: string; dueDate: string; source: "follow-up-boss"; raw: FUBTask; }; //# sourceMappingURL=index.d.ts.map