Skip to the content.

Reply to unanswered Skool posts automatically

Your community’s worst experience: a member posts a question, no one answers for 24 hours, they conclude “this place is dead” and stop coming back. This recipe finds posts with 0 comments and drafts an on-brand reply via LLM, with optional human approval before publishing.

Production version of this is what keeps engagement at 40% in Cágala, Aprende, Repite.

What you’ll build

[n8n schedule] ─→ posts:filter (unanswered=true, since=24h ago)
                      ↓
                  for each post:
                      ↓
                  LLM drafts reply
                  (Claude / GPT-4o)
                      ↓
                  Telegram approval
                      ↓
                  posts:createComment
                  (rootId=postId, parentId=postId)
                      ↓
                  Log to NocoDB / Sheets

Prerequisites

Step 1 — Find unanswered posts

{
  "action": "posts:filter",
  "cookies": "...",
  "groupSlug": "your-community",
  "params": {
    "unanswered": true,
    "since": "{{ $now.minus({hours: 24}).toISO() }}",
    "limit": 50
  }
}

since is ISO 8601. Tune the window to your community’s pace — for slower communities use 48h, for faster ones 6h.

Step 2 — Filter by relevance

Not every unanswered post should get an auto-reply. In an n8n Function or Filter node, skip:

const post = $json;

// Skip very recent posts (give humans a chance first)
const ageMin = (Date.now() - new Date(post.createdAt).getTime()) / 60000;
if (ageMin < 60) return false;  // wait 1h before auto-reply

// Skip posts that look like announcements (length, all-caps, etc.)
if (post.content.length < 30) return false;

// Skip if the author has already gotten replies (engaged member)
// (would need a members:list lookup — optional)

return true;

Step 3 — Draft via LLM

Construct a prompt with the post content, your brand voice, and clear constraints:

You are a helpful, concise community moderator for {community_name}.

Brand voice: {brand_voice_summary}
Examples of good replies you wrote previously: {3 examples}

A new post has been unanswered for {hours} hours. Draft a reply that:
- Is at most 2 short paragraphs
- Asks a clarifying follow-up if the post is vague
- References specific community resources when relevant (link to a course, a recipe, a previous post)
- Does NOT promise something the community can't deliver
- Sounds human, not corporate

Post title: {post.title}
Post body: {post.content}
Author first name: {post.author.firstName}

Respond with the reply text only. Plain text. No HTML.

Returns a draft. Keep prompt + draft for the audit log.

Send draft to Telegram with two reply commands:

📝 Draft reply for "{post.title}" by {post.author.firstName}:

{draft}

Approve: /yes_{shortId}
Edit:    /edit_{shortId}
Reject:  /no_{shortId}

Wait for response. Only on /yes proceed. Keep the draft + decision in your audit table — useful for prompt iteration.

For lower-stakes communities you can skip approval and publish directly. For the first 100 auto-replies, always require approval so you can catch tone drift before it becomes a brand problem.

Step 5 — Publish the comment

Top-level comment on the post:

{
  "action": "posts:createComment",
  "cookies": "...",
  "groupSlug": "your-community",
  "params": {
    "rootId": "",
    "parentId": "",
    "content": ""
  }
}

For top-level comments, rootId == parentId == postId (see posts docs).

Step 6 — Log

Save to NocoDB / Sheets:

postId author draft approved published publishedAt

Useful for:

Production gotchas

Don’t reply to your own posts

posts:filter returns ALL unanswered posts including yours. Filter post.author.id !== selfUserId early.

Don’t reply to comments — only top-level posts

posts:filter returns posts. To find unanswered comments inside an active post, you’d use posts:getComments and look for replies-to-comments with no further responses. That’s a different recipe (and usually not worth automating).

Mention the author in your reply (optional)

Add [@FirstName Lastname](obj://user/{authorId}) at the start. The author gets a notification, which dramatically increases the chance they engage back.

Hey [@John Smith](obj://user/abc123...) — quick thought on this:

{draft body}

Rate limit yourself

The actor’s rate limiter caps you at ~25 writes/min. If you have a backlog of 50 unanswered posts, the workflow batches naturally — no special handling needed. But don’t run two instances of the same workflow concurrently against the same group.

Avoid LLM hallucinations

If the LLM draft references a specific course, member, or fact, verify it exists before publishing. A regex check against your courses list (classroom:listCourses) catches the most common case (“check out the course on X” where course X doesn’t exist).

See also