---
name: replai
description: Operate SayWink, the Instagram "comment a keyword, get a DM" automation, through its MCP tools (list_accounts, get_setup_status, list_posts, create_rule, preview_rule, test_comment, set_rule_active, get_stats, list_events, list_handoffs, resume_conversation). Use when the user wants to auto-reply to Instagram comments with a DM, send a link to people who comment a word like "LINK" or "QUERO", set up or edit a comment-to-DM rule, check how those automations perform, see who asked for a human, or fix SayWink not sending DMs. Also use when SayWink tools are missing and need to be connected.
---

# SayWink: Instagram comment → DM automations

SayWink watches the owner's Instagram posts. When someone comments a keyword, it (optionally) replies
publicly, sends a private DM with a button, and delivers a link after the person taps or answers.
The API key belongs to an **owner**, who may have connected several Instagram professional accounts
(up to their plan's limit). The key reaches all of them and nothing else. `list_accounts` lists them
and shows the key's **default** account; every other tool takes an optional `account` (username,
with or without `@`, or `ig_user_id`) and uses the default when it's omitted. Results always name
the account they acted on.

## 0. Are the tools connected?

Look for tools named `list_accounts`, `get_setup_status`, `create_rule` and so on, possibly prefixed (e.g. `mcp__replai__…`).
If they are missing, the MCP server is not connected. Tell the user:

1. Open the SayWink dashboard and create an API key (`rpl_…`, shown once).
2. Add the remote MCP server: Streamable HTTP, URL `<REPLAI_URL>/mcp` (the same host this skill came
   from), header `Authorization: Bearer rpl_…`.
   - Claude Code: `claude mcp add --transport http --scope user replai <REPLAI_URL>/mcp --header "Authorization: Bearer rpl_…"`
   - Other clients (Claude Desktop, Codex, Cursor, Gemini CLI, VS Code, Windsurf): the dashboard
     has a copy-paste snippet for each one.
3. Restart or reload the client and check the tools appear (`/mcp` in Claude Code).

Never ask the user to paste the key into the chat. If they do, don't repeat it back.

## 1. Workflow

Follow this order. Don't skip the preview and the test before turning a rule on.

0. **`list_accounts`**: if there is more than one account, ask which one the owner means (name the
   default) and pass it as `account` to **every** call of the task. Rule ids and `media_id`s belong
   to one account, so never mix them across accounts. With a single account, just go on.
1. **`get_setup_status`**: connected, webhook subscribed, token valid, days left, rules active. If it
   lists `next_steps`, deal with those first (see Troubleshooting).
2. **`list_posts`**: show the recent posts (date + caption start) and ask which one. Use the
   `media_id` it returns; **never invent one**. `media_id: null` means "every post". A rule for a
   specific post wins over an every-post rule.
3. **Gather what's missing**, in one short question: keyword(s), the link (`link_url`), what the
   link is ("the free guide", "the discount code"…), tone, and the follow mode (section 3). If the
   owner hasn't said, use the soft invite.
4. **Draft the copy** in the owner's language: match the language they write to you in, or their
   captions (Portuguese captions → Portuguese DMs). Templates are in [templates.md](templates.md).
5. **`preview_rule`** with `rule: {…draft…}`: show the owner the exact messages, step by step.
   Adjust until they're happy.
6. **`create_rule`**. It is created **inactive** unless you pass `active: true`.
7. **`test_comment`**: run it with one comment that should match (e.g. "eu quero o LINK!") and one
   that shouldn't. Nothing is sent and nothing is logged.
8. **`set_rule_active`** `{id, active: true}`, only after the owner says yes. Tell them to try it
   from another account (see the dev-mode note under Troubleshooting).
9. Later: **`get_stats`** (funnel: comments → DMs → taps → asked to follow → links, errors),
   **`list_events`** (filter by `rule_id` / `kind`, e.g. `kind: "error"`), **`list_handoffs`**.

Other tools: `get_account`, `list_rules`, `get_rule`, `update_rule` (only the fields you pass
change), `delete_rule`. Ask before deleting; `set_rule_active false` is the reversible option.

## 2. Rule fields

| Field | Notes |
|---|---|
| `name` | Internal, ≤ 80 chars, e.g. "Free guide · launch reel" |
| `media_id` | From `list_posts`, or `null` for every post |
| `keywords` | 1–20 words, ≤ 40 chars each. Case, accents and punctuation are ignored; a keyword must appear as a whole word. Add variants: `["link", "quero", "eu quero"]` |
| `public_replies` | 0–10 public replies under the comment, one picked at random. Vary them so they don't look spammy |
| `opening_text` + `opening_button` | First DM (the private reply) and its button label |
| `require_follow` | `false` = soft invite (default, recommended). `true` = hard gate. See section 3 |
| `follow_text` + `follow_button` | Follow invitation (soft) or condition (hard gate) + re-check button |
| `link_text`, `link_url`, `link_button` | The DM that delivers the link |
| `disclose_automation` | Default `true`: adds "automated message · reply HUMAN to talk to a person" to the first DM. Keep it on |
| `active` | On/off |

