n8n Telegram and WhatsApp Approval for AI Agents

Iiro Rahkonen

TL;DR: Telegram and WhatsApp are natural approval channels for reviewers who live on mobile. n8n ships Send and Wait for Response on both, which covers most cases in a single node. Past that, you have inline-keyboard DIY with Wait for Webhook — plus channel-specific gotchas (Telegram users must /start the bot first; WhatsApp has a 24-hour messaging window and template-only rules outside it). This post walks through both native and DIY patterns, plus a managed-inbox approach that keeps messaging as notification without hardcoding chat IDs into every workflow.


If your reviewer is a founder, an agency client, or anyone whose work day is half in messaging apps, Slack is the wrong place to put their approvals. They are not in Slack. They are in Telegram, and they are in WhatsApp — especially outside North America, where WhatsApp is often the primary business channel.

This is why the "n8n AI content approval via Telegram" pattern has exploded in community content over the last year. Builders want to review the AI's LinkedIn post while waiting for coffee. They want to approve the AI-drafted customer reply from their phone, not by opening Slack on the laptop. The use case is right. The implementation is trickier than it looks.

This post walks through the two patterns for building n8n approval workflows on Telegram and WhatsApp — the native Send and Wait for Response node, and the inline-keyboard + Wait for Webhook variant when you need more control — plus the channel-specific edges each brings. At the end, an honest look at when messaging-as-reviewer-channel starts to hurt and why a managed inbox that uses messaging as a notification layer ends up fitting better.


Why messaging-first reviewers are a real audience

Three non-trivial reasons the reviewer channel matters.

Where the reviewer actually lives. A founder reviewing the AI's outbound emails is not going to open Slack every time. They check WhatsApp between meetings. If the approval lands there, it gets handled.

Mobile-first interaction. Telegram and WhatsApp are built for the phone. Messages are short, actions are one tap. A reviewer handling ten approvals per day from the phone is faster than a reviewer who has to switch to a laptop to click into Slack.

Regional reality. Parts of Europe, all of Latin America, most of Africa, the Middle East, and South/Southeast Asia run business-critical communication on WhatsApp. If your customer or your client's reviewer is there, that is the channel. Forcing them to a Western-default tool just to approve a workflow step is how a project stalls.

The cost of doing approvals in these channels is not zero — the edges show up below — but the user-experience upside is big enough that most builders keep trying. This post is the shortcut through the edges.


Pattern 1: Native Send and Wait for Response on Telegram / WhatsApp

The fastest working approval you can build for a messaging-first reviewer. One node per channel, the buttons render inline in the chat, the response lands back on $json. This is the right starting point.

Telegram setup

Node: Telegram
Resource: Message
Operation: Send and Wait for Response
Chat ID: 1234567890                      # or expression for dynamic routing
Message: "AI-drafted LinkedIn post for review:\n\n{{ $json.draft }}"
Response Type: Approval                  # Approval | Free Text | Custom Form
Approval Options: Publish / Reject
Limit Wait Time: On (24h)
On Timeout: Continue (separate output)

What this produces in Telegram:

  • The reviewer receives a Telegram message with two inline-keyboard buttons (Publish / Reject).
  • Tapping a button sends the decision back to n8n; the workflow resumes on the chosen output.
  • For Custom Form, tapping the button opens a link to an n8n-hosted form where the reviewer can edit fields before submitting.

WhatsApp setup

Node: WhatsApp Business Cloud
Resource: Message
Operation: Send and Wait for Response
Phone Number ID: {{ $env.WHATSAPP_PHONE_ID }}
Recipient: +1234567890                   # reviewer's WhatsApp number (E.164)
Message: "Refund approval needed:\n{{ $json.customer }} — ${{ $json.amount }}\nReason: {{ $json.reason }}"
Response Type: Approval
Approval Options: Approve / Reject
Limit Wait Time: On (4h)

WhatsApp's Send-and-Wait uses interactive message buttons behind the scenes. Outside an active 24-hour window, WhatsApp requires pre-approved template messages — that is the big constraint to plan around (more below).

