Skip to main content

Form integrations

Every landing page from @layero includes a form. Where the data goes is chosen by the user in the third quiz.

Telegram

Submissions arrive in a chat or a group through a bot.

What the user provides:

  1. A bot token from @BotFather
  2. The id of the chat to send to (through @RawDataBot — send it any message and it replies with the chat_id)

What the plugin does:

  1. Creates a small relay on FastAPI (forms-relay/main.py)
  2. Deploys it as a Layero runtime app
  3. Sets the env vars TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID
  4. Puts the relay URL into the landing page's <form action>

The user does not have to configure CORS, run their own API or stand up a server — Layero does that in one move.

Google Sheets

Submissions become new rows in a Google spreadsheet. No backend of your own.

What the user provides:

  1. Create an empty spreadsheet
  2. ExtensionsApps Script → paste the code (the plugin generates it for the right fields)
  3. DeployWeb appAccess: anyone → copy the URL
  4. Paste the URL back into the chat

What the plugin does:

  1. Generates the Apps Script for the form's columns (timestamp, name, email, message, …)
  2. Writes the Web App URL into <form action>
  3. Adds a little JS for a thank-you state without a reload

CORS is not needed — Apps Script accepts application/x-www-form-urlencoded without a preflight.

Custom webhook / Notion / HubSpot / your own API

If the user already has an endpoint or a service (Notion, HubSpot, ConvertKit, Airtable, their own backend), the plugin works like this:

What the user hasWhat the plugin does
A webhook URLWrites it into <form action> — done
A public form embed (Mailchimp, HubSpot, and so on)Extracts the action URL from the embed code and mirrors the field names
An API key for a serviceStands up a Layero relay (as with Telegram), keeps the key in env vars and forwards the payload
Their own backendOne question — "which fields does it expect?" — then fills in the names

When integration = skip

The user can skip the integration step outright. In that case <form action> is set to the placeholder {{FORM_ACTION}}, and they can configure it later by calling @layero add-integration ... again.