WhatsApp to PostgreSQL, expenses logged as you text
You know the moment: you spend money, tell yourself you’ll log it later, and then “later” turns into a messy catch-up session with receipts, bank apps, and half-remembered notes.
This WhatsApp expense logging automation hits freelancers hard because every transaction matters, but small business owners and busy marketers dealing with reimbursables feel it too. Instead of typing into yet another app, you just text what you spent and it lands in your database, clean and searchable.
Below you’ll see exactly how the workflow routes messages, turns plain English into structured fields, saves everything to PostgreSQL, and sends you summaries on demand (or automatically each morning).
The Problem: Expense Tracking Breaks the Moment You Get Busy
Manual expense tracking fails for a simple reason: it asks you to change behavior when you’re already juggling work, life, and a dozen small decisions. You buy coffee, pay a contractor, or grab supplies, and the “quick log” turns into opening an app, picking categories, typing amounts, and trying to remember the vendor name. Miss two days and the backlog feels annoying. Miss two weeks and it’s basically dead. The cost isn’t just time. It’s the quiet stress of not knowing your numbers until it’s too late to react.
None of these alone is the problem. Together, they are.
- You end up copying the same details into spreadsheets, apps, and reimbursement notes, and something always gets skipped.
- Categories drift over time, so your “food” or “software” totals stop meaning anything by month-end.
- Small errors creep in when you log from memory, especially for cash purchases or split transactions.
- Reports take effort, which means you avoid them until you really need them.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: WhatsApp to PostgreSQL, expenses logged as you text
flowchart LR
subgraph sg0["Incoming WhatsApp Flow"]
direction LR
n0@{ icon: "mdi:wrench", form: "rounded", label: "Date and time", pos: "b", h: 48 }
n1@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser", pos: "b", h: 48 }
n2@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model", pos: "b", h: 48 }
n3@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model1", pos: "b", h: 48 }
n4@{ icon: "mdi:wrench", form: "rounded", label: "Calculator", pos: "b", h: 48 }
n5@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model3", pos: "b", h: 48 }
n12@{ icon: "mdi:cog", form: "rounded", label: "Convert to File", pos: "b", h: 48 }
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Send Financial Response"]
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Normal Conversation "]
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Incoming WhatsApp Trigger"]
n16@{ icon: "mdi:robot", form: "rounded", label: "Message Intent Classifier", pos: "b", h: 48 }
n17@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Route by Intent", pos: "b", h: 48 }
n18@{ icon: "mdi:robot", form: "rounded", label: "Parse & Validate Transaction", pos: "b", h: 48 }
n19@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Transaction Lines", pos: "b", h: 48 }
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Format Transaction JSON"]
n21["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Validate Transaction Fields"]
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Insert Transaction into DB"]
n23@{ icon: "mdi:robot", form: "rounded", label: "Build Confirmation Message", pos: "b", h: 48 }
n29@{ icon: "mdi:robot", form: "rounded", label: "Build Custom Report Query", pos: "b", h: 48 }
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Transform Custom Query for P.."]
n31["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Format Custom Query Results"]
n32["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Execute Custom Report Query"]
n33@{ icon: "mdi:robot", form: "rounded", label: "Build Custom Financial Summary", pos: "b", h: 48 }
n34["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Send Custom Report"]
n35@{ icon: "mdi:robot", form: "rounded", label: "simple conversation ", pos: "b", h: 48 }
n37@{ icon: "mdi:wrench", form: "rounded", label: "Date and time1", pos: "b", h: 48 }
n38@{ icon: "mdi:wrench", form: "rounded", label: "Date and time2", pos: "b", h: 48 }
n39@{ icon: "mdi:wrench", form: "rounded", label: "Date and time3", pos: "b", h: 48 }
n40@{ icon: "mdi:wrench", form: "rounded", label: "Date and time4", pos: "b", h: 48 }
n41@{ icon: "mdi:wrench", form: "rounded", label: "Date and time5", pos: "b", h: 48 }
n42@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model2", pos: "b", h: 48 }
n43@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model7", pos: "b", h: 48 }
n44@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model8", pos: "b", h: 48 }
n4 -.-> n33
n0 -.-> n18
n37 -.-> n29
n38 -.-> n33
n39 -.-> n23
n40 -.-> n16
n41 -.-> n35
n12 --> n33
n17 --> n29
n17 --> n18
n17 --> n35
n35 --> n14
n2 -.-> n16
n3 -.-> n29
n42 -.-> n18
n5 -.-> n33
n43 -.-> n35
n44 -.-> n23
n20 --> n21
n19 --> n20
n1 -.-> n18
n29 --> n30
n15 --> n16
n16 --> n17
n23 --> n13
n22 --> n23
n32 --> n31
n31 --> n12
n21 --> n22
n18 --> n19
n33 --> n34
n30 --> n32
end
subgraph sg1["Daily 8AM Flow"]
direction LR
n6@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model4", pos: "b", h: 48 }
n7@{ icon: "mdi:database", form: "rounded", label: "Postgres2", pos: "b", h: 48 }
n8@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model5", pos: "b", h: 48 }
n9@{ icon: "mdi:wrench", form: "rounded", label: "Calculator1", pos: "b", h: 48 }
n10@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser2", pos: "b", h: 48 }
n11@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model6", pos: "b", h: 48 }
n24@{ icon: "mdi:play-circle", form: "rounded", label: "Daily 8AM Trigger", pos: "b", h: 48 }
n25@{ icon: "mdi:robot", form: "rounded", label: "Build Daily Report Query", pos: "b", h: 48 }
n26@{ icon: "mdi:robot", form: "rounded", label: "Execute Daily Report Query", pos: "b", h: 48 }
n27@{ icon: "mdi:robot", form: "rounded", label: "Build Daily Financial Summary", pos: "b", h: 48 }
n28["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/whatsapp.svg' width='40' height='40' /></div><br/>Send Daily Report"]
n36["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Transform Custom Query for P.."]
n7 -.-> n26
n9 -.-> n27
n24 --> n25
n6 -.-> n25
n8 -.-> n26
n11 -.-> n27
n25 --> n36
n10 -.-> n26
n26 --> n27
n27 --> n28
n36 --> n26
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n15,n24 trigger
class n1,n16,n18,n23,n29,n33,n35,n10,n25,n26,n27 ai
class n2,n3,n5,n42,n43,n44,n6,n8,n11 aiModel
class n0,n4,n37,n38,n39,n40,n41,n9 ai
class n17 decision
class n22,n32,n7 database
class n20,n21,n30,n31,n36 code
classDef customIcon fill:none,stroke:none
class n13,n14,n15,n20,n21,n22,n30,n31,n32,n34,n28,n36 customIcon
The Solution: Turn WhatsApp Into Your Finance Inbox
This workflow treats WhatsApp like the front door for your personal (or small business) finance system. A WhatsApp message triggers the automation, then an AI agent classifies what you meant: are you logging a transaction, asking for a report, or just chatting about money? If it’s a transaction, the workflow parses your natural language into structured fields like date, category, type (expense/income/debt), amount, and person or company. It checks that the required fields are present, inserts the entry into PostgreSQL, then replies back with a confirmation you can trust. If you ask for insights, it generates a Postgres query, runs it, and returns a readable summary right in the chat.
The workflow starts with WhatsApp incoming messages (plus a scheduled daily trigger for morning summaries). From there, intent routing decides which branch to run: transaction logging, reports and analytics, or general finance conversation. Finally, WhatsApp sends the confirmation or report back to you, so you never have to “go look it up” elsewhere.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you log about 10 transactions a week. Manually, even a “fast” flow is maybe 3 minutes per item once you switch apps, pick a category, and type details, which is roughly 30 minutes weekly. If you fall behind and do it in one sitting, it feels like a chore. With this workflow, you send a WhatsApp message that takes about 20 seconds, wait a moment for the AI to parse it, and you get a confirmation back. You’re still tracking, but the effort is spread out and tiny.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- WhatsApp Business Cloud API to receive and reply to messages.
- PostgreSQL to store structured transactions long-term.
- OpenRouter API key (get it from your OpenRouter dashboard) for AI parsing and report generation.
Skill level: Intermediate. You’ll connect a few credentials, create a database table, and test webhooks, but you won’t be writing an app from scratch.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A WhatsApp message (or a scheduled morning trigger) starts everything. When you send “Spent 300 on groceries at Walmart” the workflow receives it via the WhatsApp trigger. There’s also a daily schedule trigger for automatic summaries at a set time (often 8 AM).
The message gets classified by intent. An AI agent reads the text and decides if you’re asking for a report, logging a transaction, or just having a general finance chat. That routing matters because reports need database queries, while transactions need structured extraction and validation.
Transactions are parsed, checked, then inserted into PostgreSQL. The workflow extracts date, category, type, amount, and person/company, splits multiple entries if you sent them in one message, and verifies required fields. Then it inserts the row into your Postgres table and generates a confirmation reply so you know it worked.
Reports turn into queries, then readable summaries. If you send “today’s report” or “compare March vs April spending,” the workflow composes a SQL query, runs it in PostgreSQL, formats the output, and returns a clear WhatsApp message with totals and highlights.
You can easily modify reporting time and categories to match your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the WhatsApp Trigger
This workflow starts by listening for incoming WhatsApp messages and routing them into the intent classifier.
- Add or open WhatsApp Incoming Trigger and connect it to Intent Classification Agent.
- Complete the WhatsApp trigger setup so it can receive inbound messages from your WhatsApp provider.
- Credential Required: Connect your WhatsApp credentials (required for WhatsApp Incoming Trigger).
Step 2: Configure the Schedule Trigger for Daily Reports
A separate scheduled path generates daily finance summaries.
- Open Daily Morning Trigger and define the schedule that fits your reporting cadence.
- Ensure Daily Morning Trigger outputs to Compose Daily Report Query as in the execution flow.
Step 3: Connect AI Language Models and Tools
Multiple AI agents rely on OpenRouter language models and helper tools. These must be connected to the parent nodes.
- Attach OpenRouter Chat Engine as the language model for Intent Classification Agent.
- Attach OpenRouter Chat Engine F to Parse and Verify Transaction, OpenRouter Chat Engine H to Build Confirmation Reply, OpenRouter Chat Engine E to Generate Daily Finance Summary, and OpenRouter Chat Engine B to Generate Custom Finance Summary.
- Credential Required: Connect your OpenRouter credentials on all OpenRouter chat engine nodes used by agents.
- For AI tools like Timestamp Utility, Timestamp Utility A, Timestamp Utility B, Timestamp Utility C, Timestamp Utility D, Timestamp Utility E, Arithmetic Helper, Math Utility, Structured Result Parser, Structured Result Parser 2, and Postgres Tooling, add credentials on the parent agent nodes (not on the tool nodes themselves).
Step 4: Configure Intent Routing and Transaction Processing
Inbound messages are classified and routed into transaction logging, custom reporting, or general conversation.
- Confirm the flow from WhatsApp Incoming Trigger → Intent Classification Agent → Intent Routing Switch.
- Verify the transaction path: Intent Routing Switch → Parse and Verify Transaction → Split Transaction Entries → Format Transaction JSON Data → Check Transaction Fields → Insert Transaction to DB → Build Confirmation Reply → Send Finance Reply.
- Verify the general conversation path: Intent Routing Switch → Basic Conversation Flow → Standard Conversation.
Step 5: Configure Reporting and Database Queries
Daily and custom reports use Postgres queries prepared by AI and formatted into summaries.
- Daily report flow should follow: Daily Morning Trigger → Compose Daily Report Query → Adapt Daily Query for Postgres → Run Daily Report Query → Generate Daily Finance Summary → Dispatch Daily Report.
- Custom report flow should follow: Intent Routing Switch → Compose Custom Report Query → Adapt Custom Query for Postgres → Run Custom Report Query → Format Custom Query Output → Convert Data to File → Generate Custom Finance Summary → Dispatch Custom Report.
- Credential Required: Connect your Postgres credentials in Insert Transaction to DB, Run Custom Report Query, and any agent nodes that use Postgres Tooling (credentials must be added to the parent node).
Step 6: Configure WhatsApp Reply Outputs
Final responses are sent through WhatsApp for confirmations, daily reports, custom reports, and general conversations.
- Ensure Send Finance Reply receives output from Build Confirmation Reply.
- Ensure Dispatch Daily Report receives output from Generate Daily Finance Summary and Dispatch Custom Report from Generate Custom Finance Summary.
- Ensure Standard Conversation receives output from Basic Conversation Flow.
- Credential Required: Connect your WhatsApp credentials on Send Finance Reply, Dispatch Daily Report, Dispatch Custom Report, and Standard Conversation.
Step 7: Test & Activate Your Workflow
Validate both WhatsApp and scheduled paths before turning the workflow on.
- Use Execute Workflow and send a WhatsApp test message to trigger WhatsApp Incoming Trigger.
- Confirm a successful run logs a transaction into Postgres and sends a reply via Send Finance Reply.
- Manually execute Daily Morning Trigger to verify the daily report path ends at Dispatch Daily Report.
- When all paths succeed, toggle the workflow to Active for production use.
Common Gotchas
- WhatsApp Business Cloud API credentials can expire or lack the right permissions. If replies suddenly stop, check your Meta app token, phone number ID, and webhook subscription settings first.
- If you’re using Wait nodes or external processing, response times vary. Bump up the wait duration if downstream steps fail because they received an empty or delayed AI response.
- Default AI prompts are honestly too generic for consistent categories. Add your currency, preferred category list, and example messages early or you’ll be cleaning data later.
Frequently Asked Questions
About 30 minutes if you already have WhatsApp and PostgreSQL ready.
No. You’ll mostly connect accounts and paste in credentials. A little comfort editing fields and testing messages helps.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenRouter API usage costs, which depend on the model you choose.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, but you’ll want to add a user identifier to each transaction. In practice, that means capturing the sender from the WhatsApp trigger and writing it into PostgreSQL as an extra column, then filtering reports by that field. Many people also add per-user category rules (so “fuel” and “gas” map consistently). If you prefer, you can route each user to a different database table or schema to keep things clean.
Usually it’s an expired Meta token or a webhook configuration issue. Regenerate the app token, confirm the phone number ID, and make sure your webhook is still subscribed to message events. If incoming messages work but replies fail, check WhatsApp template or messaging permissions and any account restrictions.
On n8n Cloud Starter you can handle a typical personal or small business volume easily, and higher plans support more executions. If you self-host, there’s no execution limit (it depends on your server). In day-to-day use, this workflow is usually gated by AI response time and WhatsApp API throughput, not PostgreSQL.
For this use case, n8n is often the better fit because you can self-host, add branching logic for “transaction vs report vs chat,” and control how the AI parsing behaves without paying per-step the same way. Zapier or Make can still work if you only want a basic “message in, row in spreadsheet” setup. The moment you want proper validation, database writes, and custom reporting queries, n8n tends to feel more flexible. If you’re unsure, think about where you want the data to live long-term and how often you’ll want reports. Talk to an automation expert and you can map it out quickly.
Once this is running, expense tracking stops being a “project” you keep restarting. The workflow handles the repetitive stuff, and your numbers stay current without you babysitting them.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.