Three response types, same as Slack

  • Approval. One-tap inline buttons. Fastest reviewer path.
  • Free Text. Reviewer replies with plain text. Useful for "approve with rationale" or short freeform decisions.
  • Custom Form. Fields you define, pre-filled with the AI output, editable before submit. Best for "approve with edits" without building a form yourself.

What works well here

Most approval workflows on Telegram or WhatsApp can live entirely on the native node. One reviewer, a fixed channel, short messages — this is the 80% case and it ships fast.

Where the cracks show

Telegram: the /start requirement. A Telegram bot cannot DM a user who has never started a conversation with it. New reviewer? Onboarding step: they have to open the bot and tap /start before the first approval can deliver. Silent delivery failures on a new rotation are almost always this.

WhatsApp: the 24-hour messaging window. WhatsApp Business only lets you freely message a user within 24 hours of their last inbound message to your business. Outside that window, you can only send template messages — pre-approved, pre-formatted content that Meta has signed off on. This has two consequences:

  • Your approval request outside a 24h window has to be a template. Freeform AI content does not fit the template constraint well.
  • If a reviewer goes silent for more than 24 hours, the next approval you send them must start from a template.

Chat IDs are hardcoded per node. Telegram wants a numeric chat_id; WhatsApp wants an E.164 phone number. Every Send-and-Wait node has a specific recipient. Adding a reviewer means editing the workflow. Rotating reviewers weekly means editing the workflow.

No cross-workflow inbox. A reviewer handling approvals across five workflows sees five separate Telegram conversations (or five WhatsApp threads). No single view of everything pending.

Mobile context is limited. A rich review — "here is the AI draft plus the CRM record plus the prompt it saw" — is a lot to scroll through on a phone. The native node's message body is the only context the reviewer gets unless you wire up additional sends.

Verdict. Use the native node for the first workflow or two. Shipping takes minutes. The edges below only become painful once volume, reviewer count, or context density grow.

Onboard new Telegram reviewers by having them /start your bot before their first approval. A reviewer added to a rotation who has not /started will silently miss messages. Add this as a one-line step in your reviewer onboarding doc and you prevent a class of bug that is otherwise invisible.

If Pattern 1 is already hitting the edges for you, join the early-access list for Humangent — Pattern 3 below is a design direction, and the beta is how the shape gets decided with real users.


Pattern 2: Inline keyboards + Wait for Webhook

When you need richer context, custom actions beyond approve/reject, or dynamic routing, the native node runs out of room. Pattern 2 drops to the raw messaging APIs (Telegram Bot API's sendMessage with inline_keyboard, or WhatsApp's interactive message type) and wires the callback manually through Wait for Webhook.

Telegram: inline keyboard with callback

Posting the message with inline buttons.

Node: HTTP Request
Method: POST
URL: https://api.telegram.org/bot{{ $env.TG_BOT_TOKEN }}/sendMessage
Body (JSON):
{
  "chat_id": "{{ $json.reviewer_chat_id }}",
  "text": "📝 AI post ready for review:\n\n{{ $json.draft }}",
  "parse_mode": "Markdown",
  "reply_markup": {
    "inline_keyboard": [
      [
        { "text": "✅ Publish",  "callback_data": "publish:{{ $json.requestId }}" },
        { "text": "❌ Reject",   "callback_data": "reject:{{ $json.requestId }}" }
      ],
      [
        { "text": "✏️ Edit",    "callback_data": "edit:{{ $json.requestId }}" }
      ]
    ]
  }
}

Receiving the callback via a separate listener workflow:

Workflow B (listener):
  Telegram Trigger (Updates: callback_query)
    -> Parse callback_data into action + requestId
    -> Answer the callback_query (so Telegram removes the loading spinner on the button)
    -> HTTP Request to the paused Wait URL of the approval workflow
         URL: https://your-n8n.com/webhook/approval/{{ $json.requestId }}
         Body: { "action": "{{ $json.action }}", "user": "{{ $json.from.username }}" }

Like the Slack Block Kit pattern, this runs as two workflows. The dispatcher sends the message and pauses; the listener catches Telegram's callback and unblocks the paused workflow via its unique Wait URL. Trying to do both in one linear workflow runs into the same "two triggers in one workflow" limitation.

