Instrument x Seth Akkerman
Projects AI Speech Outline Generator

AI Speech Outline Generator

A Google Docs add-on that generates structured speech outlines directly inside a document — audience, topic, duration, tone, and brand inputs feed an OpenAI model that inserts a formatted table ready to present from.

Built as a client-facing demo for Uber for Business, this tool lives entirely inside Google Docs — no separate app, no copy-pasting between tabs. A custom sidebar panel surfaces a handful of fields: audience, topic, duration, brand, and tone. Hit generate, and a fully structured speech outline gets inserted at the cursor as a formatted table, complete with section breakdowns, durations, and talking points.

How it works

The sidebar is a lightweight Google Apps Script web app wired directly into the document. When a user submits the form, it calls a server-side function that constructs a prompt and hits the OpenAI API — defaulting to GPT-4o Mini for speed and cost-efficiency, with GPT-4o and GPT-4 Turbo as selectable options. The response is parsed and written back into the document as a native table, so it looks like something you actually built in Docs rather than something pasted in from a chatbot.

The default configuration is pre-filled for Uber for Business use cases — “Grocery Store Sales Teams” as the audience, 20-minute duration, confident and motivational tone — but every field is editable. The whole thing can be locked down or opened up depending on how much control you want to hand the end user.

Why it matters

Most AI writing tools ask you to leave your document, generate somewhere else, and paste back in. This collapses that workflow entirely. The document is the interface. For sales teams preparing customer-facing presentations, that friction reduction is the whole point — the fewer context switches between tools, the more likely people actually use it.

The broader pattern here is interesting: Google Workspace as an AI deployment surface. Docs, Sheets, and Slides all support Apps Script, which means tools like this can be deployed to an entire org without anyone installing anything. Enterprise rollouts that would normally require IT approval and a new SaaS subscription can sometimes just be a script attached to a shared file.

Applying this to your project

  1. Copy both files as-is: code.gs and Sidebar.html. There’s no build step, no other config, and nothing to discard — this is the entire project.
  2. Before anything else, deal with the API key: code.gs line 9 hardcodes DEMO_API_KEY in plaintext. Delete that value, and instead wire the sidebar to the saveApiKey() function that already exists in the code but currently has no UI calling it — add a small “Save API Key” input/button in Sidebar.html that calls google.script.run.saveApiKey(key), so each user’s key lives in that document’s Script Properties instead of in your source file.
  3. Swap out the hardcoded brand defaults for your own client: the fallback values in sanitizeForm() ('Uber for Business', 'Grocery Store Sales Teams', the tone string) and the matching placeholder/value attributes on the inputs in Sidebar.html. Also rename the menu label in onOpen() and the sidebar title in showSidebar() away from “Uber Speech Generator.”
  4. The two real integration points are buildMessages() and insertOutlineTable() in code.gs. buildMessages() defines the JSON schema the AI must return (total_minutes, sections, bullets) — change this if you want a different kind of document (e.g. an agenda instead of a speech). insertOutlineTable() is what turns that JSON back into a formatted Doc table — any schema change on one side needs a matching change on the other.
  5. Gotchas found in the code: response_format: { type: "json_object" } in callAiForOutline() only works with newer OpenAI models — if you add older models to the dropdown in Sidebar.html, the request will fail. There’s also no retry/timeout handling around the UrlFetchApp.fetch() call, so a slow or rate-limited API response just surfaces as a raw error string in the sidebar. And console.log(JSON.stringify(json...)) in generateSpeechOutline() is a leftover debug line worth removing once you’re past testing.

Other ways to repurpose this

Product Design

Web Design

Marketing

Branding

Dependencies

openai-chat-completions-api v1 Called directly via UrlFetchApp (no SDK) to turn a speaker's audience/topic/tone inputs into a structured JSON speech outline.
google-apps-script-v8-runtime V8 (no package manager — this project has no package.json/lockfile) Hosts the entire script server-side inside the Google Doc; provides the JS execution environment with no build step or npm install.
DocumentApp Google Apps Script built-in service Reads the active Google Doc and appends the generated outline as a formatted table with headings and bold header row.
HtmlService Google Apps Script built-in service Renders Sidebar.html as the docked sidebar UI shown inside Google Docs.
PropertiesService Google Apps Script built-in service Provides document-scoped storage for a user-supplied API key as a fallback path (currently bypassed by the hardcoded demo key).
UrlFetchApp Google Apps Script built-in service Makes the outbound HTTPS POST request to the OpenAI API from within the Apps Script sandbox.
Role
Design Engineer
Tools
Google Apps Script OpenAI API GPT-4o Google Docs
Video thumbnail for AI Speech Outline Generator