Devpost story — Slack Form Builder

Inspiration

Every team runs on questions: "How did the offsite go?", "What should we order for the launch party?", "Are customers happy with the new pricing?" And every time, the same ritual — someone opens an external form builder, drags fields around, copies a link, pastes it into Slack, and then begs people to click out of Slack to answer. The form lives in one place, the people live in another, and the results live in a third.

I had already built a web app that generates forms from natural language, and the lesson it taught me was uncomfortable: the AI was never the bottleneck — the surface was. The link was the bottleneck. People answer where they already are, and where they already are is Slack. So instead of bringing people to the form, I brought the entire form lifecycle — creation, editing, filling, publishing, and analytics — into Slack, and rebuilt it around the surfaces Slack gives an agent developer today: the AI assistant panel, the App Home, modals, and the brand-new Block Kit agent components.

What it does

Slack Form Builder is an AI form agent that lives entirely in Slack. You describe the form you need in plain English — in the AI assistant panel, a DM, an @mention, or /slacky-form — and:

  1. A card carousel asks how the AI should think — 💭 Sentiment (emotions, satisfaction scales), 📊 Statistics (numbers, demographics), or ⚖️ Balanced — and the agent suggests the right mode by reading your prompt.
  2. OpenAI designs the form in seconds — 4–8 questions with proper types (rating scales, dropdowns, emails, dates), previewed question-by-question with type badges.
  3. You refine it conversationally — 🪄 "add a phone number question, make email optional, translate it to Spanish" — and the AI applies the edit without losing anything.
  4. People fill it natively — every question renders as a real Slack input in a modal: ⭐ star ratings, dropdowns, date pickers, email fields. No link, no browser tab, no login.
  5. You publish it to any channel as a rich card with one button, so teammates answer inside the conversation where the question came up.
  6. Results become a live dashboard — distribution tables built with Slack's new data_table block, rating averages, and latest quote highlights, refreshable in place.
  7. Everything lands in Google BigQuery — every form and response is mirrored to a real analytics warehouse, so the data outlives the demo.

The whole journey — idea to insight — happens without ever leaving Slack.

How we built it

Slack isn't the delivery channel here; it's the framework the whole product hangs on. The app is Bolt for JavaScript running in Socket Mode (no public URL, no ngrok), created from a declarative app manifest, and it deliberately uses every agent surface Slack offers:

  • The AI assistant panel (Assistant in Bolt, assistant_view in the manifest) is the front door — suggested prompts like "✨ Customer feedback form", live status updates ("is designing your form…"), and thread titles set from your request.
  • The new Block Kit agent components are the UI language: a carousel of card blocks for choosing the AI mode, a card for the published form in channels, and data_table blocks for result distributions. Because these blocks are new, every rich surface ships with a classic-blocks twin — a postRich() helper tries the rich version and falls back automatically (the fallback results dashboard draws ▓▓▓░░ ASCII bar charts, which honestly have their own charm).
  • Modals do the transactional work: form filling (each AI question type maps to a native Slack input element — number_input with min/max, radio_buttons as star scales, email_text_input, datepicker), AI editing, publishing with a conversations_select, and new-form creation.
  • App Home is the dashboard: every form with its response count, publish state, and one-click fill/edit/publish/results.
  • Events and commands (app_mention, message.im, app_home_opened, /slacky-form) make the agent reachable from anywhere in the workspace.

Around that Slack core: OpenAI's Responses API does all the reasoning — natural language → a strict form JSON schema, and edit instructions → a full updated form, with a validation layer that normalizes anything the model gets creative with. Google BigQuery (@google-cloud/bigquery, service-account auth) is the analytics warehouse — forms and responses are mirrored with parameterized DML inserts into a slacky_form_builder dataset. A local JSON store is the source of truth, so the app is resilient by design: if BigQuery is unreachable, the mirror self-disables and nothing user-facing breaks. A doctor.js preflight verifies Slack auth, the OpenAI model, and the BigQuery dataset before every demo.

Challenges we ran into

The newest Block Kit blocks are powerful but young: support varies by surface, data_table silently fails without a caption, and card bodies cap at 200 characters with 3 buttons. Instead of avoiding them, I built every message twice — rich and classic — and let postRich() decide at post time, so the UX upgrades where Slack supports it and never breaks where it doesn't. Slack's trigger_id dies three seconds after a button click, which taught me to open modals before doing any AI work, ever. BigQuery's streaming inserts are blocked on sandbox-tier projects, so I switched to parameterized DML INSERT statements, which work everywhere — and made the mirror append-only and self-disabling so a permissions hiccup could never take down a live demo. And mapping a free-form AI output onto Slack's strict input elements needed a defensive validation layer: unknown question types coerce to text, choice questions get default options, and modals cap their block count safely.

Accomplishments that we're proud of

The moment that sold me on the whole idea: typing "customer feedback form with rating scales" into the assistant panel and, fifteen seconds later, submitting that form as native Slack star ratings — then watching the response appear in a BigQuery table. The conversational edit loop is the feature I'm proudest of — "add a phone number question" went 6 → 7 questions in testing while preserving every existing question verbatim. The full lifecycle is demonstrably inside Slack: create in the assistant panel, fill in a modal, publish as a card, analyze in a data_table. And the resilience engineering paid off: every rich surface has a tested fallback, and the app runs identically with or without its warehouse.

What we learned

The best interface is the one nobody has to adopt — meeting people inside Slack removed the single biggest source of friction in form tools, the link. Slack's newest agent surfaces genuinely change what a bot can feel like: the assistant panel makes an app conversational by default, and the card/carousel/data_table blocks make responses feel like a product instead of a wall of text — but shipping them responsibly means building graceful degradation in from day one. I learned that with LLMs, the schema contract is the product: a strict JSON shape plus a forgiving validator turns a creative model into a reliable form engine. And I learned to treat external dependencies as enhancements rather than requirements — local-first storage with a fire-and-forget BigQuery mirror meant no single failure could ever break the experience.

What's next for Slack Form Builder

Bring back the analytics superpowers from my web version, now Slack-native: AI sentiment analysis on text answers surfaced as an insight alert on the results dashboard, live web benchmarks ("how do my scores compare to industry averages?") with citations, and synthetic sample data so a dashboard is never empty. Scheduled forms — "send the team pulse survey every Monday at 9am" — so feedback becomes a habit instead of an event. BigQuery-powered trends across form versions and time. And the bigger vision this project convinced me of: forms are just the first agent — the same describe-it-in-plain-English pattern can let anyone on a team create their own specialized Slack agents, no code, no console, one sentence at a time. Then ship it to the Slack Marketplace so any workspace is one click away from never pasting a form link again.

Built With

Share this project:

Updates