New to Kestra?
Use blueprints to kickstart your first workflows.
Kestra webhook flow that upserts inbound website form submissions into Odoo CRM leads with validation, email dedup, retries, and Slack alerting.
Capture website form submissions and write them straight into Odoo CRM as deduplicated leads. This event-driven flow exposes an authenticated webhook endpoint that your landing page, marketing platform, or form tool can POST to, then validates the payload, looks up any existing lead by email, and upserts the record in the crm.lead model over Odoo's XML-RPC API. It solves the classic lead-capture problems: spam and junk reaching the CRM, duplicate leads from retries or double submits, lost UTM attribution, and silent failures when the CRM is briefly unreachable.
io.kestra.plugin.core.trigger.Webhook trigger named form_submission exposes a signed endpoint keyed by ODOO_WEBHOOK_KEY. Each POST starts an execution with the JSON body in trigger.body.validate_payload (io.kestra.plugin.core.execution.Fail) rejects the run when email is missing, too short or long, or lacks @ and ., or when name is empty, so malformed and spam submissions never become leads.find_existing (io.kestra.plugin.odoo.Query with operation: SEARCH_READ) queries crm.lead by email_from and type = lead to detect an existing open lead for that address.upsert_lead (io.kestra.plugin.core.flow.If) branches on whether a match was found: update_lead runs a WRITE to refresh the existing record, otherwise create_lead runs a CREATE for a new one. This makes the endpoint idempotent on email.utm_source and utm_campaign from the payload are folded into the lead description so source attribution is preserved.log_updated or log_created records the affected lead id without logging the submitter's email.Odoo has no native scheduler for reacting to external HTTP events: it cannot expose a validated, retrying, deduplicating intake endpoint on its own. Kestra adds an event-driven webhook trigger, per-task retries on transient XML-RPC errors, declarative YAML you can version and review, full execution lineage for every captured lead, and a failure path that alerts Slack. The validation guard, conditional upsert, and attribution logic all live in one auditable flow rather than scattered across form-tool scripts.
crm.lead records.ODOO_URL: Base URL of the Odoo instance, including scheme and port (for example https://erp.example.com).ODOO_DB: Odoo database name to connect to.ODOO_USERNAME: Odoo login used for XML-RPC authentication.ODOO_PASSWORD: Password for that Odoo user.ODOO_WEBHOOK_KEY: Secret key embedded in the webhook URL. Treat it as a credential, since it is the main thing protecting the endpoint.SLACK_WEBHOOK: Slack incoming webhook URL used for failure alerts.ODOO_WEBHOOK_KEY.name and email (plus optional company, phone, message, utm_source, utm_campaign).team_id and user_id in the values map of create_lead and update_lead.find_existing filters.