Litelead-mcp

getCustomerContactById Tool

Overview

The getCustomerContactById tool retrieves a single contact record by its document ID for a specific customer from the Firebase/Firestore database.

Location

tools/getCustomerContactById.js

Description

Retrieves a specific contact by customer ID and contact ID. The contact is retrieved from the Firestore path: /Accounts/{accountId}/Customers/{customerId}/Contacts/{contactId}.

Input Schema

{
  customerId: string;  // REQUIRED: Customer document ID
  contactId: string;   // REQUIRED: Contact document ID
}

Parameters

Parameter Type Required Default Description
customerId string Yes - Firestore document ID of the customer
contactId string Yes - Firestore document ID of the contact

Output Schema

{
  contact: Contact | null;
}

Contact Object

{
  id: string;                        // Firestore document ID
  path: string;                      // Full Firestore path
  contactId: number;                 // Unique contact ID
  createdAt: string | Date;          // Creation timestamp
  createdBy: string;                 // Creator user ID
  customer: string;                  // Customer reference path
  email: string;                     // Contact email address
  firstName: string;                 // First name
  greeting: string;                  // Greeting/salutation
  imported: boolean;                 // Whether contact was imported
  lastName: string;                  // Last name
  mailchimp: {
    id: string | null;               // Mailchimp ID if synced
  };
  metadata: Record<string, any>;     // Additional metadata
  mobilePhone: string;               // Mobile phone number
  opt_out_email?: boolean;           // Email opt-out status
  opt_out_letter?: boolean;          // Letter opt-out status
  ownedBy: string;                   // Owner user ID
  tags: any[];                       // Contact tags
  telePhone: string;                 // Telephone number
}

Usage Examples

Basic Usage

// Get a specific contact for a customer
const result = await getCustomerContactById(context, {
  customerId: "customer123",
  contactId: "contact456"
});

if (result.contact) {
  console.log(result.contact.firstName, result.contact.lastName);
  console.log(result.contact.email);
} else {
  console.log("Contact not found");
}

Checking if Contact Exists

const result = await getCustomerContactById(context, {
  customerId: "customer123",
  contactId: "contact456"
});

if (result.contact === null) {
  console.log("Contact does not exist for this customer");
}

Implementation Details

Data Transformation

The tool transforms the Firestore document by:

  1. Adding the document id and full path
  2. Converting createdAt timestamp to Date object
  3. Preserving all other fields as-is
const data = docSnap.data();
return {
  contact: {
    id: docSnap.id,
    path: docSnap.ref.path,
    ...data,
    createdAt: safeToDate(data.createdAt) || data.createdAt,
  },
};

Validation

The tool validates that both required parameters are provided:

if (!customerId) {
  throw new Error("The 'customerId' parameter is required.");
}

if (!contactId) {
  throw new Error("The 'contactId' parameter is required.");
}

Not Found Handling

If the contact document doesn’t exist, the tool returns { contact: null } instead of throwing an error.

Error Handling

Common Errors

Error Cause Solution
“The ‘customerId’ parameter is required.” Missing customerId Provide customerId in params
“The ‘contactId’ parameter is required.” Missing contactId Provide contactId in params
“Failed to fetch contact with id [contactId] for customer [customerId].” Firestore error Check Firebase connection and permissions

Error Response

Errors are logged with both IDs and re-thrown:

catch (error) {
  console.error(
    `Error fetching contact with id ${contactId} for customer ${customerId}:`,
    error
  );
  throw new Error(
    `Failed to fetch contact with id ${contactId} for customer ${customerId}.`
  );
}

Performance Considerations

  1. Direct Document Access: Uses getDoc() for efficient single document retrieval
  2. Subcollection Query: Efficiently navigates the nested collection structure
  3. Indexed Reads: Document ID lookups are always indexed

Firestore Collection Structure

/Accounts/{accountId}/Customers/{customerId}/Contacts/{contactId}
  - contactId: number
  - createdAt: timestamp
  - createdBy: string
  - customer: string (reference)
  - email: string
  - firstName: string
  - greeting: string
  - imported: boolean
  - lastName: string
  - mailchimp: { id: string | null }
  - metadata: object
  - mobilePhone: string
  - opt_out_email: boolean
  - opt_out_letter: boolean
  - ownedBy: string
  - tags: array
  - telePhone: string

See Also