Flow Preview
Private Start CaptchaGroup Join Gate
Overview
Verify that a user is human with the built-in CAPTCHA action: a private /start captcha and a group join gate that mutes new members until they press the right emoji.
Who It's For
The user wants to protect a bot or a Telegram group from bots and spam with a press-the-right-emoji captcha, either on /start in private chat or when new members join a group.
Setup Requirements
- Should the captcha run in private chat on /start, on group joins, or both?
- How many wrong attempts are allowed before the user fails?
- What should happen on failure: remove the member from the group, mute them, or just take the Failure branch?
- For the group gate: add the bot to the group as an admin with the "Restrict members" permission.
- Publish the flows and test in a private chat with /start, then with a test account joining the group.
- Tune the action settings to taste: number of emoji, grid width, attempts, time limit, and what happens on failure.
Node Breakdown
- Trigger fires: /start command in private chat, or a chat_member join event in a group
- A single CAPTCHA action (inside an ACTION block) does everything: sends "press the ➡️ Apple" with a shuffled emoji grid, verifies the press, regenerates a fresh grid on wrong answers, counts attempts, and applies the optional timeout
- Group extras are action settings, not extra blocks: mute-while-verifying, kick/mute on fail, delete the challenge message when done
- The ACTION block's Success path continues after a pass (welcome message); its Failure branch handles rejected users
Details
Good to know
- CAPTCHA is a built-in ACTION type (like Delay or Set Variable). Put it in its own ACTION block; the block's two paths are wired with create_link conditionBranch: TRUE/none = passed (Success), FALSE = failed (Failure). Do NOT assemble captchas from SET_VARIABLE/CONDITION/dynamic-button chains.
- All behavior is the action's config: optionsCount (4-9 emoji), buttonsPerRow (grid width, default 3), maxAttempts, timeoutSeconds (auto-fail when unanswered), failAction NONE/KICK/MUTE, muteWhileVerifying, deleteOnFinish, and an optional promptText intro line.
- The challenge text and emoji names are localized automatically (Russian/English) from the user's Telegram language; promptText overrides only the intro line.
- Group gate: the bot must be a group admin with the "Restrict members" permission — chat_member join events only reach admin bots, and mute/kick need that right.
- Group gate limitation: the flow contact is the group chat, so only one captcha per group can be pending at a time and simultaneous joins can interfere. The action itself ignores presses from anyone but the challenged member. For high-traffic groups prefer the private /start variant.
- In private chats failAction and muteWhileVerifying are ignored — the Failure branch is the only consequence.
Keep in mind
- Do not build the captcha from SET_VARIABLE/CONDITION/dynamic-button chains or a module — the CAPTCHA action does the whole challenge-verify-retry loop internally.
- Do not add separate restrict/unrestrict action blocks around the captcha — muteWhileVerifying and failAction cover group enforcement.
- Do not use the group gate for high-traffic groups without mentioning the one-pending-captcha-per-group limitation.
- Do not promise the group gate works without admin rights — chat_member events require the bot to be a group admin.
