Skip to main content
Glama

mcp-google-sheets

new-contact.ts9.41 kB
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework'; import { httpClient, HttpMethod } from '@activepieces/pieces-common'; import { pollingHelper, DedupeStrategy, Polling } from '@activepieces/pieces-common'; import dayjs from 'dayjs'; import { fetchUsers, fetchTags, WEALTHBOX_API_BASE, handleApiError } from '../common'; const polling: Polling<any, any> = { strategy: DedupeStrategy.TIMEBASED, items: async ({ propsValue, lastFetchEpochMS, auth }) => { if (!auth) { throw new Error('Authentication is required'); } const searchParams = new URLSearchParams(); searchParams.append('limit', '100'); if (propsValue.contact_type) searchParams.append('contact_type', propsValue.contact_type); if (propsValue.type) searchParams.append('type', propsValue.type); if (propsValue.household_title) searchParams.append('household_title', propsValue.household_title); if (propsValue.assigned_to) searchParams.append('assigned_to', propsValue.assigned_to); const tagsFilter = propsValue.tags_filter; if (tagsFilter && Array.isArray(tagsFilter) && tagsFilter.length > 0) { tagsFilter.forEach((tag: string) => { searchParams.append('tags[]', tag); }); } if (propsValue.active !== undefined && propsValue.active !== '') { searchParams.append('active', propsValue.active); } if (propsValue.include_deleted) { searchParams.append('deleted', 'true'); } if (lastFetchEpochMS) { const lastFetchDate = dayjs(lastFetchEpochMS - 1000).toISOString(); searchParams.append('updated_since', lastFetchDate); } const queryString = searchParams.toString(); const url = queryString ? `${WEALTHBOX_API_BASE}/contacts?${queryString}` : `${WEALTHBOX_API_BASE}/contacts`; try { const response = await httpClient.sendRequest({ method: HttpMethod.GET, url: url, headers: { 'ACCESS_TOKEN': auth as unknown as string, 'Accept': 'application/json' } }); if (response.status >= 400) { handleApiError('poll new contacts', response.status, response.body); } const contacts = response.body.contacts || []; const newContacts = contacts.filter((contact: any) => { if (!lastFetchEpochMS) return true; const contactCreatedAt = dayjs(contact.created_at).valueOf(); return contactCreatedAt > lastFetchEpochMS; }); return newContacts.map((contact: any) => ({ epochMilliSeconds: dayjs(contact.created_at).valueOf(), data: contact })); } catch (error) { throw new Error(`Failed to poll new contacts: ${error instanceof Error ? error.message : 'Unknown error'}`); } } }; export const newContact = createTrigger({ name: 'new_contact', displayName: 'New Contact', description: 'Fires when a new contact is created', type: TriggerStrategy.POLLING, props: { contact_type: Property.StaticDropdown({ displayName: 'Contact Type', description: 'Only trigger for contacts of this type (optional)', required: false, options: { options: [ { label: 'Client', value: 'Client' }, { label: 'Past Client', value: 'Past Client' }, { label: 'Prospect', value: 'Prospect' }, { label: 'Vendor', value: 'Vendor' }, { label: 'Organization', value: 'Organization' } ] } }), type: Property.StaticDropdown({ displayName: 'Entity Type', description: 'Only trigger for contacts of this entity type (optional)', required: false, options: { options: [ { label: 'Person', value: 'person' }, { label: 'Household', value: 'household' }, { label: 'Organization', value: 'organization' }, { label: 'Trust', value: 'trust' } ] } }), household_title: Property.StaticDropdown({ displayName: 'Household Title', description: 'Only trigger for contacts with this household title (optional)', required: false, options: { options: [ { label: 'Head', value: 'Head' }, { label: 'Spouse', value: 'Spouse' }, { label: 'Partner', value: 'Partner' }, { label: 'Child', value: 'Child' }, { label: 'Grandchild', value: 'Grandchild' }, { label: 'Parent', value: 'Parent' }, { label: 'Grandparent', value: 'Grandparent' }, { label: 'Sibling', value: 'Sibling' }, { label: 'Other', value: 'Other' }, { label: 'Dependent', value: 'Dependent' } ] } }), assigned_to: Property.Dropdown({ displayName: 'Assigned To', description: 'Only trigger for contacts assigned to this user (optional)', required: false, refreshers: [], options: async ({ auth }) => { if (!auth) return { options: [] }; try { const users = await fetchUsers(auth as unknown as string); return { options: users.map((user: any) => ({ label: `${user.name} (${user.email})`, value: user.id })) }; } catch (error) { return { options: [], error: 'Failed to load users. Please check your authentication.' }; } } }), tags_filter: Property.MultiSelectDropdown({ displayName: 'Tags Filter', description: 'Only trigger for contacts with one of these tags (optional)', required: false, refreshers: ['auth'], options: async ({ auth }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Connect your Wealthbox account first' }; } try { const availableTags = await fetchTags(auth as unknown as string, 'Contact'); const tagOptions = availableTags.map((tag: any) => ({ label: tag.name, value: tag.name })); return { disabled: false, options: tagOptions, placeholder: tagOptions.length === 0 ? 'No tags available' : 'Select tags to filter by' }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { disabled: true, options: [], placeholder: `Error loading tags: ${errorMessage}` }; } } }), active: Property.StaticDropdown({ displayName: 'Active Status', description: 'Filter by active status', required: false, options: { options: [ { label: 'All Contacts', value: '' }, { label: 'Active Only', value: 'true' }, { label: 'Inactive Only', value: 'false' } ] } }), include_deleted: Property.Checkbox({ displayName: 'Include Deleted Contacts', description: 'Include contacts that have been deleted', required: false, defaultValue: false }) }, sampleData: { id: 1, creator: 1, created_at: '2015-05-24 10:00 AM -0400', updated_at: '2015-10-12 11:30 PM -0400', prefix: 'Mr.', first_name: 'Kevin', middle_name: 'James', last_name: 'Anderson', suffix: 'M.D.', nickname: 'Kev', job_title: 'CEO', twitter_name: 'kev.anderson', linkedin_url: 'linkedin.com/in/kanderson', background_information: 'Met Kevin at a conference.', birth_date: '1975-10-27', anniversary: '1998-11-29', client_since: '2002-05-21', assigned_to: 1, referred_by: 1, type: 'Person', gender: 'Male', contact_source: 'Referral', contact_type: 'Client', status: 'Active', marital_status: 'Married', important_information: 'Has 3 kids in college', personal_interests: 'Skiing: Downhill, Traveling', investment_objective: 'Income', time_horizon: 'Intermediate', risk_tolerance: 'Moderate', company_name: 'Acme Co.', tags: [ { id: 1, name: 'Clients' } ], street_addresses: [ { street_line_1: '155 12th Ave.', street_line_2: 'Apt 3B', city: 'New York', state: 'New York', zip_code: '10001', country: 'United States', principal: true, kind: 'Work', id: 1, address: '155 12th Ave., Apt 3B, New York, New York 10001, United States' } ], email_addresses: [ { id: 1, address: 'kevin.anderson@example.com', principal: true, kind: 'Work' } ], phone_numbers: [ { id: 1, address: '(555) 555-5555', principal: true, extension: '77', kind: 'Work' } ] }, onEnable: async (context) => { await pollingHelper.onEnable(polling, { store: context.store, propsValue: context.propsValue, auth: context.auth }); }, onDisable: async (context) => { await pollingHelper.onDisable(polling, { store: context.store, propsValue: context.propsValue, auth: context.auth }); }, run: async (context) => { return await pollingHelper.poll(polling, context); }, test: async (context) => { return await pollingHelper.test(polling, context); } });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server