IntegrationsAdvanced

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.

12 minAdvanced

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.

reply.py
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 out

Step 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.

reply.py
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.

reply.py
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.")
zsh — comment approval loop
You
maya_builds: love this, what saw did you use?
Agent
Reply -> Thanks! It was a basic 10 inch miter saw, nothing fancy. Post? (y/n)
You
y
Agent
Posted.
Each draft waits for a y or n before anything is posted.
Never fully automate replies
Auto-posting without review invites embarrassment and can look like spam to YouTube. Keep the approval prompt, or at minimum log drafts to review in a batch.

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

Tags
#comments#claude#api#moderation#youtube