Skip to main content
Glama

mcp-google-sheets

catch-hook.ts5.21 kB
import { createTrigger, DynamicPropsValue, Property, TriggerStrategy, } from '@activepieces/pieces-framework'; import { assertNotNullOrUndefined, MarkdownVariant } from '@activepieces/shared'; const liveMarkdown = `**Live URL:** \`\`\`text {{webhookUrl}} \`\`\` generate sample data & triggers published flow. `; const testMarkdown = ` **Test URL:** if you want to generate sample data without triggering the flow, append \`/test\` to your webhook URL. `; const syncMarkdown = `**Synchronous Requests:** If you expect a response from this webhook, add \`/sync\` to the end of the URL. If it takes more than 30 seconds, it will return a 408 Request Timeout response. To return data, add an Webhook step to your flow with the Return Response action. `; enum AuthType { NONE = 'none', BASIC = 'basic', HEADER = 'header', } export const catchWebhook = createTrigger({ name: 'catch_webhook', displayName: 'Catch Webhook', description: 'Receive incoming HTTP/webhooks using any HTTP method such as GET, POST, PUT, DELETE, etc.', props: { liveMarkdown: Property.MarkDown({ value: liveMarkdown, variant: MarkdownVariant.BORDERLESS, }), syncMarkdown: Property.MarkDown({ value: syncMarkdown, variant: MarkdownVariant.INFO, }), testMarkdown: Property.MarkDown({ value: testMarkdown, variant: MarkdownVariant.INFO, }), authType: Property.StaticDropdown<AuthType>({ displayName: 'Authentication', required: true, defaultValue: 'none', options: { disabled: false, options: [ { label: 'None', value: AuthType.NONE }, { label: 'Basic Auth', value: AuthType.BASIC }, { label: 'Header Auth', value: AuthType.HEADER }, ], }, }), authFields: Property.DynamicProperties({ displayName: 'Authentication Fields', required: false, refreshers: ['authType'], props: async ({ authType }) => { if (!authType) { return {}; } const authTypeEnum = authType.toString() as AuthType; let fields: DynamicPropsValue = {}; switch (authTypeEnum) { case AuthType.NONE: fields = {}; break; case AuthType.BASIC: fields = { username: Property.ShortText({ displayName: 'Username', description: 'The username to use for authentication.', required: true, }), password: Property.ShortText({ displayName: 'Password', description: 'The password to use for authentication.', required: true, }), }; break; case AuthType.HEADER: fields = { headerName: Property.ShortText({ displayName: 'Header Name', description: 'The name of the header to use for authentication.', required: true, }), headerValue: Property.ShortText({ displayName: 'Header Value', description: 'The value to check against the header.', required: true, }), }; break; default: throw new Error('Invalid authentication type'); } return fields; }, }), }, sampleData: null, type: TriggerStrategy.WEBHOOK, async onEnable() { // ignore }, async onDisable() { // ignore }, async run(context) { const authenticationType = context.propsValue.authType; assertNotNullOrUndefined( authenticationType, 'Authentication type is required' ); const verified = verifyAuth( authenticationType, context.propsValue.authFields ?? {}, context.payload.headers ); if (!verified) { return []; } return [context.payload]; }, }); function verifyAuth( authenticationType: AuthType, authFields: DynamicPropsValue, headers: Record<string, string> ): boolean { switch (authenticationType) { case AuthType.NONE: return true; case AuthType.BASIC: return verifyBasicAuth( headers['authorization'], authFields['username'], authFields['password'] ); case AuthType.HEADER: return verifyHeaderAuth( headers, authFields['headerName'], authFields['headerValue'] ); default: throw new Error('Invalid authentication type'); } } function verifyHeaderAuth( headers: Record<string, string>, headerName: string, headerSecret: string ) { const headerValue = headers[headerName.toLocaleLowerCase()]; return headerValue === headerSecret; } function verifyBasicAuth( headerValue: string, username: string, password: string ) { if (!headerValue.toLocaleLowerCase().startsWith('basic ')) { return false; } const auth = headerValue.substring(6); const decodedAuth = Buffer.from(auth, 'base64').toString(); const [receivedUsername, receivedPassword] = decodedAuth.split(':'); return receivedUsername === username && receivedPassword === password; }

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