How to Auto-Draft Replies to YouTube Comments with Claude
Pull recent comments through the Data API, draft on-brand replies with Claude, and post them back, with a human approval gate.
Replying to every comment keeps a channel alive but eats hours. This guide reads recent top-level comments with the YouTube Data API, drafts replies with Claude in your voice, prints them for approval, and only posts the ones you confirm.
What you need
- client_secret.json with the youtube.force-ssl scope
- An Anthropic API key
- Python 3.9+ with the google client and anthropic packages
- A video id whose comments you want to handle
Step 1: Fetch recent comments
The commentThreads.list endpoint returns top-level comments. Keep the comment id so you can thread your reply onto it later.
from upload import service # reuse auth helper
def recent_comments(video_id, limit=10):
yt = service()
res = yt.commentThreads().list(
part="snippet", videoId=video_id, maxResults=limit, order="time",
).execute()
out = []
for item in res.get("items", []):
top = item["snippet"]["topLevelComment"]
out.append({
"id": top["id"],
"text": top["snippet"]["textDisplay"],
"author": top["snippet"]["authorDisplayName"],
})
return outStep 2: Draft replies with Claude
Give Claude a short persona and pass it the comment. Ask for a one or two sentence reply and a flag when a comment is hostile or spam so you can skip it.
import os, json
from anthropic import Anthropic
ai = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
SYSTEM = (
"You reply to YouTube comments as a friendly maker channel host. "
"Return JSON: {reply: string, skip: boolean}. "
"Set skip true for spam, hostility, or anything needing a human."
)
def draft(comment_text):
msg = ai.messages.create(
model="claude-opus-4-5", max_tokens=300, system=SYSTEM,
messages=[{"role": "user", "content": comment_text}],
)
return json.loads(msg.content[0].text)Step 3: Approve, then post
Print each draft, ask for a y or n, and only call comments.insert for the approved ones. This keeps a human in the loop, which matters because a bad auto-reply is public and permanent.
def post_reply(parent_id, text):
service().comments().insert(
part="snippet",
body={"snippet": {"parentId": parent_id, "textOriginal": text}},
).execute()
if __name__ == "__main__":
for c in recent_comments("dQw4w9WgXcQ"):
d = draft(c["text"])
if d["skip"]:
print("SKIP:", c["text"][:50]); continue
print(f"\n{c['author']}: {c['text']}")
print("Reply ->", d["reply"])
if input("Post? (y/n) ").lower() == "y":
post_reply(c["id"], d["reply"])
print("Posted.")Result
You can clear a backlog of comments in minutes: Claude drafts, you tap y or n, and only your approved replies go live under your channel name.
Watch related tutorials
1:42:18
28:14
41:09
9:47
8:23
52:31