Omitted texts get friendly English defaults. Write your own copy whenever the owner isn't writing in English.

## 3. Follow mode: soft invite or hard gate

- **Soft invite (`require_follow: false`, the default and the one to recommend).** Everyone gets the
  link. People who don't follow also get `follow_text` as a friendly invitation after the link.
- **Hard gate (`require_follow: true`).** The link only goes to followers. Others get `follow_text`
  with a re-check button (`follow_button`) until they follow.

**Policy caveat, which you must tell the owner if they ask for a hard gate:** Meta's spam Community
Standards forbid requiring people to engage, follows included, to get access to content
("follow-gating"). A hard gate risks App Review rejection and enforcement on the account. It's the
owner's call. Ask them; don't choose it for them. If they insist, set it and repeat the warning once.

**Consent rule.** Instagram only lets SayWink check whether someone follows after that person has
messaged the account: they typed a reply or tapped a quick-reply button. A comment alone isn't
enough. That is why the flow is comment → first DM with a button → tap/reply → follow check → link.
If the check fails ("User consent is required"), the soft invite still sends the link, and the
hard gate asks the person to reply first.

## 4. Human handoff

If a person's DM contains a word like *human, humano, person, pessoa, agent, atendente, suporte,
support*, SayWink pauses the automation for that person, logs `human_requested`, and sends nothing
more. `list_handoffs` shows who is waiting. The owner answers them in the Instagram inbox.
`resume_conversation {igsid}` gives the person back to the automation. Ask the owner first.
Mention waiting handoffs whenever you review stats.

## 5. Writing DMs that work

- **Short.** One or two sentences per message. People read these on a phone, often in the Requests
  folder.
- **One clear call to action** per message, matching the button: "Tap below and I'll send it" with
  the button "Send me the link".
- **Say what they get**: "the free 7-day plan", not "the thing".
- **Disclose the automation.** Keep `disclose_automation` on, and don't pretend to be a person.
- **Buttons ≤ 20 characters** (Instagram's limit). Use a verb: "Quero o link", "Send it", "Open".
- **Keyword in the caption.** Remind the owner to tell people what to comment ("Comment GUIDE and
  I'll DM you").
- **Public replies** should sound human and vary ("Sent you a DM 📩", "Check your DMs ✨"). Never put
  the link in a public reply.
- Hard gate only: make `follow_text` honest ("Follow, then tap 'I followed'").

## 6. Instagram limits (SayWink enforces them, but plan around them)

- **One private reply per comment**, within **7 days** of the comment. That is the first DM.
- After the person taps or answers, a **24-hour window** opens for the rest of the conversation (link,
  follow invitation). SayWink replies within seconds; Meta requires bots to answer within 30 s.
- **Button and quick-reply labels: ≤ 20 characters.** `link_text` is shown with a button, so keep it
  **≤ 640 characters**. Keep every DM under ~900 characters (Instagram caps text at 1,000 bytes, and
  the disclosure note adds some).
- The first DM lands in **Requests** for non-followers, and buttons may not render there. SayWink then
  falls back to plain text asking them to reply. Write `opening_text` so it still makes sense
  without the button ("Reply with any message and I'll send it").
- Each person gets the link at most 3 times per rule. The first DM goes once per person per rule.

## 7. Troubleshooting

Start with `get_setup_status`, then `list_events {kind: "error"}`.

| Symptom | Cause → fix |
|---|---|
| `webhook_subscribed: false` | Comments never reach SayWink. The owner reconnects Instagram in the dashboard |
| `token_valid: false` / token expired | The owner reconnects Instagram in the dashboard (the token stops working when access is removed in Meta's Business settings or the password changes) |
| `Account "…" is not available to this API key` | That account isn't connected by this key's owner. Use one of the usernames in the error (or `list_accounts`); to add an account, the owner connects it in the dashboard (within the plan's limit) |
| Comments arrive but no DM, error mentions messaging/permission | In the Instagram app: **Settings → Messages and story replies → Message controls → Connected tools → Allow access to messages** must be on |
| No comment events at all | The account must be **public** and a **professional** (Business/Creator) account. Comments by the account itself are ignored. Check the rule is active and the keyword is a whole word (`test_comment`) |
| Works for the owner's test account, nobody else gets DMs | The Meta app is in **development mode / Standard Access**: only people with a role on the app (testers) get DMs. Production needs App Review + Business Verification (Advanced Access) |
| "User consent is required" | Normal before the person replies. See the consent rule in section 3 |
| Same person gets nothing on a second comment | Expected: one first DM per person per rule (dedupe) |
| A person stopped getting answers | They asked for a human. `list_handoffs`, then `resume_conversation` if the owner agrees |
| Button missing in the DM | Instagram refused it, probably a non-follower in Requests. The plain-text fallback was sent |

When you report errors, quote the event's `detail` (step, message, code) and explain it in plain
words. Don't retry by spamming tools; one check, then tell the owner what to do.
