/** * Contacts resource module for IT Glue API * * Provides methods to interact with the /contacts endpoint. * Contacts represent individuals associated with organizations in your IT documentation system. * This resource allows you to manage contact information, including personal details, * communication preferences, and organizational relationships. * * ## Related Resources * Contacts are commonly used with: * - {@link Organizations} - Parent organizations that contacts belong to * - {@link ContactTypes} - Classify contacts by role (employee, vendor, client) * - {@link Locations} - Physical locations where contacts are based * - {@link Configurations} - IT assets and systems that contacts are responsible for * - {@link Passwords} - Credentials associated with contact accounts * - {@link Documents} - Documentation created or owned by contacts * - {@link RelatedItems} - Create relationships between contacts and other resources * - {@link Tags} - Categorize and label contacts for better organization * - {@link Attachments} - Store files and documents related to contacts * * @see {@link Organizations.getContacts} for retrieving contacts by organization * @see {@link Organizations#get} for retrieving the parent organization * @see {@link ContactTypes#list} for retrieving available contact types * @see {@link Configurations#list} for retrieving configurations assigned to contacts * * @example * import { ITGlueClient } from '../client'; * import { Contacts } from './resources/contacts'; * * const client = new ITGlueClient({ apiKey: 'your-api-key' }); * const contacts = new Contacts(client); * * // List contacts * const list = await contacts.list(); * * // Get a single contact * const contact = await contacts.get('456'); * * // Create a new contact * const created = await contacts.create({ * data: { * type: 'contacts', * attributes: { * 'first-name': 'John', * 'last-name': 'Doe', * 'contact-type-name': 'Employee' * } * } * }); * * // Update a contact * const updated = await contacts.update('456', { * data: { * type: 'contacts', * attributes: { 'first-name': 'Jane' } * } * }); * * // Delete a contact * await contacts.delete('456'); * * @category Organizations */ import { ITGlueClient } from '../client'; import { QueryUtilOptions, QueryParams, RequestBody, BaseListResponse, BaseItemResponse, ContactResource } from '../types'; export declare class Contacts { private client; private basePath; private paginationUtil; /** * Create a Contacts resource instance * @param {ITGlueClient} client - ITGlueClient instance */ constructor(client: ITGlueClient); /** * List all contacts * @param {QueryUtilOptions} [options] - Optional query parameters (filter, sort, page, etc.) * @param {boolean} [allPages=false] - If true, fetches all pages automatically * @returns {Promise>} List of contacts and pagination metadata * @example * // Basic usage - get first page of contacts * const results = await client.contacts.list(); * console.log(`Found ${results.data.length} contacts`); * console.log('Total pages:', results.meta.pagination.total_pages); * * @example * // Advanced usage with pagination and sorting * const results = await client.contacts.list({ * page: { number: 2, size: 50 }, * sort: 'last-name', // Sort by last name alphabetically * include: ['contact_type', 'organization', 'location'] // Include related data * }); * * @example * // Filtering contacts by organization and type * const managers = await client.contacts.list({ * filter: { * organization_id: '123', * 'contact-type-name': 'Manager' * }, * sort: ['last-name', 'first-name'] * }); * * @example * // Get all contacts across multiple pages * const allContacts = await client.contacts.list({}, true); // allPages = true * console.log(`Retrieved all ${allContacts.data.length} contacts`); * * @example * // Manual pagination for contact directory * async function getAllContactsByOrganization(orgId) { * let page = 1; * let allContacts = []; * let hasMore = true; * * while (hasMore) { * const response = await client.contacts.list({ * filter: { organization_id: orgId }, * page: { number: page, size: 100 }, * sort: ['last-name', 'first-name'] * }); * * allContacts = [...allContacts, ...response.data]; * hasMore = response.meta.pagination.total_pages > page; * page++; * } * * return allContacts; * } * * @example * // Error handling for list operations * try { * const results = await client.contacts.list({ * filter: { invalid_field: 'value' } * }); * } catch (error) { * if (error.response?.status === 400) { * console.log('Invalid filter parameters:', error.response.data.errors); * } else if (error.response?.status === 401) { * console.log('Authentication failed - check your API key'); * } else if (error.response?.status === 403) { * console.log('Access denied - insufficient permissions to list contacts'); * } else { * console.log('Request failed:', error.message); * } * } */ list(options?: QueryUtilOptions, allPages?: boolean): Promise>; /** * Get a single contact by ID * @param {string} id - Contact ID * @param {QueryParams} [params] - Optional query parameters * @returns {Promise>} Contact resource * @example * // Basic usage - get contact by ID * const contact = await client.contacts.get('456'); * console.log('Contact name:', `${contact.data.attributes['first-name']} ${contact.data.attributes['last-name']}`); * console.log('Title:', contact.data.attributes.title); * console.log('Contact type:', contact.data.attributes['contact-type-name']); * * @example * // Get contact with related data included * const contactWithRelated = await client.contacts.get('456', { * include: ['contact_type', 'organization', 'location'] * }); * * // Access included data * const included = contactWithRelated.included || []; * const organization = included.find(item => item.type === 'organizations'); * const contactType = included.find(item => item.type === 'contact_types'); * * @example * // Error handling for get operations * try { * const contact = await client.contacts.get('invalid-id'); * } catch (error) { * if (error.response?.status === 404) { * console.log('Contact not found'); * } else if (error.response?.status === 403) { * console.log('Access denied - insufficient permissions'); * } else { * console.log('Error retrieving contact:', error.message); * } * } * * @example * // Safe get with existence check * async function safeGetContact(id) { * try { * const contact = await client.contacts.get(id); * return contact.data; * } catch (error) { * if (error.response?.status === 404) { * return null; // Contact doesn't exist * } * throw error; // Re-throw other errors * } * } * @see * {@link Organizations#get} - Get specific organization details * {@link Organizations#list} - List organizations that this contact belongs to * {@link ContactTypes#get} - Get specific contacttype details * {@link ContactTypes#list} - List contacttypes related to contacts */ get(id: string, params?: QueryParams): Promise>; /** * Create a new contact * @param {RequestBody} data - Contact data (must be formatted according to JSON:API spec) * @returns {Promise>} Created contact resource * @example * // Basic contact creation * const newContact = await client.contacts.create({ * data: { * type: 'contacts', * attributes: { * 'first-name': 'John', * 'last-name': 'Doe', * 'contact-type-name': 'Employee' * }, * relationships: { * organization: { * data: { type: 'organizations', id: '123' } * } * } * } * }); * * console.log('Created contact with ID:', newContact.data.id); * * @example * // Advanced contact creation with comprehensive information * const newContact = await client.contacts.create({ * data: { * type: 'contacts', * attributes: { * 'first-name': 'Jane', * 'last-name': 'Smith', * 'contact-type-name': 'Manager', * 'title': 'IT Director', * 'notes': 'Primary IT contact for infrastructure projects', * 'contact-emails': [ * { * 'value': 'jane.smith@company.com', * 'primary': true, * 'label-name': 'Work' * }, * { * 'value': 'j.smith@company.com', * 'primary': false, * 'label-name': 'Work Alt' * } * ], * 'contact-phones': [ * { * 'value': '+1-555-123-4567', * 'primary': true, * 'label-name': 'Work' * }, * { * 'value': '+1-555-987-6543', * 'primary': false, * 'label-name': 'Mobile' * } * ] * }, * relationships: { * organization: { * data: { type: 'organizations', id: '123' } * } * } * } * }); * * @example * // Bulk contact creation with error handling * async function createMultipleContacts(contactList) { * const results = []; * const errors = []; * * for (const contactData of contactList) { * try { * const created = await client.contacts.create({ * data: { * type: 'contacts', * attributes: contactData, * relationships: { * organization: { * data: { type: 'organizations', id: contactData.organizationId } * } * } * } * }); * results.push(created.data); * } catch (error) { * errors.push({ contactData, error: error.message }); * } * } * * return { results, errors }; * } * * @example * // Error handling for contact creation * try { * const created = await client.contacts.create({ * data: { * type: 'contacts', * attributes: { * // Missing required first-name field * 'last-name': 'Doe', * 'contact-type-name': 'Employee' * } * } * }); * } catch (error) { * if (error.response?.status === 422) { * console.log('Validation errors:'); * error.response.data.errors.forEach(err => { * console.log(`- ${err.detail} (${err.source?.pointer})`); * }); * } else if (error.response?.status === 403) { * console.log('Permission denied - cannot create contact'); * } else { * console.log('Creation failed:', error.message); * } * } * @see * {@link Organizations#create} - Create new organization * {@link Organizations#list} - List organizations that this contact belongs to * {@link ContactTypes#create} - Create new contacttype * {@link ContactTypes#list} - List contacttypes related to contacts */ create(data: RequestBody): Promise>; /** * Update a contact by ID * @param {string} id - Contact ID * @param {RequestBody} data - Updated contact data (must be formatted according to JSON:API spec) * @returns {Promise>} Updated contact resource * @example * // Basic update - modify contact details * const updatedContact = await client.contacts.update('456', { * data: { * type: 'contacts', * attributes: { * 'first-name': 'Jane', * 'title': 'Senior IT Manager' * } * } * }); * * console.log('Contact updated successfully'); * * @example * // Update contact with new communication details * const updatedContact = await client.contacts.update('456', { * data: { * type: 'contacts', * attributes: { * 'first-name': 'Jane', * 'last-name': 'Johnson', * 'title': 'Senior IT Manager', * 'notes': 'Recently promoted to senior position', * 'contact-emails': [ * { * 'value': 'jane.johnson@company.com', * 'primary': true, * 'label-name': 'Work' * } * ], * 'contact-phones': [ * { * 'value': '+1-555-123-9999', * 'primary': true, * 'label-name': 'Work' * } * ] * } * } * }); * * @example * // Conditional update based on current state * async function conditionalUpdateContact(id, updates) { * try { * // First, get current state * const current = await client.contacts.get(id); * * // Check if update is needed * const needsUpdate = Object.keys(updates).some( * key => current.data.attributes[key] !== updates[key] * ); * * if (!needsUpdate) { * console.log('Contact is already up to date'); * return current; * } * * // Perform update * return await client.contacts.update(id, { * data: { * type: 'contacts', * attributes: updates * } * }); * } catch (error) { * console.error('Update failed:', error.message); * throw error; * } * } * * @example * // Error handling for contact updates * try { * const updated = await client.contacts.update('456', { * data: { * type: 'contacts', * attributes: { * 'contact-emails': [ * { * 'value': 'invalid-email-format', * 'primary': true, * 'label-name': 'Work' * } * ] * } * } * }); * } catch (error) { * if (error.response?.status === 404) { * console.log('Contact not found'); * } else if (error.response?.status === 422) { * console.log('Validation failed:', error.response.data.errors); * } else if (error.response?.status === 409) { * console.log('Conflict - contact may have been modified by another user'); * } else { * console.log('Update failed:', error.message); * } * } * @see * {@link Organizations#update} - Update organization * {@link Organizations#get} - Get specific organization details * {@link ContactTypes#update} - Update contacttype * {@link ContactTypes#get} - Get specific contacttype details */ update(id: string, data: RequestBody): Promise>; /** * Delete a contact by ID * @param {string} id - Contact ID * @returns {Promise} * @example * // Basic deletion * await client.contacts.delete('456'); * console.log('Contact deleted successfully'); * * @example * // Safe deletion with confirmation * async function safeDeleteContact(id) { * try { * // First verify the contact exists * const contact = await client.contacts.get(id); * const fullName = `${contact.data.attributes['first-name']} ${contact.data.attributes['last-name']}`; * console.log(`Deleting contact: ${fullName}`); * * // Perform deletion * await client.contacts.delete(id); * console.log('Contact deleted successfully'); * return true; * } catch (error) { * if (error.response?.status === 404) { * console.log('Contact not found - may already be deleted'); * return false; * } * throw error; * } * } * * @example * // Bulk deletion with error handling * async function deleteMultipleContacts(contactIds) { * const results = []; * * for (const id of contactIds) { * try { * await client.contacts.delete(id); * results.push({ id, status: 'deleted' }); * } catch (error) { * results.push({ * id, * status: 'error', * error: error.response?.status === 404 ? 'not_found' : error.message * }); * } * } * * return results; * } * * @example * // Error handling for delete operations * try { * await client.contacts.delete('456'); * } catch (error) { * if (error.response?.status === 404) { * console.log('Contact not found - may already be deleted'); * } else if (error.response?.status === 403) { * console.log('Permission denied - cannot delete contact'); * } else if (error.response?.status === 409) { * console.log('Cannot delete - contact is referenced by other resources'); * } else { * console.log('Deletion failed:', error.message); * } * } * @see * {@link Organizations#list} - List organizations that this contact belongs to * {@link Organizations#get} - Get specific organization details * {@link ContactTypes#list} - List contacttypes related to contacts * {@link ContactTypes#get} - Get specific contacttype details */ delete(id: string): Promise; }