New to Kestra?
Use blueprints to kickstart your first workflows.
Watch an S3 inbox for receipt images, extract vendor, date, and total with Gemini multimodal, reshape into typed JSON, and notify Google Chat.
Turn a folder of receipt photos into structured expense records without a dedicated OCR pipeline. This blueprint watches an S3 inbox for new receipt images, asks Google Gemini's multimodal model to read the image and describe the vendor, date, currency, and total, then reshapes that description into strict JSON with a second Gemini call. It solves the gap between a model that can read an image and a downstream system that needs typed fields it can insert into a database.
new_receipt trigger (io.kestra.plugin.aws.s3.Trigger) polls the expense-receipts bucket's inbox/ prefix every 5 minutes and starts one execution per batch of new images, downloading matches to internal storage.describe_receipt (io.kestra.plugin.gemini.MultimodalCompletion) sends the downloaded image alongside a text prompt to gemini-3.5-flash-lite, asking for the vendor, purchase date, currency, and total as labeled plain text.structure_fields (io.kestra.plugin.gemini.StructuredOutputCompletion) takes that free-text description and reshapes it into a fixed JSON schema (vendor, purchaseDate, currency, total), so downstream systems get typed fields instead of prose.notify_finance (io.kestra.plugin.googleworkspace.chat.GoogleChatIncomingWebhook) posts the structured result to a Google Chat space for the finance team to review.Gemini can read one image and describe it, but it has no concept of a receipts folder, no polling loop, and no way to hand its answer to a second model call or a chat notification. Kestra adds the Trigger that watches storage, the execution history around each Gemini call, and the chaining between the multimodal read and the structured reshape, so a failed step does not force a re-read of the image. Everything lives in one declarative YAML flow you can version.
inbox/ prefix.GEMINI_API_KEY: API key for both Gemini calls.AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY: credentials for the S3 bucket.GOOGLE_CHAT_WEBHOOK: incoming webhook URL for the finance Chat space.new_receipt trigger at your own bucket and prefix.structure_fields to insert the record directly into an expense ledger.If task to flag totals above a threshold for manual review.