Skip to main content
Glama

mcp-google-sheets

file.ts3.25 kB
import { ApFile } from '@activepieces/pieces-framework' import { isNil, isString } from '@activepieces/shared' import axios from 'axios' import isBase64 from 'is-base64' import mime from 'mime-types' import { ProcessorFn } from './types' export const fileProcessor: ProcessorFn = async (_property, urlOrBase64) => { if (isNil(urlOrBase64) || !isString(urlOrBase64)) { return null } try { const file = handleBase64File(urlOrBase64) if (!isNil(file)) { return file } return await handleUrlFile(urlOrBase64) } catch (e) { console.error(e) return null } } function handleBase64File(propertyValue: string): ApFile | null { if (!isBase64(propertyValue, { allowMime: true })) { return null } const matches = propertyValue.match(/^data:([A-Za-z-+/]+);base64,(.+)$/) // example match: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC if (!matches || matches?.length !== 3) { return null } const base64 = matches[2] const extension = mime.extension(matches[1]) || 'bin' return new ApFile( `unknown.${extension}`, Buffer.from(base64, 'base64'), extension, ) } async function handleUrlFile(path: string): Promise<ApFile | null> { const fileResponse = await axios.get(path, { responseType: 'arraybuffer', }) const filename = getFileName(path, fileResponse.headers['content-disposition'], fileResponse.headers['content-type']) ?? 'unknown' const extension = filename.split('.').length > 1 ? filename.split('.').pop() : undefined return new ApFile( filename, Buffer.from(fileResponse.data, 'binary'), extension, ) } function getFileName(path: string, disposition: string | null, mimeType: string | undefined): string | null { const url = new URL(path) if (isNil(disposition)) { const fileNameFromUrl = url.pathname.includes('/') && url.pathname.split('/').pop()?.includes('.') ? url.pathname.split('/').pop() : null if (!isNil(fileNameFromUrl)) { return fileNameFromUrl } const resolvedExtension = mimeType ? mime.extension(mimeType) : null return `unknown.${resolvedExtension ?? 'bin'}` } const utf8FilenameRegex = /filename\*=UTF-8''([\w%\-.]+)(?:; ?|$)/i if (utf8FilenameRegex.test(disposition)) { const result = utf8FilenameRegex.exec(disposition) if (result && result.length > 1) { return decodeURIComponent(result[1]) } } // prevent ReDos attacks by anchoring the ascii regex to string start and // slicing off everything before 'filename=' const filenameStart = disposition.toLowerCase().indexOf('filename=') const asciiFilenameRegex = /^filename=(["']?)(.*?[^\\])\1(?:; ?|$)/i if (filenameStart >= 0) { const partialDisposition = disposition.slice(filenameStart) const matches = asciiFilenameRegex.exec(partialDisposition) if (matches != null && matches[2]) { return matches[2] } } return null }

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