| name | slides-to-site |
| description | Convert a Google Slides presentation into a psd401.ai presentation page. Takes a Google Slides URL, reads all slide content, asks for metadata, and generates the markdown file. Use when adding presentations to the psd401.ai website. Triggers on: add presentation to site, slides to site, publish presentation, psd401.ai presentation. |
| argument-hint | <google-slides-url> |
| model | claude-opus-5 |
| effort | high |
| allowed-tools | ["Bash","Read","Write","Edit","Glob","Grep"] |
| extended-thinking | true |
Slides to Site
Convert a Google Slides presentation into a psd401.ai presentation page. Reads the full presentation via gws slides, collects metadata from the user, and generates a properly formatted markdown file.
Constants
- psd401.ai repo:
/Users/hagelk/non-ic-code/psd401.ai
- Presentations dir:
/Users/hagelk/non-ic-code/psd401.ai/src/content/presentations/
- Thumbnails dir:
/Users/hagelk/non-ic-code/psd401.ai/public/images/thumbnails/
Workflow
Process each presentation URL the user provides. After each one, ask if they have more. When done, commit and push.
Step 1: Parse the Google Slides URL
Extract the presentation ID from the user-provided URL argument ($ARGUMENTS).
Supported URL formats:
https://docs.google.com/presentation/d/PRESENTATION_ID/edit → extract PRESENTATION_ID
https://docs.google.com/presentation/d/PRESENTATION_ID/pub → extract PRESENTATION_ID
https://docs.google.com/presentation/d/e/2PACX-.../pub → this is a published URL; extract the 2PACX-... portion after /e/
- Just a bare presentation ID
Validate the extracted ID is non-empty. If no URL was provided, ask the user for one.
Step 2: Read the Presentation Content
Run:
gws slides presentations get --params '{"presentationId": "PRESENTATION_ID"}' --format json
Parse the JSON response to extract:
- Title: from
title field at the top level
- All slide text: walk
slides[].pageElements[].shape.text.textElements[].textRun.content and concatenate
- Speaker notes: from
slides[].slideProperties.notesPage.pageElements[].shape.text.textElements[].textRun.content
If gws fails with an auth error, tell the user:
Auth issue detected. Run: gws auth login -s slides,drive
Then try again.
Step 3: Ask User for Metadata
Use AskUserQuestion to collect all metadata in a single prompt. Show the extracted title as a default. Ask for:
I extracted the presentation content. Here's what I need from you:
**Title**: {extracted_title} (press Enter to keep, or type a new one)
**Date** the presentation was/will be given (YYYY-MM-DD):
**Presenters** (comma-separated names):
**Audience** (e.g., "PSD Community", "PSD Staff", "WTA Conference", "WSSDA Conference"):
**Type** (e.g., "School Board Presentation", "Public Workshop", "PD Session", "Conference Session"):
**Description** (1-2 sentences — or type "auto" and I'll generate one from the content):
**Slug** (kebab-case filename, suggested: {auto_slug}) — press Enter to accept or type a new one:
Where {auto_slug} is generated by lowercasing the title, removing non-alphanumeric chars, and converting spaces to hyphens.
If the user says "auto" for description, synthesize a 1-2 sentence summary from the slide content.
Step 4: Generate the Embed URL
Convert the input URL to embed format:
- For standard URLs (
/d/PRESENTATION_ID/): https://docs.google.com/presentation/d/PRESENTATION_ID/embed
- For published URLs (
/d/e/2PACX-.../): https://docs.google.com/presentation/d/e/2PACX-.../embed
Step 5: Export Thumbnail
Auto-generate the thumbnail using the Slides API thumbnail endpoint:
- Extract the first slide's
objectId from the presentation JSON fetched in Step 2 (it's slides[0].objectId)
- Call the thumbnail API:
gws slides presentations pages getThumbnail --params '{"presentationId": "PRESENTATION_ID", "pageObjectId": "FIRST_SLIDE_OBJECT_ID"}' --format json
- Parse the
contentUrl from the JSON response
- Download it with curl:
curl -sL -o /Users/hagelk/non-ic-code/psd401.ai/public/images/thumbnails/{slug}.png "CONTENT_URL"
- Verify the file was created and is a valid PNG using
file command
If any step fails (permissions, auth, etc.), inform the user:
Could not auto-generate thumbnail. Please manually save the first slide as:
/Users/hagelk/non-ic-code/psd401.ai/public/images/thumbnails/{slug}.png
Set the thumbnail path in frontmatter regardless: /images/thumbnails/{slug}.png
Step 6: Generate Markdown Content
Using the full slide text content, generate the markdown body. Follow the exact format used by existing presentations in the repo.
Structure:
- Bold title — repeats the frontmatter title
- Context paragraph — who presented, when, where, to whom, and a summary of what the presentation covers
- Key Takeaways — 4-7 bullet points with bold headers followed by details, extracted/synthesized from actual slide content
- Actionable Insights — 3-5 bullet points with bold headers and practical recommendations
- Looking Ahead — 1 paragraph on future directions or implications
Step 7: Write the File
Assemble the complete markdown file using this exact template:
---
title: '{title}'
date: '{YYYY-MM-DD}'
presenters:
- '{Presenter 1}'
- '{Presenter 2}'
audience: '{audience}'
type: '{type}'
thumbnail: '/images/thumbnails/{slug}.png'
slides: '{embed_url}'
description: '{description}'
---
**{Title}**
{Context paragraph — who presented this, when, where, to what audience, and what it covers.}
**Key Takeaways:**
- **{Point 1 Header}:** {Details synthesized from slide content}
- **{Point 2 Header}:** {Details synthesized from slide content}
- **{Point 3 Header}:** {Details synthesized from slide content}
- **{Point 4 Header}:** {Details synthesized from slide content}
**Actionable Insights:**
- **{Insight 1}:** {Practical recommendation}
- **{Insight 2}:** {Practical recommendation}
- **{Insight 3}:** {Practical recommendation}
**Looking Ahead:**
{Future directions paragraph — what comes next, implications, or next steps.}
Critical formatting rules:
- Frontmatter values with colons or special chars MUST be wrapped in single quotes
- Each presenter gets its own
- 'Name' line under presenters:
- No
tags: field — the site derives tags from presenters, type, and audience
- One blank line between each section
- Use
**bold** for section headers and bullet point leaders
Write the file to: /Users/hagelk/non-ic-code/psd401.ai/src/content/presentations/{slug}.md
After writing, read the file back to verify it was created correctly and frontmatter is valid.
Show the user:
✓ Created: src/content/presentations/{slug}.md
Title: {title}
Presenters: {presenters}
Slides embed: {embed_url}
Step 8: Ask for More Presentations
Ask the user:
Do you have more presentations to add, or should I commit and push?
- If they have more → loop back to Step 1 with the next URL
- If done → proceed to Step 9
Keep track of all slugs created in this session for the commit.
Step 9: Commit and Push to Deploy
Once the user confirms they're done:
cd /Users/hagelk/non-ic-code/psd401.ai
git add src/content/presentations/{all-slugs}.md public/images/thumbnails/{all-slugs}.png
git commit -m "content: add presentation(s) — {title(s)}"
git push origin main
After pushing, inform the user:
Pushed to main. AWS Amplify will auto-deploy the changes.
New presentation(s) will be live at psd401.ai/presentations shortly.
If any thumbnail files don't exist (manual export needed), only git add the markdown files and remind the user to add thumbnails later.