Skip to content

/blog-audio

Paid Gemini TTS audio for a finished blog post: summary, full read-aloud, or two-speaker dialogue, with an MP3 and an HTML5 embed. Asks for explicit consent before the first paid call. Runs only on an explicit request: /blog audio, "generate audio for this blog post", "narrate

From plugin
claude-blog
2.6k32 skills20 agents

Claude Code

$ npx -y skills add AgriciDaniel/claude-blog --skill blog-audio --agent claude-code

SKILL.md

blog-audio.SKILL.md
name: blog-audio
description: >
  Paid Gemini TTS audio for a finished blog post: summary, full read-aloud,
  or two-speaker dialogue, with an MP3 and an HTML5 embed. Asks for explicit
  consent before the first paid call. Runs only on an explicit request:
  /blog audio, "generate audio for this blog post", "narrate this blog post",
  "audio version of this post", or "podcast version of this post". Not for
  general speech or dictation questions.
user-invocable: true
argument-hint: "[generate|voices|setup] [file-or-text] [--mode summary|full|dialogue] [--voice name]"
license: MIT
metadata:
  author: AgriciDaniel
  version: "2.3.2"

Blog Audio: Gemini TTS Narration for Blog Posts

Bundled paths below use host Markdown substitution of `${CLAUDE_SKILL_DIR}`; it is not an exported shell variable. Resolve them before execution, quote paths, and refuse nonabsolute overrides. Pass `blog_reference_root` resolved from `${CLAUDE_SKILL_DIR}/../blog/references`, `blog_template_root` from `${CLAUDE_SKILL_DIR}/../blog/templates`, and needed sibling roots to agents. Read the main reference `orchestration-details.md` before loading project context; pass only its helper-fenced output to downstream agents.

Generate professional audio narration of blog content using Google's Gemini TTS. Three modes: summary (200-300 word spoken overview), full article read-aloud, or two-speaker podcast dialogue. 30 prebuilt voices, over 130 languages on Gemini 3.8 Flash TTS (over 100 on Flash-Lite), HTML5 embed output. Dated model, pricing and language facts live in `${CLAUDE_SKILL_DIR}/references/models.md`.

Cost and consent gate (mandatory, read first)

This skill spends the user's Google AI credit and writes audio files.

  • **What it spends:** one paid Gemini TTS call per text chunk. Long text is

split into chunks, so a full read-aloud costs several calls. The script's `--max-chunks` flag caps the chunks per run (default 12); never raise it without telling the user the new worst-case cost.

  • **Cost basis:** audio output tokens at 25 tokens per second of audio, priced