WhatsApp: interactive message

WhatsApp's equivalent is the interactive message type with button or list reply options.

Node: HTTP Request
Method: POST
URL: https://graph.facebook.com/v20.0/{{ $env.WA_PHONE_ID }}/messages
Headers:
  Authorization: Bearer {{ $env.WA_TOKEN }}
  Content-Type: application/json
Body (JSON):
{
  "messaging_product": "whatsapp",
  "to": "{{ $json.reviewer_phone }}",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "body": { "text": "Refund: ${{ $json.amount }} — {{ $json.customer }}" },
    "action": {
      "buttons": [
        { "type": "reply", "reply": { "id": "approve:{{ $json.requestId }}", "title": "Approve" } },
        { "type": "reply", "reply": { "id": "reject:{{ $json.requestId }}",  "title": "Reject" } }
      ]
    }
  }
}

The reviewer's tap fires a webhook to your WhatsApp Business app's callback URL. A listener workflow reads the interactive.button_reply.id, parses the action + requestId, and POSTs to the paused approval workflow's Wait URL.

What you gain over native

Richer layouts. Multi-row keyboards, list pickers, reply templates, media with captions, formatted markdown. The native node gives you one message body and up to a few button labels; raw APIs give you the channel's full palette.

Custom actions, not just approve / reject. Add an "Edit" button that deep-links to a form. Add a "More context" button that posts an upstream record. Add domain-specific actions like "Escalate to legal" or "Send to design review."

Dynamic routing. Your dispatcher workflow can look up the right reviewer's chat ID at runtime from a database, not hardcoded into each node.

What you still own

The listener workflow. One per channel. Maintained alongside every approval workflow on that channel.

Chat ID / phone number registry. A table somewhere mapping reviewer IDs to Telegram chat IDs and WhatsApp phone numbers. Updated when reviewers rotate or change numbers.

The 24-hour window logic (WhatsApp). You need to track when the reviewer last messaged your business. If the approval is going outside the window, either delay it until the reviewer re-engages or fall back to a pre-approved template format.

Reminders, escalation, audit — all DIY. Same as the Slack Block Kit pattern. Each timeout branch is its own wiring; each reviewer decision needs a deliberate log write.

Verdict. Pattern 2 is right when you have a specific UX requirement the native node cannot hit — custom actions, rich layouts, dynamic routing. Budget 3–5 hours to set up properly plus ongoing maintenance of the listener workflow and the reviewer registry.

Telegram and WhatsApp callback URLs have tight response windows. Telegram expects an answerCallbackQuery response quickly (otherwise the reviewer sees a spinning button). WhatsApp webhooks expect a 200 response within a few seconds or the message will be retried — which means duplicate resume calls into your paused workflow. Always respond fast, then do the real work async.


WhatsApp's 24-hour window is a design constraint, not a bug

Builders hit this one late. A reviewer approves something Monday morning. You send another approval on Wednesday. Silence. You assume the reviewer is busy. They are not — WhatsApp dropped your message because it was outside the 24-hour customer service window.

The rules, for approval-workflow purposes:

  • Inside 24 hours of the reviewer's last inbound message: you can send anything — free-form text, buttons, media. This is the normal operating window.
  • Outside 24 hours: you can only send template messages that Meta has pre-approved. Templates have fixed formatting, optional variable slots, and category (utility / marketing / authentication). An approval request can be a template — it is a utility template — but the approval body content is constrained by the template structure.

Practical patterns:

Keep the reviewer warm. If approvals are frequent, the 24-hour window naturally stays open. Every reviewer reply resets the timer.

Design a utility template for out-of-window pings. A simple "You have an approval pending — tap below to review" with a link to an n8n-hosted form or a managed inbox. The link re-opens the 24-hour window when the reviewer taps and replies.

Do not try to send free-form AI output as a template. The template approval process rejects variable content that cannot be predicted. If your approval body is AI-generated, put the AI content behind a link and send only the notification-with-link template.

Account for international time zones. Approvals sent at 2 AM local time for the reviewer are likely to sit beyond 24 hours. Consider scheduling windows or using a managed inbox where the reviewer's preferred channel is a user-level setting, not a workflow-level one.


