Skip to main content
Glama

mcp-google-sheets

props.ts7.7 kB
import { DynamicPropsValue, Property } from '@activepieces/pieces-framework'; import { attioApiCall, attioPaginatedApiCall } from './client'; import { HttpMethod } from '@activepieces/pieces-common'; import { AttributeResponse, ListResponse, ObjectResponse, SelectOptionResponse } from './types'; import { isNil } from '@activepieces/shared'; interface DropdownParams { displayName: string; description?: string; required: boolean; } export const objectTypeIdDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, description: params.description, required: params.required, refreshers: [], options: async ({ auth }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Please connect your account first.', }; } const response = await attioApiCall<{ data: Array<ObjectResponse> }>({ accessToken: auth as string, method: HttpMethod.GET, resourceUri: '/objects', }); return { disabled: false, options: response.data.map((obj) => ({ label: obj.singular_noun, value: obj.id.object_id, })), }; }, }); export const listIdDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, description: params.description, required: params.required, refreshers: [], options: async ({ auth }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Please connect your account first.', }; } const response = await attioApiCall<{ data: Array<ListResponse> }>({ accessToken: auth as string, method: HttpMethod.GET, resourceUri: '/lists', }); return { disabled: false, options: response.data.map((obj) => ({ label: obj.name, value: obj.id.list_id, })), }; }, }); export const listParentObjectIdDropdown = (params: DropdownParams) => Property.Dropdown({ displayName: params.displayName, description: params.description, required: params.required, refreshers: ['listId'], options: async ({ auth, listId }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Please connect your account first.', }; } if (!listId) { return { disabled: true, options: [], placeholder: 'Please select list first.', }; } const response = await attioApiCall<{ data: ListResponse }>({ accessToken: auth as string, method: HttpMethod.GET, resourceUri: `/lists/${listId}`, }); return { disabled: false, options: [{ label: response.data.parent_object[0], value: response.data.parent_object[0] }], }; }, }); async function createPropertyDefinition( property: AttributeResponse, objectType:'lists'|'objects', objectTypeId: string, accessToken: string, isSearch=false ) { const { api_slug, title, is_required, type, is_multiselect } = property; const required = isSearch ? false : is_required switch (type) { case 'text': case 'currency': case 'location': case 'phone-number': case 'personal-name': return Property.ShortText({ displayName: title, required, description: type === 'personal-name' ? 'Provide comma-separated format name i.e. Last name(s), First name(s).' : '', }); case 'number': case 'rating': return Property.Number({ displayName: title, required, }); case 'checkbox': return Property.Checkbox({ displayName: title, required, }); case 'date': case 'timestamp': return Property.DateTime({ displayName: title, required, }); case 'actor-reference': case 'email-address': case 'domain': { const basicField = is_multiselect ? Property.Array : Property.ShortText; return basicField({ displayName: title, required, }); } case 'status': { const response = await attioApiCall<{ data: SelectOptionResponse[] }>({ method: HttpMethod.GET, accessToken: accessToken, resourceUri: `/${objectType}/${objectTypeId}/attributes/${api_slug}/statuses`, }); return Property.StaticDropdown({ displayName: title, required, options: { disabled: false, options: response.data.map((opt) => ({ label: opt.title, value: opt.title, })), }, }); } case 'select': { const response = await attioApiCall<{ data: SelectOptionResponse[] }>({ method: HttpMethod.GET, accessToken: accessToken, resourceUri: `/${objectType}/${objectTypeId}/attributes/${api_slug}/options`, }); const dropdownType = is_multiselect ? Property.StaticMultiSelectDropdown : Property.StaticDropdown; return dropdownType({ displayName: title, required, options: { disabled: false, options: response.data.map((opt) => ({ label: opt.title, value: opt.title, })), }, }); } default: return null; } } export const objectFields =(isSearch=false)=> Property.DynamicProperties({ displayName: 'Object Attributes', refreshers: ['objectTypeId'], required: false, props: async ({ auth, objectTypeId }) => { if (!auth || !objectTypeId) return {}; const accessToken = auth as unknown as string; const objectId = objectTypeId as unknown as string; const props: DynamicPropsValue = {}; const response = await attioPaginatedApiCall<AttributeResponse>({ method: HttpMethod.GET, accessToken: accessToken, resourceUri: `/objects/${objectId}/attributes`, }); for (const attribute of response) { if (!attribute.is_writable) continue; const { api_slug } = attribute; props[api_slug] =await createPropertyDefinition(attribute,'objects', objectId, accessToken,isSearch); } return Object.fromEntries(Object.entries(props).filter(([_, prop]) => prop !== null)); }, }); export const listFields =(isSearch=false)=> Property.DynamicProperties({ displayName: 'List Attributes', refreshers: ['listId'], required: false, props: async ({ auth, listId }) => { if (!auth || !listId) return {}; const accessToken = auth as unknown as string; const list_id = listId as unknown as string; const props: DynamicPropsValue = {}; const response = await attioPaginatedApiCall<AttributeResponse>({ method: HttpMethod.GET, accessToken: accessToken, resourceUri: `/lists/${list_id}/attributes`, }); for (const attribute of response) { if (!attribute.is_writable) continue; const { api_slug } = attribute; props[api_slug] =await createPropertyDefinition(attribute,'lists', list_id, accessToken,isSearch); } return Object.fromEntries(Object.entries(props).filter(([_, prop]) => prop !== null)); }, }); export async function formatInputFields( accessToken: string, objectType:'lists'|'objects', objectId: string, inputValues: Record<string, any>, ) { const attributes = await attioPaginatedApiCall<AttributeResponse>({ method: HttpMethod.GET, accessToken: accessToken, resourceUri: `/${objectType}/${objectId}/attributes`, }); const typeMapping = attributes.reduce((acc, { api_slug, type }) => { acc[api_slug] = type; return acc; }, {} as Record<string, string>); const formattedFields: Record<string, any> = {}; for (const [key, value] of Object.entries(inputValues)) { if (isNil(value) || value === '') continue; if(Array.isArray(value) && value.length === 0) continue; const fieldType = typeMapping[key]; switch (fieldType) { case 'phone-number': formattedFields[key] = [value]; break; case 'domain': case 'select': formattedFields[key] = typeof value === 'string' ? [value] : value; break; default: formattedFields[key] = value; break; } } return formattedFields; }

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