per model (rates and their checked date are in `references/models.md`; re-read https://ai.google.dev/gemini-api/docs/pricing before quoting a number). Run `--dry-run --json` first for the script's estimate.

  • **What it writes:** the audio file under `audio/` (or `--output`) and, in

setup only, the managed `.venv`.

  • **Consent:** before the FIRST paid call in a session, state the mode, model,

chunk count, and estimated cost, then wait for an explicit yes. The yes covers only that run. Writing a blog post does not consent to audio.

  • **No uncapped spend:** never retry or loop on paid calls beyond the cap;

one retry on a transient error, then report.

  • **Skips:** if the user declines, the key is missing, or setup is absent,

skip and return ONE line for the orchestrator's "Fallbacks and skips" summary, such as "Audio: no API key set, skipped".

Quick Reference

| Command | What it does | |---------|-------------| | `/blog audio generate <file>` | Generate audio narration of a blog post | | `/blog audio voices` | Show available voices with characteristics | | `/blog audio setup` | Check/configure API key for Gemini TTS |

Prerequisites

  • Python 3.11+; the explicit setup action owns the managed venv
  • `GOOGLE_AI_API_KEY` or `GEMINI_API_KEY` environment variable (`GOOGLE_AI_API_KEY` is the one blog-image uses; the audio script accepts either)
  • FFmpeg (for WAV-to-MP3 conversion; falls back to WAV if missing). Never install it implicitly; tell the user and let them install it

Persistent runtime directory

`CLAUDE_BLOG_RUNTIME_DIR` optionally selects one trusted absolute persistent root. This integration uses `<root>/blog-audio/.venv`; NotebookLM also uses `<root>/blog-notebooklm/data` for its library, authentication and browser state. Without this override, the existing skill-local defaults stay in use. Google's shared credential config/token paths stay unchanged. No state is copied or migrated automatically, and ordinary runs never perform setup.

Preserve an existing validated operator override. For a plugin without one, explicitly pass the host-substituted `${CLAUDE_PLUGIN_DATA}/claude-blog-runtime` path on both setup and every later runner call. This is Markdown substitution, not an exported shell variable. Execute only once it is an absolute resolved path. Single quotes keep an unresolved placeholder literal so validation rejects it instead of expanding it to a different shell path:

CLAUDE_BLOG_RUNTIME_DIR='${CLAUDE_PLUGIN_DATA}/claude-blog-runtime' python3 "${CLAUDE_SKILL_DIR}/scripts/setup_environment.py" --check --json
CLAUDE_BLOG_RUNTIME_DIR='${CLAUDE_PLUGIN_DATA}/claude-blog-runtime' python3 "${CLAUDE_SKILL_DIR}/scripts/run.py" generate_audio.py --help

Only explicit setup without `--check` installs dependencies. Standalone users keep the default unless they explicitly choose an absolute runtime root. Relative, unresolved, or linked managed subdirectories fail closed. Changing the root selects separate state; it never authorizes a migration or cleanup of the old root. Plugin persistent data follows the host's uninstall retention rules; preserve it explicitly when uninstalling if it is still needed.

Use the Installed run.py Wrapper

BLOG_SKILLS_DIR="${CLAUDE_BLOG_SKILLS_DIR:-${CLAUDE_SKILL_DIR}/..}"
case "$BLOG_SKILLS_DIR" in /*) ;; *) echo "ERROR: skills dir must be absolute" >&2; exit 1 ;; esac
AUDIO_RUN="$BLOG_SKILLS_DIR/blog-audio/scripts/run.py"
python3 "$AUDIO_RUN" generate_audio.py --text-file blog_audio_prepared.txt --voice Charon --model flash38 --json

Put prepared narration in a file and pass `--text-file`. If you must use `--text`, follow the shell argument rule in `${CLAUDE_SKILL_DIR}/../blog/SKILL.md` (single quotes, embedded `'` written as `'\''`).

Ordinary generate and voices commands perform a nonmutating capability check. If the managed environment is absent,

Read more
@agricidaniel
Ships withclaude-blog

claude-blog is a Claude Code skill suite that writes, optimizes, audits, localizes, and refreshes blog content at scale. Every article is evaluated for Google-aligned usefulness and internal AI citation readiness heuristics.

Stars on GitHub

Momentum

stars in total
2.6k
Star history of AgriciDaniel/claude-blog on GitHub, a chart by star-history.com

Other skills on claude-blog.

blog-analyze
Auto-invoked

blog-analyze

Score one blog post (or a folder of posts) on a 5-category 100-point scale covering content quality, SEO, E-E-A-T, technical…

blog-audit
Auto-invoked

blog-audit

Full-site blog health assessment scanning all blog files for quality scores, orphan pages, topic cannibalization, stale content,…

blog-brand
Auto-invoked

blog-brand

Establish durable brand and voice context for cross-skill consumption. Generates BRAND.md (audience, positioning, do/don't…

blog-brief
Auto-invoked

blog-brief

Create a content brief for ONE planned post: target and secondary keywords, search intent, template choice, competitor gaps from…

blog-calendar
Auto-invoked

blog-calendar

Build a dated monthly or quarterly editorial calendar: which posts to publish or review when, content mix, templates,…

blog-cannibalization
Auto-invoked

blog-cannibalization

Detect keyword cannibalization across blog posts by extracting primary keywords from titles and headings, clustering semantically…

More skills from other plugins.

prompt-lookup

prompt-lookup

Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use…

@gh-f@gh-fInstall Skill
ppt-master

ppt-master

AI-driven presentation workflow for generating editable PPTX decks and slides, reconstructing page visuals, creating reusable…

@hugohe3@hugohe3Install Skill
morph-ppt

morph-ppt

Use this skill when the user wants a .pptx with smooth cross-slide animation — PowerPoint Morph transitions, Keynote-style…

officecli12d33k
@iofficeai@iofficeaiInstall Skill

Questions about blog-audio.

Which coding agents can use blog-audio?
blog-audio installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.