N8n Workflow Design: Routing One WhatsApp Location to Ride Booking, Food Delivery & Special Collection

Hi everyone,
I’m building a WhatsApp workflow in n8n that handles multiple services from the same incoming location message:

  • :taxi: Ride booking (pickup & dropoff)
  • :hamburger: Food delivery
  • :package: Special collection
    My challenge is preserving the original WhatsApp location (“latitude”/“longitude”) while querying Google Sheets for active rides, orders, or collections. After nodes like Find Active Ride or Find Active Order, the Google Sheets output replaces the original webhook payload, so by the time the workflow reaches the correct service branch, the original location coordinates are no longer available.
    I’m looking for the best scalable architecture for routing a single location message to multiple services while preserving the original payload. Would you use Merge nodes, Code nodes, Execute Workflow, data stores, or another design pattern?
    Any advice from experienced n8n developers would be greatly appreciated. Thanks!

Describe the problem/error/question

What is the error message (if any)?

Please share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Hi @Thabang_Makalela

Since you are handling three distinct services (Ride, Food, Collection), putting all this logic in one workflow will eventually lead to “spaghetti” canvas. The most scalable architecture is a Router → Service pattern.

The Architecture:

  • Main Router Workflow:

    1. Receives WhatsApp Webhook.
    2. Validates the location.
    3. Uses a Switch Node to determine the service (Ride vs. Food vs. Collection).
    4. Uses the Execute Workflow Node to call a specific sub-workflow (e.g., Service_Ride_Booking).
    5. Crucial: Pass the entire json payload as the input to the sub-workflow.
  • Service Sub-workflows:

    • Each sub-workflow starts with an Execute Workflow Trigger​.
    • It receives the location, performs the Google Sheets lookup, and handles the business logic.
    • Since the location is passed as the initial input, it’s always available at the start of the sub-process.
3 Likes

Good point on the Router → Service split for keeping things maintainable long-term. One thing worth adding for anyone who wants a simpler setup first: even in a single flat workflow (no Execute Workflow split), you don’t actually need Merge or Code nodes to carry the location forward.

n8n keeps every node’s output accessible for the whole execution, not just whatever the “current item” looks like at a given point. So downstream - including inside each Switch branch - you can reference the original trigger node directly instead of the current item:

{{ $('WhatsApp Trigger').item.json.location.latitude }}
{{ $('WhatsApp Trigger').item.json.location.longitude }}

(swap the name for your actual trigger node). That still resolves correctly after Find Active Ride / Find Active Order overwrite the current item, as long as you keep normal one-to-one item pairing along the way (avoid Code nodes that build brand new items without pairedItem, avoid Merge nodes that would break the lineage).

So: single workflow + $('WhatsApp Trigger') references solves the “payload gets overwritten” problem without any extra routing. The Router → Service split above is still the better call once the branches get complex enough to want isolated, independently testable sub-workflows.

3 Likes

A good approach is to preserve the original webhook data before sending the workflow into service-specific nodes. In n8n, using a Set node to store the location fields, or a Merge node to combine the original payload with Google Sheets results later, can help maintain the latitude and longitude values. Structuring each service branch with clear data handling will also make the workflow easier to scale and debug. For teams planning food-related services, I also found a useful resource about the olive garden :spaghetti: menu options that may provide some inspiration.

Small but important tweak to the $(‘WhatsApp Trigger’) approach: use .first() rather than .item here.

.item resolves through item pairing, and the moment your Sheets lookup returns a different number of items than the trigger did, that pairing breaks — you get either the wrong row’s coordinates or a ‘can’t determine which item to use’ error, and it usually shows up later when you add a branch, not now. A WhatsApp webhook is one message per execution, so $(‘WhatsApp Trigger’).first().json.location.latitude is unambiguous and stays correct no matter what the branches do.