Automatic urban mood report!

You upload a photo from your phone.
30 seconds later, you have a complete urban mood report.

Here’s how it works:

Webapp receives the image.
n8n webhook triggers automatically.
Fetches weather in Buenos Aires (Open Meteo API).
Fetches real-time traffic (Google Maps).
Processes everything with JS code.
Builds the day’s context.
Triggers the local system that generates the final content.

All connected via webhooks.

Zero clicks. Zero manual intervention.

Running for 6 months without breaking.

The hybrid system is key: n8n as the bridge between the public webapp and the local system doing the heavy lifting.

Before: manual content, inconsistent, forgot to publish.
Now: any time of the day that the user wants to generate content.

1 Like

Nice setup. The part I like most is the split between the public webapp, n8n as the orchestration layer, and the local system doing the heavier generation work. That is usually much easier to operate than trying to put everything in one workflow.

If it has been running for 6 months, I would mainly harden the boring failure cases now:

- add a correlation_id from the first webhook call and pass it through every n8n step and local-system call

- store one small run log per report: received image, weather fetched, traffic fetched, local generation started, final content created, final delivery status

- make the webhook idempotent, so the same uploaded photo cannot accidentally generate duplicate reports if the phone/webapp retries

- add timeout branches for Google Maps, Open Meteo, and the local system separately

- cache weather/traffic briefly, so a temporary API issue does not block every report

- keep one manual replay path for failed runs, using the same original payload and correlation_id

The local-system boundary is the place I would watch most closely. If that machine is offline, busy, or returns a partial result, n8n should create a clear failed state instead of letting the workflow look like it just stopped.

Small operational detail: I would also keep a simple “last 20 reports” view somewhere, even if it is just a table. For a workflow like this, debugging from recent run history is usually faster than reading the full workflow each time.

1 Like

Hi @jorferraro
Nice setup!
n8n as the orchestration layer, with the heavier local system doing the content generation. The only things I’d clarify are webhook security and external API assumptions: if the webapp is public, I’d use authentication/signature validation, rate limiting, and clear data retention/privacy rules for uploaded photos; I’d also specify which Google Maps endpoint is used, since some APIs provide traffic estimates/travel duration rather than full “real-time traffic” state.

1 Like

Thanks for the operational breakdown. the split you highlighted (public webapp / n8n orchestration / local generation) is exactly the architecture, and it’s been solid so far.

Your point about correlation_id + run logs is where I need to go next. Right now my failure mode is editorial state: if the track selection happens but Paper export fails, I need to replay without re-selecting music. The system has a 45-day anti-repetition rule and losing track of what already played would break editorial continuity.

I’m adding:

  • editorial_date as the canonical identifier (separate from when the workflow ran)

  • Track commit before Paper update (so I can retry export without burning another track. It happened)

  • Idempotency by date (same day can’t generate two different pieces)

The “last 20 reports” view makes total sense. I’ll build it as a visual gallery (thumbnail + track + date) rather than a table, since I need to spot editorial breaks (repeated tracks, wrong images) not just technical failures.

Appreciate the push toward operational hardening!

Hi1 You’re right about clarifying the Google Maps endpoint. I’m using the Directions API with departure_time=now to compare traffic-adjusted duration against baseline duration. That ratio gets bucketed into fluido/cargado/saturado as a traffic proxy, not real-time congestion state.

On webhook security: the system is private (just me and one other operator) and generates one piece per day for a cultural project, so auth/rate limiting aren’t current risks. The webhook URL is effectively secret, and there’s no PII in the uploads beyond the photo itself.

That said, your point about data retention is fair. I should document how long uploaded images live in the system and make that transparent if this ever expands beyond personal use. I´d like to see this system elsewhere.

For now, I’m prioritizing editorial state management (tracking which music has been used, ensuring failed exports don’t corrupt the selection memory) over perimeter defense, but I’ll keep your framing in mind if the system ever touches external users.
Thank you!

1 Like