Pattern 3: A managed inbox, messaging as the notification layer

Patterns 1 and 2 both keep the approval state inside the messaging app. The thread is the record, the buttons are the action, the history is the chat log. That model is fragile once you cross the thresholds above: reviewer rotation, cross-workflow inbox, WhatsApp 24-hour window, Telegram /start onboarding.

Pattern 3 puts the approval state in a platform designed for it, and uses Telegram / WhatsApp / Slack / email as notification layers that each reviewer picks individually. This is the direction I am building Humangent toward — in private beta, sketch below is a design direction, not a feature list.

n8n shape

Trigger
  -> [AI content generation]
  -> HTTP Request: POST to Humangent
     Body:
     {
       "callback_url": "{{ $node['Wait for Webhook'].webhookUrl }}",
       "title": "LinkedIn post for review",
       "body": "{{ $json.draft }}",
       "editable_fields": ["draft"],
       "actions": ["publish", "reject", "request_revision"],
       "assignee": "marketing-team",
       "timeout": "4h"
     }
  -> Wait for Webhook
  -> Switch on action -> publish / reject / revise

Design goals relevant to messaging-first reviewers

  • Reviewer picks their channel. Each reviewer sets their preferred delivery channel (Telegram / WhatsApp / Slack / email) on their own account. The workflow never hardcodes a Telegram chat ID or a WhatsApp phone number. A reviewer who switches from Telegram to WhatsApp does it in their settings, not by editing n8n workflows.
  • The 24-hour WhatsApp window is managed for you. The platform tracks the window and falls back to a template-with-link notification when needed. The reviewer clicks the link, lands on the inbox, re-opens the window, and takes action.
  • Onboarding /start prompt built in. New Telegram reviewers get a one-time prompt to start the bot the first time they are assigned a request.
  • Context lives on the web, not in a 1500-character message. The Telegram / WhatsApp ping is short. The review surface is a proper page with the full context, editable fields, and prior approvals. No more scrolling three screens on a phone.
  • Cross-workflow inbox. A reviewer sees every pending request across every workflow in one place — their messaging app is the ping, the inbox is the work surface.
  • No plugins. The n8n side stays on standard HTTP Request and Wait for Webhook. If the service is gone tomorrow, you swap two nodes.

Honest status

All of the above is a design direction. Humangent is in private beta. If you need a finished system today, Pattern 1 or 2 is the honest answer — they work, they are just more DIY than you might like. If you can trade "I want this shipped today" for "I want to shape how this ships," early access is the route.


Practical patterns across all three approaches

A few node-level habits apply regardless of which pattern you pick.

Match the reviewer's channel to their real life. Founder reviewer? WhatsApp. Agency client? WhatsApp or Telegram depending on region. Internal team? Probably Slack, but ask. Do not default.

Keep the message body short on mobile. A three-line summary plus a link to full context beats a 40-line message the reviewer has to scroll. Use the link for detail; use the message for a decision prompt.

Always set a timeout. No timeout is a bug. An unhandled timeout output is a bigger bug. Four hours for routine, 24 hours for weekend-tolerant, 72 hours outer bound.

Update (or reply in thread) after the decision. Stale approval messages in a Telegram chat invite double-taps. A short "Approved by Alice at 14:32" reply makes the state visible at a glance.

Log every decision somewhere you own. Even if the platform gives you an audit trail, write the row yourself too. When compliance asks, you want to control the answer.

Test with your own chat ID first. Before handing a messaging approval workflow to a real reviewer, test delivery end-to-end with your own Telegram account and your own WhatsApp number. Channel-specific delivery bugs (a chat ID typo, a WhatsApp-template mismatch) are the fastest way to burn trust with a new reviewer.


Comparison at a glance

Native Send and Wait Inline keyboard + Wait for Webhook Managed inbox (target state)
Setup time ~10 min 3–5 h (dispatcher + listener) Designed for ~30 min
Recipient Chat ID / phone per node Chat ID / phone per node (usually dynamic) Per-reviewer channel preference
Custom actions 3 response types Any button / list layout the channel allows Any actions per request
Telegram /start onboarding Manual step Manual step Design goal: handled by platform
WhatsApp 24h window You plan around it You plan around it Design goal: managed + template fallback
Cross-workflow inbox No No Design goal: yes
Audit trail Execution log Whatever you log Built-in (design goal)
Maintenance Low at small scale Medium–high Intended to be low

