Skip to main content
Glama

mcp-google-sheets

props.ts25.3 kB
import { DropdownOption, DynamicPropsValue, OAuth2PropertyValue, PiecePropValueSchema, Property, } from '@activepieces/pieces-framework'; import { AuthenticationType, httpClient, HttpMethod, HttpRequest, } from '@activepieces/pieces-common'; import { WorkflowResponse, HubspotProperty, HubspotFieldType, ListBlogsResponse } from './types'; import { DEFAULT_COMPANY_PROPERTIES, DEFAULT_CONTACT_PROPERTIES, DEFAULT_DEAL_PROPERTIES, DEFAULT_LINE_ITEM_PROPERTIES, DEFAULT_PRODUCT_PROPERTIES, DEFAULT_TICKET_PROPERTIES, DEFAULT_TASK_PROPERTIES, OBJECT_TYPE, STANDARD_OBJECT_TYPES, } from './constants'; import { Client } from '@hubspot/api-client'; import { hubspotAuth } from '../../'; const buildEmptyList = ({ placeholder }: { placeholder: string }) => { return { disabled: true, options: [], placeholder, }; }; export function getDefaultPropertiesForObject(objectType: OBJECT_TYPE): string[] { switch (objectType) { case OBJECT_TYPE.CONTACT: return DEFAULT_CONTACT_PROPERTIES; case OBJECT_TYPE.DEAL: return DEFAULT_DEAL_PROPERTIES; case OBJECT_TYPE.TICKET: return DEFAULT_TICKET_PROPERTIES; case OBJECT_TYPE.COMPANY: return DEFAULT_COMPANY_PROPERTIES; case OBJECT_TYPE.PRODUCT: return DEFAULT_PRODUCT_PROPERTIES; case OBJECT_TYPE.LINE_ITEM: return DEFAULT_LINE_ITEM_PROPERTIES; case OBJECT_TYPE.TASK: return DEFAULT_TASK_PROPERTIES; default: return []; } } async function fetchOwnersOptions(accessToken: string): Promise<DropdownOption<string>[]> { const client = new Client({ accessToken: accessToken }); const limit = 100; const options: DropdownOption<string>[] = []; let after: string | undefined; do { const response = await client.crm.owners.ownersApi.getPage(undefined, after, limit); for (const owner of response.results) if (owner.email) { options.push({ label: owner.email, value: owner.id, }); } after = response.paging?.next?.after; } while (after); return options; } async function fetchUsersOptions(accessToken: string): Promise<DropdownOption<string>[]> { const client = new Client({ accessToken: accessToken }); const limit = 100; const options: DropdownOption<string>[] = []; let after: string | undefined; do { const response = await client.settings.users.usersApi.getPage(limit, after); for (const user of response.results) { if (user.email) { options.push({ label: user.email, value: user.id, }); } } after = response.paging?.next?.after; } while (after); return options; } async function fetchTeamsOptions(accessToken: string): Promise<DropdownOption<string>[]> { const client = new Client({ accessToken: accessToken }); const options: DropdownOption<string>[] = []; const response = await client.settings.users.teamsApi.getAll(); for (const team of response.results) { if (team.name) { options.push({ label: team.name, value: team.id, }); } } return options; } async function fetchCurrenciesOptions(accessToken: string): Promise<DropdownOption<string>[]> { const options: DropdownOption<string>[] = []; const response = await httpClient.sendRequest<{ results: Array<{ currencyCode: string; currencyName: string }>; }>({ method: HttpMethod.GET, url: 'https://api.hubapi.com/settings/v3/currencies/codes', authentication: { type: AuthenticationType.BEARER_TOKEN, token: accessToken, }, }); for (const currency of response.body.results) { options.push({ label: currency.currencyName, value: currency.currencyCode, }); } return options; } // async function fetchBusinessUnitsOptions(accessToken: string): Promise<DropdownOption<string>[]> { // const client = new Client({ accessToken: accessToken }); // const options: DropdownOption<string>[] = []; // const response = await client.settings.businessUnits.businessUnitApi.getByUserID() // for (const businessUnit of response.results) { // if (businessUnit.name) { // options.push({ // label: businessUnit.name, // value: businessUnit.id, // }); // } // } // return options; // } async function createReferencedPropertyDefinition( property: HubspotProperty, propertyDisplayName: string, accessToken: string, ) { let options: DropdownOption<string>[] = []; switch (property.referencedObjectType) { case 'OWNER': options = await fetchOwnersOptions(accessToken); break; default: return null; } return Property.StaticDropdown({ displayName: propertyDisplayName, required: false, options: { disabled: false, options, }, }); } function createPropertyDefinition(property: HubspotProperty, propertyDisplayName: string) { switch (property.fieldType) { case HubspotFieldType.BooleanCheckBox: return Property.StaticDropdown({ displayName: propertyDisplayName, required: true, defaultValue:'', options:{ disabled:false, options:[ { label:'Yes', value:'true' }, { label:'No', value:'false' }, { label:"Unanswered", value:'' } ] } }); case HubspotFieldType.Date: return Property.DateTime({ displayName: propertyDisplayName, description: property.type === 'date' ? 'Provide date in YYYY-MM-DD format' : '', required: false, }); case HubspotFieldType.Number: return Property.Number({ displayName: propertyDisplayName, required: false, }); case HubspotFieldType.PhoneNumber: case HubspotFieldType.Text: return Property.ShortText({ displayName: propertyDisplayName, required: false, }); case HubspotFieldType.TextArea: case HubspotFieldType.Html: return Property.LongText({ displayName: propertyDisplayName, required: false, }); case HubspotFieldType.CheckBox: return Property.StaticMultiSelectDropdown({ displayName: propertyDisplayName, required: false, options: { disabled: false, options: property.options ? property.options.map((option) => { return { label: option.label, value: option.value, }; }) : [], }, }); case HubspotFieldType.Select: case HubspotFieldType.Radio: return Property.StaticDropdown({ displayName: propertyDisplayName, required: false, options: { options: property.options ? property.options.map((option) => { return { label: option.label, value: option.value, }; }) : [], }, }); default: return null; } } async function retrieveObjectProperties( auth: PiecePropValueSchema<typeof hubspotAuth>, objectType: string, excludedProperties: string[] = [], ) { const client = new Client({ accessToken: auth.access_token }); // Fetch property groups const propertyGroups = await client.crm.properties.groupsApi.getAll(objectType); const groupLabels = propertyGroups.results.reduce((map, group) => { map[group.name] = group.label; return map; }, {} as Record<string, string>); // Fetch all properties for the given object type const allProperties = await client.crm.properties.coreApi.getAll(objectType); const props: DynamicPropsValue = {}; for (const property of allProperties.results) { // skip read only properties if ( excludedProperties.includes(property.name) || property.modificationMetadata?.readOnlyValue || property.hidden ) { continue; } // create property name with property group name const propertyDisplayName = `${groupLabels[property.groupName] || ''}: ${property.label}`; if (property.referencedObjectType) { props[property.name] = await createReferencedPropertyDefinition( property, propertyDisplayName, auth.access_token, ); continue; } if (property.name === 'hs_shared_user_ids') { const userOptions = await fetchUsersOptions(auth.access_token); props[property.name] = Property.StaticMultiSelectDropdown({ displayName: propertyDisplayName, required: false, options: { disabled: false, options: userOptions, }, }); continue; } if (['hs_shared_team_ids', 'hs_attributed_team_ids'].includes(property.name)) { const teamOptions = await fetchTeamsOptions(auth.access_token); props[property.name] = Property.StaticMultiSelectDropdown({ displayName: propertyDisplayName, required: false, options: { disabled: false, options: teamOptions, }, }); continue; } if (property.name === 'deal_currency_code') { const currencyOptions = await fetchCurrenciesOptions(auth.access_token); props[property.name] = Property.StaticDropdown({ displayName: propertyDisplayName, required: false, options: { disabled: false, options: currencyOptions, }, }); continue; } if (property.name === 'hs_all_assigned_business_unit_ids') { // TO DO : Add business unit options // const businessUnitOptions = await fetchBusinessUnitsOptions(authValue.access_token); // props[property.name] = Property.StaticMultiSelectDropdown({ // displayName: propertyDisplayName, // required: false, // options: { // disabled: false, // options: businessUnitOptions, // }, // }); continue; } props[property.name] = createPropertyDefinition(property, propertyDisplayName); } // Remove null props return Object.fromEntries(Object.entries(props).filter(([_, prop]) => prop !== null)); } export const standardObjectDynamicProperties = (objectType: string, excludedProperties: string[]) => Property.DynamicProperties({ displayName: 'Object Properties', refreshers: [], required: false, props: async ({ auth }) => { if (!auth) return {}; // Useful for Find actions // if (typeof createIfNotExists === "boolean" && createIfNotExists === false) { // return {}; // } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; return await retrieveObjectProperties(authValue, objectType, excludedProperties); }, }); export const customObjectDynamicProperties = Property.DynamicProperties({ displayName: 'Custom Object Properties', refreshers: ['customObjectType'], required: false, props: async ({ auth, customObjectType }) => { if (!auth || !customObjectType) { return {}; } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; return await retrieveObjectProperties(authValue, customObjectType as unknown as string); }, }); export const standardObjectPropertiesDropdown = ( params: DropdownParams, includeDefaultProperties = false, isSingleSelect = false, ) => { const dropdownFunction = isSingleSelect ? Property.Dropdown : Property.MultiSelectDropdown; return dropdownFunction({ displayName: params.displayName, refreshers: [], required: params.required, description: params.description, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); // Fetch all properties for the given object type const allProperties = await client.crm.properties.coreApi.getAll(params.objectType); const propertyGroups = await client.crm.properties.groupsApi.getAll(params.objectType); const groupLabels = propertyGroups.results.reduce((map, group) => { map[group.name] = group.label; return map; }, {} as Record<string, string>); const defaultProperties = includeDefaultProperties ? [] : getDefaultPropertiesForObject(params.objectType); // Filter and create options for properties that are not default const options: DropdownOption<string>[] = []; for (const property of allProperties.results) { if (!includeDefaultProperties && defaultProperties.includes(property.name)) { continue; } const propertyDisplayName = `${groupLabels[property.groupName] || ''}: ${property.label}`; options.push({ label: propertyDisplayName, value: property.name, }); } return { disabled: false, options, }; }, }); }; export const customObjectPropertiesDropdown = ( displayName: string, required: boolean, isSingleSelect = false, ) => Property.DynamicProperties({ displayName, refreshers: ['customObjectType'], required, props: async ({ auth, customObjectType }) => { if (!auth || !customObjectType) { return {}; } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); // Fetch all properties for the given object type const allProperties = await client.crm.properties.coreApi.getAll( customObjectType as unknown as string, ); const propertyGroups = await client.crm.properties.groupsApi.getAll( customObjectType as unknown as string, ); const groupLabels = propertyGroups.results.reduce((map, group) => { map[group.name] = group.label; return map; }, {} as Record<string, string>); const options: DropdownOption<string>[] = []; for (const property of allProperties.results) { const propertyDisplayName = `${groupLabels[property.groupName] || ''}: ${property.label}`; options.push({ label: propertyDisplayName, value: property.name, }); } const props: DynamicPropsValue = {}; const dropdownFunction = isSingleSelect ? Property.StaticDropdown : Property.StaticMultiSelectDropdown; props['values'] = dropdownFunction({ displayName, required, options: { disabled: false, options, }, }); return props; }, }); export const workflowIdDropdown = Property.Dropdown({ displayName: 'Workflow', refreshers: [], // description: 'Workflow to add contact to', required: true, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const token = (auth as OAuth2PropertyValue).access_token; const workflowsResponse = await httpClient.sendRequest<{ workflows: WorkflowResponse[]; }>({ method: HttpMethod.GET, url: `https://api.hubapi.com/automation/v2/workflows`, authentication: { type: AuthenticationType.BEARER_TOKEN, token: token, }, }); const options: DropdownOption<number>[] = []; for (const workflow of workflowsResponse.body.workflows) { if (workflow.enabled) { options.push({ label: workflow.name, value: workflow.id, }); } } return { disabled: false, options, }; }, }); export const pipelineDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, refreshers: [], required: params.required, description: params.description, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const pipelinesResponse = await client.crm.pipelines.pipelinesApi.getAll(params.objectType); const options = pipelinesResponse.results.map((pipeline) => { return { label: pipeline.label, value: pipeline.id, }; }); return { disabled: false, options, }; }, }); export const pipelineStageDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, refreshers: ['pipelineId'], required: params.required, description: params.description, options: async ({ auth, pipelineId }) => { if (!auth || !pipelineId) { return buildEmptyList({ placeholder: 'Please connect your account and select a pipeline.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const pipelineStagesResponse = await client.crm.pipelines.pipelineStagesApi.getAll( params.objectType, pipelineId as string, ); const options = pipelineStagesResponse.results.map((stage) => { return { label: stage.label, value: stage.id, }; }); return { disabled: false, options, }; }, }); export const productDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, refreshers: [], required: params.required, description: params.description, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const options: DropdownOption<string>[] = []; const limit = 100; let after: string | undefined; do { const response = await client.crm.products.basicApi.getPage(limit, after, ['name']); for (const product of response.results) { options.push({ label: product.properties.name ?? product.id, value: product.id, }); } after = response.paging?.next?.after; } while (after); return { disabled: false, options, }; }, }); export const customObjectDropdown = Property.Dropdown({ displayName: 'Type of Custom Object', refreshers: [], required: true, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const customObjectsResponse = await client.crm.schemas.coreApi.getAll(); const options = customObjectsResponse.results.map((customObj) => { return { label: customObj.labels.plural ?? customObj.name, value: customObj.objectTypeId, }; }); return { disabled: false, options, }; }, }); export const staticListsDropdown = Property.Dropdown({ displayName: 'List ID', refreshers: [], required: true, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const options: DropdownOption<number>[] = []; let offset = 0; let hasMore = true; do { const request: HttpRequest = { url: 'https://api.hubapi.com/contacts/v1/lists/static', method: HttpMethod.GET, authentication: { type: AuthenticationType.BEARER_TOKEN, token: authValue.access_token, }, queryParams: { count: '100', offset: offset.toString(), }, }; const response = await httpClient.sendRequest<{ total: number; offset: number; 'has-more': boolean; lists: Array<{ name: string; listId: number }>; }>(request); for (const list of response.body.lists) { options.push({ label: list.name, value: list.listId, }); } offset += 100; hasMore = response.body['has-more']; } while (hasMore); return { disabled: false, options, }; }, }); export const fromObjectTypeAssociationDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, refreshers: [], required: params.required, description: params.description, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const customObjectsResponse = await client.crm.schemas.coreApi.getAll(); // const options = customObjectsResponse.results.map((customObj) => { return { label: customObj.labels.plural ?? customObj.name, value: customObj.objectTypeId, }; }); return { disabled: false, options: [...STANDARD_OBJECT_TYPES, ...options], }; }, }); export const associationTypeDropdown = Property.Dropdown({ displayName: 'Type of the association', refreshers: ['fromObjectType', 'toObjectType'], required: true, options: async ({ auth, fromObjectType, toObjectType }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const associationLabels = await client.crm.associations.v4.schema.definitionsApi.getAll( fromObjectType as string, toObjectType as string, ); const options = associationLabels.results.map((associationLabel) => { return { label: associationLabel.label ?? `${fromObjectType}_to_${toObjectType}`, value: associationLabel.typeId, }; }); return { disabled: false, options, }; }, }); export const toObjectIdsDropdown = (params: DropdownParams) => Property.MultiSelectDropdown({ displayName: params.displayName, description: params.description, refreshers: ['toObjectType'], required: params.required, options: async ({ auth, toObjectType }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const limit = 100; const options: DropdownOption<string>[] = []; let after: string | undefined; do { const response = await client.crm.objects.basicApi.getPage( toObjectType as string, limit, after, ); for (const object of response.results) { let labelName; switch (toObjectType) { case OBJECT_TYPE.CONTACT: labelName = 'email'; break; case OBJECT_TYPE.COMPANY: labelName = 'name'; break; case OBJECT_TYPE.DEAL: labelName = 'dealname'; break; case OBJECT_TYPE.TICKET: labelName = 'subject'; break; case OBJECT_TYPE.LINE_ITEM: labelName = 'name'; break; } options.push({ label: object.properties[labelName!] ?? object.id, value: object.id, }); } after = response.paging?.next?.after; } while (after); return { disabled: false, options, }; }, }); export const formDropdown = Property.Dropdown({ displayName: 'Form', refreshers: [], required: true, options: async ({ auth }) => { if (!auth) { return buildEmptyList({ placeholder: 'Please connect your account.', }); } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const limit = 100; const options: DropdownOption<string>[] = []; let after: string | undefined; do { const response = await client.marketing.forms.formsApi.getPage(after, limit); for (const form of response.results) { options.push({ label: form.name, value: form.id, }); } after = response.paging?.next?.after; } while (after); return { disabled: false, options, }; }, }); export const blogUrlDropdown = Property.Dropdown({ displayName: 'Blog URL', refreshers: [], required: true, options: async ({ auth }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Please connect your account.' }; } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const response = await httpClient.sendRequest<ListBlogsResponse>({ method: HttpMethod.GET, url: 'https://api.hubapi.com/content/api/v2/blogs', authentication: { type: AuthenticationType.BEARER_TOKEN, token: authValue.access_token }, queryParams: { limit: '100', }, }); return { disabled: false, options: response.body.objects.map((blog) => { return { label: blog.absolute_url, value: blog.id.toString(), }; }), }; }, }); export const blogAuthorDropdown = Property.Dropdown({ displayName: 'Blog Author', refreshers: [], required: true, options: async ({ auth }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Please connect your account.' }; } const authValue = auth as PiecePropValueSchema<typeof hubspotAuth>; const client = new Client({ accessToken: authValue.access_token }); const options: DropdownOption<string>[] = []; let after: string | undefined; do { const response = await client.cms.blogs.authors.blogAuthorsApi.getPage( undefined, undefined, undefined, undefined, undefined, undefined, undefined, after, 100, ); for (const author of response.results) { options.push({ label: author.name, value: author.id, }); } after = response.paging?.next?.after; } while (after); return { disabled: false, options, }; }, }); type DropdownParams = { objectType: OBJECT_TYPE; displayName: string; required: boolean; description?: string; }; export const pageType=Property.StaticDropdown({ displayName:'Page Type', required:true, defaultValue:'landing_page', options:{ disabled:false, options:[ { label:'Landing Page', value:'landing_page' }, { label:'Site Page', value:'site_page' } ] } })

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