Meeting to Action — Devpost Submission
Tagline (one-liner)
Meeting talk becomes tracked work — a Slack agent that turns your notes into approved, tracked action items.
Inspiration
Every team we've worked on has the same quiet tax: a meeting ends, someone says "I'll write up the notes," and the action items evaporate into a wall of text nobody rereads. Decisions get made out loud, but they never make it into a task, an owner, or a deadline — so they get made again two weeks later.
We wanted to test a simple idea: what if the follow-up wrote itself? Not another notes-taking app competing for a tab in your browser, but something that lives exactly where the meeting notes already land — Slack — and turns raw text into tracked, owned, nudge-able work.
What it does
Meeting to Action watches for meeting notes pasted into a Slack channel and:
- Extracts action items, owners, and due dates using Gemini — including resolving loose relative dates like "Thursday" or "next sprint" into real calendar dates.
- Checks Slack's Real-Time Search (RTS) API for related past discussions before surfacing each item, so nothing gets proposed in a vacuum — if the topic came up before, the card shows how many related mentions exist.
- Proposes, doesn't decide. Every extracted item appears as an interactive Block Kit card with Approve and Discard buttons. Nothing gets tracked without a human confirming it.
- Persists approved items to a Google Sheet — task, owner, resolved due date, status, who approved it, and a link straight back to the original Slack message.
- Skips duplicates automatically, so re-mentioning the same task later doesn't create a second row.
- Flags overdue items by highlighting rows once their resolved due date passes.
How we built it
- Slack Bolt SDK (Node.js) running in Socket Mode — no public URL or inbound webhook needed, which made local iteration fast.
- Slack Block Kit for the interactive approval card (Approve/Discard buttons, owner/due display, related-mentions note).
- Slack Real-Time Search API (
assistant.search.context) — queried with a user token (search:read.publicscope) to pull related past messages before an item is surfaced. - Gemini API for extraction — a single structured prompt returns task, owner, raw due date, and a resolved ISO date, given today's date as context.
- Google Sheets API — approved items are appended as rows, with duplicate-checking against existing tasks and conditional background-highlighting for overdue items, all done via
batchUpdatecalls. - Google Cloud service account for Sheets auth, supporting both local file-based credentials and an environment-variable-based credential for hosted deployment (Render background worker).
Challenges we ran into
- RTS token requirements. The RTS endpoint (
assistant.search.context) requires anaction_tokenwhen called with a bot token — tied to Slack's Assistant framework. We found that calling it with a user token instead avoids this requirement, which was the key unlock for getting it working without building the full Assistant integration. - A silent bug in our own related-mentions counter.
assistant.search.contextreturnsresultsas an object ({ messages: [...] }), not an array — so our first version'sres.results.lengthwas alwaysundefined. The API was working the whole time; our display logic wasn't reading the response shape correctly. Caught this by adding temporary debug logging to see the raw response before concluding anything was broken. - Model deprecation mid-build. Our original extraction model was removed from availability for new API accounts partway through building, which meant swapping to a current model and re-verifying prompt behavior.
- Sheets permission errors. Service account credentials alone aren't enough — the target Sheet has to be explicitly shared with the service account's email as an Editor. A
403 PERMISSION_DENIEDpointed us to this directly.
Accomplishments we're proud of
- A full working pipeline from a single Slack message to a persisted, deduplicated, context-checked row in Google Sheets — with a human approval step in between at every point.
- Genuine RTS API integration that surfaces real related messages from workspace history, not a canned demo.
- Deployable outside a single dev machine — the same codebase runs locally against a file-based service account key, or on a hosted background worker using an environment-variable-based credential.
What we learned
- Meeting text is messier than it looks — commitments are often implicit, and good extraction needs conversational cues, not just keyword matching.
- RTS is most valuable as a precision tool, not a blanket search — querying only when a real decision-like item is extracted kept it fast and useful rather than noisy.
- A human-approval step doesn't slow an agent down as much as expected — it made the tool more trustworthy to actually rely on.
What's next
- A "mark as done" button that updates the existing Sheet row instead of appending a new one.
- Multi-language meeting support.
- Per-channel or per-week Sheet tabs for teams running multiple concurrent projects.
Built With
slack, slack-api, slack-bolt, slack-block-kit, real-time-search, model-context-protocol, mcp, gemini, google-sheets-api, google-cloud, node.js, javascript, oauth, rest-api, json, socket-mode, render
Track
Best New Slack Agent
Built With
- ai-agents
- automation
- express.js
- git
- javascript
- json
- llm
- mcp
- model-context-protocol
- natural-language-processing
- node.js
- oauth
- openai
- productivity
- prompt-engineering
- real-time-search
- rest-api
- slack
- slack-agent-builder
- slack-api
- slack-block-kit
- slack-bolt
- slack-cli
- webhooks
Log in or sign up for Devpost to join the conversation.