Short answer: use a cloud cron job to trigger the daily report endpoint, then make the endpoint idempotent and move long work to a queue. The least complex design is a fixed daily trigger plus a short HTTP handler that records a client-supplied operation ID before generating or enqueueing the email. Retries then repeat the request safely instead of creating a second report or a second outbound webhook.
The important boundary is operational recovery. Node.js can own the email-generation logic, with a library such as Nodemailer, but it should not be asked to impersonate a durable scheduler. A public HTTPS endpoint, a cloud cron service, an idempotent consumer, and run history give the property-management team something much more useful than a clever timer: a way to explain what happened when the 08:00 report did not arrive.
1. Price the state you retain, not just the scheduled call
The bill for this design is made of more than one request.…