Keep this open while you build an automation that turns a client call into a draft proposal deck. The blocks follow the order of the work: first the data and the meeting log, then human approval and the model's instructions, and finally the slide generator call and the draft review. You come back to the last block for every proposal, not just during the build.
Tool names are examples: a meeting notetaker such as Fireflies, n8n as the automation platform, a Google Sheet, Slack, and a presentation generator such as Gamma. The questions stay the same on any stack.
1. Split into two workflows
A workflow is a chain of steps run in order, and a node is a single step. Logging a meeting and doing something with that log are two different jobs, and you build them separately.
- [ ] The first workflow only logs the meeting; it doesn't generate any proposal.
- [ ] The second workflow starts from a new entry in the meeting log, not from the meeting itself.
- [ ] List the meeting types you may later want to handle differently: sales call, internal meeting, call with an existing client.
- [ ] Check that a new branch for another meeting type can be added without rebuilding the proposal workflow.
Each workflow has one job. Then a new path is a new branch, not a rebuild.
2. Trigger and data readiness
A webhook is an address another program calls on its own when something happens. Polling means checking repeatedly until the data is ready.
- [ ] The notetaker's developer settings hold the production webhook URL, not the test one.
- [ ] The "transcription complete" event is ticked.
- [ ] Check what the notification actually carries; usually it's only the meeting ID and the event type.
- [ ] A separate node fetches the full meeting data by ID: transcript, title, attendees, summaries.
- [ ] A short wait sits before the fetch.
- [ ] A condition node checks whether the AI-generated summary exists yet.
- [ ] If it doesn't, the workflow goes back to waiting and asks again; if it does, the flow moves on.
- [ ] Test the loop on a meeting whose summary hasn't been generated yet.
The notification tells you something happened. You fetch the data separately, and sometimes you wait for it.
3. Clean the transcript
The data arrives as JSON, a structured text format of fields and values. Before it reaches the model or the sheet, pull out only what you use.
- [ ] A code node returns the list of people who spoke in the meeting.
- [ ] The transcript for the model shows each speaker's name once at the start of their turn, not before every sentence.
- [ ] Write the code with an AI chat: paste the full input JSON and describe the output you want.
- [ ] When the code fails, go back to the chat with three things: the code you got, what it produced, and why that's wrong.
- [ ] Check the result on a meeting with several speakers, not just one.
4. Meeting log: ID and status
The sheet is both a log and a status board. It only works if every meeting can be found in it without ambiguity.
- [ ] Columns: date and time, title, attendees, gist, status, meeting ID.
- [ ] The meeting ID is the unique key; neither the title nor the date is.
- [ ] A new row gets a neutral status.
- [ ] The status changes to "declined" when a person refuses generation.
- [ ] The status changes to "generated" after the slide generator call.
- [ ] A status change updates the existing row, matched by ID, instead of appending a new one.
- [ ] After fetching data, the second workflow keeps only the last item, so two meetings ending at once don't confuse it.
Anything that needs to find a meeting again looks it up by ID.
5. Human approval before generating
Human-in-the-loop: the automation pauses and waits for a person to decide.
- [ ] After a meeting ends, a message arrives asking whether to generate a proposal.
- [ ] The message includes the meeting title, so deciding doesn't require opening the sheet.
- [ ] "Yes" starts generation.
- [ ] "No" sets the status to "declined" and ends the run.
- [ ] The message goes to the person who ran the call and knows whether a proposal makes sense.
Not every call ends in a proposal. Asking costs one click; an unneeded proposal costs more.
6. Prompt for the model: template
The model produces something slightly different every time. A structured prompt keeps that randomness in check.
- [ ] Role: an experienced AI solutions consultant and sales engineer who turns a call transcript into a client proposal.
- [ ] Objective: the proposal is built from the transcript and only the transcript.
- [ ] Constraint: the document is entirely client-facing; no follow-up questions.
- [ ] Constraint: no internal notes and no text about how the document was produced.
- [ ] Constraint: missing data is marked with a clear placeholder, such as [amount to confirm], instead of invented details.
- [ ] Tone: matter-of-fact, confident, readable for a decision-maker.
- [ ] Section structure, in this order:
- [ ] title page
- [ ] executive summary
- [ ] problem and challenge
- [ ] proposed solution
- [ ] return on investment
- [ ] intangible benefits
- [ ] implementation roadmap
- [ ] success metrics
- [ ] why us
- [ ] Optional: the agent can search a database of your company's past projects and base the "why us" slide on the closest case.
- [ ] After a few drafts, go back to the prompt and fix whatever keeps coming out wrong.
7. Slide generator call
An API is a service entrance to a program that lets another program talk to it without clicking through the interface.
- [ ] Example request copied from the generator's API documentation.
- [ ] For every field, answer: is it required, what does it do, what do you want.
- [ ] The input text is the proposal agent's output.
- [ ] Text mode set to preserve, so the generator doesn't condense or rewrite the proposal.
- [ ] Theme ID copied from your own template.
- [ ] Set: amount of text, tone, audience, image source.
- [ ] Sharing: comment access, with the link emailed to your internal address.
- [ ] The API key sits in the authentication header, not in the request body.
- [ ] The agent's text is stripped of line breaks and quotation marks before it goes into the request body.
- [ ] After the call, a notification says the deck is being generated.
One unescaped quote breaks the whole request. Clean the text before sending, every time.
8. A second way in
Sometimes you decline and then change your mind. The second path has to feed the same downstream steps.
- [ ] A form with one field: the meeting ID copied from the sheet.
- [ ] The form runs the same steps as the automatic path: fetch, clean, agent, generator, status.
- [ ] Both paths feed into one standardizing node (in n8n, a Set node).
- [ ] The standardizing node exposes the transcript and the meeting ID under the same names.
- [ ] The agent and the sheet update read only from the standardizing node, never directly from either path.
- [ ] Test each path on its own; both have to run to the end.
9. Draft review before sending
Tick this block for every proposal. The draft looks professional, which is exactly why it's easy to send unread.
- [ ] Every figure (hours saved, cost savings, error reduction) checked against the client's real data, or removed.
- [ ] No figure comes from a rough estimate tossed out during the call.
- [ ] Every placeholder filled in, or removed along with its sentence.
- [ ] Every chart can be described in one sentence; axes and colors match the legend.
- [ ] The implementation timeline is set by you, based on the team and the scope, not copied from the model.
- [ ] The "why us" slide rests on real projects, not generalities.
- [ ] The document contains no system text, internal notes, or questions to yourself.
- [ ] The client's name and the description of their problem match what was said on the call.
- [ ] The proposal is sent by a person who has read all of it.
The automation takes the work, not the signature. Numbers, dates, and promises go through a person.
An empty box in block nine won't stop you sending today. It comes back later as a client asking about a figure nobody can defend. If you can't tick a box, fix the draft before it goes out.