Claude
Skills
Sign in
Back

slides-to-site

Included with Lifetime
$97 forever

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.

Writing & Docs

What this skill does


# 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:
```bash
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:

1. Extract the first slide's `objectId` from the presentation JSON fetched in Step 2 (it's `slides[0].objectId`)
2. Call the thumbnail API:
```bash
gws slides presentations pages getThumbnail --params '{"presentationId": "PRESENTATION_ID", "pageObjectId": "FIRST_SLIDE_OBJECT_ID"}' --format json
```
3. Parse the `contentUrl` from the JSON response
4. Download it with curl:
```bash
curl -sL -o /Users/hagelk/non-ic-code/psd401.ai/public/images/thumbnails/{slug}.png "CONTENT_URL"
```
5. 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:**
1. **Bold title** — repeats the frontmatter title
2. **Context paragraph** — who presented, when, where, to whom, and a summary of what the presentation covers
3. **Key Takeaways** — 4-7 bullet points with **bold headers** followed by details, extracted/synthesized from actual slide content
4. **Actionable Insights** — 3-5 bullet points with **bold headers** and practical recommendations
5. **Looking Ahead** — 1 paragraph on future directions or implications

### Step 7: Write the File

Assemble the complete markdown file using this exact template:

```markdown
---
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:

```bash
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.

Related in Writing & Docs