"Target state" describes Pattern 3 design intent, not shipped features.


Starter template: AI LinkedIn post approval via Telegram

A complete workflow for the common case — AI drafts a LinkedIn post, a founder approves or rejects via Telegram before it publishes.

[Schedule Trigger: daily 9:00]
    |
[HTTP Request: fetch topic list from Airtable / Notion]
    |
[AI Agent: draft LinkedIn post for today's topic]
    |
[Telegram: Send and Wait for Response — Custom Form]
  Recipient: {{ $env.FOUNDER_CHAT_ID }}
  Fields:
    - post (textarea, prefilled with draft, editable)
    - decision (select: publish / reject / request_revision)
  Limit Wait Time: 4h
  On Timeout: separate output
    |
[Switch on decision]
    |-- publish  -> [LinkedIn: post using edited body]
    |              -> [Telegram: post confirmation with link to the published post]
    |-- reject   -> [Airtable: mark topic as rejected with optional reason]
    |-- revise   -> [AI Agent: redraft with feedback] -> loop back to Telegram review (max 3)
    |
[Timeout branch]
    -> [Telegram: "Pending approval expired. Next check-in tomorrow."]
    -> [Airtable: keep topic in queue for re-surface]

Editable body in action. If the founder edits the post text before tapping Publish, {{ $json.post }} contains the edited version. LinkedIn posts that edited version — not the original draft. A surprisingly common bug is to feed the original body to the publish step; test this path explicitly.

Revision cap. Three rounds is a reasonable cap. Beyond that, the topic goes back to the queue and a human drafts from scratch. The AI is not going to get it right on round four.


Common questions

Can I use Telegram and WhatsApp together in the same workflow? Yes. Nothing stops you from sending the request to Alice via Telegram and, if she does not respond within two hours, escalating to Bob via WhatsApp. Each Send-and-Wait (or HTTP Request + Wait for Webhook) is independent. In Pattern 3, the design intent is that each reviewer's preferred channel is a user setting, so the workflow stays unaware of which channel actually delivers.

What happens if the reviewer replies with text instead of tapping a button? Native Send-and-Wait Approval mode expects a button tap — free text will not resume the workflow. If you want to accept free text too, use the Free Text or Custom Form response type. In Pattern 2, you control how replies are parsed, so you can accept both buttons and typed replies (e.g., "approve", "yes", "👍").

Can WhatsApp messages include the full AI output or just a summary? Inside the 24-hour window, you can send the full AI output as free-form text. Outside the window, the message has to be a pre-approved template — usually a short notification with a link, because AI-generated variable content does not fit template approval rules. Design your message body assuming both states.

What about Telegram groups and WhatsApp groups? Telegram groups work with Send-and-Wait. Whoever taps the button first resumes the workflow — useful for "first available reviewer wins." WhatsApp groups do not support interactive buttons from the Business API in the same way — stick to 1:1 for WhatsApp approvals.

How do I handle a reviewer in a different time zone? For native Send-and-Wait, set a generous Limit Wait Time (12–24 hours) so the approval does not time out overnight. For WhatsApp specifically, be aware of the 24-hour window — an approval sent at 3 AM their time may still be pending at 1 AM yours when the window expires. In Pattern 3, the design goal is to let each reviewer set quiet hours so the workflow does not ping them off-hours.

Is there a way to test Telegram approvals without a production bot token? Create a second Telegram bot for testing (talk to BotFather, get a token, set it as an environment variable). Send yourself test approvals from this bot before pointing the workflow at the real reviewer.



If your reviewers live on Telegram or WhatsApp and you would rather not wire a listener workflow per channel, join the Humangent waitlist at humangent.io. Humangent is a human-in-the-loop inbox for n8n workflows, in private beta — the per-reviewer channel preference is a design direction the beta is shaping. Free during private beta, no credit card.