Monthly Invoices Example
In this example we will create a schedule for each customer, to push an invoice generation job to queue at midnight each 1st day of month. We'll also add a queue processor to call our application payment service to generate and send out invoice to client.
Architectural overview
We create an individual schedule for each client, so if for whatever reason we fail to process queue item (infrastructure issues, bugs in code, etc...) it would not prevent other invoices from being sent. Each schedule will just push one item per month to our queue and it will handle the rest.
We will create our schedules to execute in timezone of our client, so clients get it on his start of the day. Not when a new month starts on our server.
Each time a new client subscribes to our app, we can now just call scheduleInvoice
and when client resigns or changes to free plan we just deleteInvoiceSchedule
and invoices are no longer sent.
Thanks to having a separate schedule for each client, we can also easily investigate problems, select different invoicing periods per client, pause and resume individual clients, etc.
Code example
import lq from '@dayone-labs/lambda-queue-express'
import './models'
const queue = lq.queue(
'/generate-invoice',
async (event: { customerId: string }) => {
await paymentService.sendInvoice(event.customerId)
}
)
const scheduleInvoice = async (customer: Customer) => {
await lq.schedule(
'@monthly',
{ customerId: customer.id },
{
queue: queue.queue,
key: `monthly-invoice-${customer.id}`,
target: queue.target,
timezone: customer.timezone,
}
)
}
const deleteInvoiceSchedule = async (customer: Customer) => {
await lq.deleteScheduleByKey(`monthly-invoice-${customer.id}`)
}
//Queue is an Express router, just mount it with app.use(queue)
export default {
route: queue,
scheduleInvoice,
deleteInvoiceSchedule,
}
Remarks
IMPORTANT
Don't worry about malicious clients calling your /generate-invoice
endpoint. LambdaQueue signs each request with your personal secret key and validates each call if you're using our client libraries. Check out your language SDK documentation for more information.
🔴 If you're not using our SDKs though, make sure you check x-lq-signature
header and validate signature.
TIP
When scheduling periodic jobs it sometimes makes sense to execute them in client specific timezone. If no timezone was selected, we'll execute your schedules in UTC.