Project
A second Messenger AI chatbot, rebuilt from scratch on Activepieces after shipping the first one on Make.com — same category of tool, different platform, deliberately chosen to build real fluency across builders as part of the progression toward multi-agentic AI systems. Wired for webhook verification, conversation memory, duplicate detection, Groq AI replies, and Messenger Send API delivery.
After shipping the first Messenger AI agent on Make.com, this project rebuilds the same category of system — a Facebook Messenger chatbot with memory, AI-generated replies, and automatic logging — on Activepieces. The goal wasn't just to duplicate the result, it was to get hands-on with how a different automation platform handles the same problems: expression syntax, trigger sample data, step-level testing, and webhook verification all work differently here than they did in Make.com.
The flow catches every incoming Meta webhook event on a single trigger, then routes it two ways: verification handshakes get echoed straight back (required for Meta's initial webhook setup), while real user messages get parsed, checked against existing conversation records to avoid duplicate processing, sent to Groq AI for a reply, logged to Activepieces Tables with a live timestamp, and sent back to the user via the Messenger Send API.
| # | Step | Tool | Status |
|---|---|---|---|
| 1 | Single trigger catches every incoming Meta webhook event — both the verification handshake and real user messages | Activepieces Webhook | ✓ Live |
| 2 | Router splits verification requests (GET with hub.mode=subscribe) from real messages (POST with message data) | Activepieces Router | ✓ Live |
| 3 | Verification branch echoes hub.challenge straight back — completes Meta's webhook setup handshake | Activepieces Webhook | ✓ Live |
| 4 | Message branch parses the raw payload — extracts senderId and messageText, flags whether the message is valid, and stamps an ISO timestamp | Activepieces Code (JS) | ✓ Live |
| 5 | Checks Activepieces Tables for an existing conversation record matching this sender, to catch duplicate webhook fires | Activepieces Tables | ✓ Live |
| 6 | Router splits already-processed duplicates (skipped) from genuinely new messages that continue to the AI reply logic | Activepieces Router | ✓ Live |
| 7 | Pulls existing conversation history for this sender, giving the AI reply full context rather than treating each message in isolation | Activepieces Tables | ✓ Live |
| 8 | Sends the message and conversation context to Groq AI to generate the reply | HTTP · Groq AI | ✓ Live |
| 9 | Extracts and formats the AI's reply text from the raw API response | Activepieces Code (JS) | ✓ Live |
| 10 | Writes senderId, the updated conversation history, and a live ISO timestamp to the conversations table | Activepieces Tables | ✓ Live |
| 11 | Secondary record write — table split still being finalized as the customer-record and conversation-log structures are separated | Activepieces Tables | ⚠ In progress |
| 12 | Posts the AI's reply back to the user via the Meta Messenger Send API, using the Page Access Token generated during app setup | HTTP · Meta Messenger API | ✓ Live |
This build started with a working reference point already in hand — the Make.com Messenger agent — which made it a useful stress test for how much of that architecture (and how much debugging instinct) actually transfers to a new platform.
Instead of designing a new bot from scratch, the same core pipeline from the Make.com build — webhook, memory, AI reply, logging — was rebuilt on Activepieces, on a separate Facebook Page used purely for testing.
The Raw Body field kept returning an empty response even though the trigger data existed. It traced back to how Activepieces stores trigger sample data separately from live test runs — the picker had nothing real to reference until a test request was sent through the builder's own test-data form, not just the live URL.
senderId briefly showed up with a stray space. Rather than assume the parsing code was wrong, the Code step was audited line by line, confirmed as a pure passthrough with no string manipulation — and the space was traced to a step panel that simply hadn't been retested since the sample data was cleaned up.
lastUpdated started as a static "now" string. It was replaced with a real new Date().toISOString() generated directly inside the existing parsing step, then mapped into the table write through the picker — confirmed with a live ISO timestamp in the logged record.
The full 12-step pipeline runs cleanly end to end — verification, parsing, dedup, AI reply, logging, and reply delivery. The only thing standing between this and a public bot is Meta App Review, since the connected app is still in Development mode.
This bot is fully built and functioning, but Meta App Review hasn't been completed, so it's currently only reachable by admins and testers on the connected Page. Once App Review clears, this section will be updated with a live link — the same way the Make.com Messenger agent's "try it" section works today.
// in the meantime, the step breakdown and build story above reflect the actual live build