{ "kind": "open-flow-workflow", "version": 1, "name": "WooCommerce Customer to Mautic", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_00090b70ddcc4b49": { "name": "Receive a customer update", "kind": "integration", "config": { "events": { "kind": "value", "value": [ "customer.updated" ] }, "webhookName": { "kind": "value", "value": "Mautic customer sync" } }, "definition": { "configInputs": [ { "jsonSchema": { "type": "array", "items": { "type": "string", "enum": [ "coupon.created", "coupon.updated", "coupon.deleted", "coupon.restored", "customer.created", "customer.updated", "customer.deleted", "order.created", "order.updated", "order.deleted", "order.restored", "product.created", "product.updated", "product.deleted", "product.restored", "product.published" ] }, "minItems": 1, "maxItems": 16, "uniqueItems": true }, "nullable": false, "handle": "events" }, { "jsonSchema": { "type": "string", "minLength": 1, "maxLength": 120 }, "nullable": false, "handle": "webhookName", "value": "OOMOL Trigger" } ], "definitionVersion": 2, "description": "Triggers when selected WooCommerce store events occur.", "displayName": "Store Event", "key": "woocommerce.on_store_event", "name": "on_store_event", "outputs": [ { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "deliveryId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "event" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "resource" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "source" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "topic" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "webhookId" } ], "provider": "woocommerce", "type": "integration", "endpoint": { "body": { "allowArray": false, "allowEmpty": false, "formats": [ "json" ] }, "methods": [ "POST" ], "successStatus": 202 } } }, "n_a9f10f6a88e26b53": { "inputs": { "customer": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_00090b70ddcc4b49", "output": "body" } ] } }, "name": "Prepare customer fields", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "customer" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1, "description": "A Mautic search expression or text filter applied to the collection." }, "nullable": false, "handle": "search" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "email" }, { "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "minProperties": 1, "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias." }, "nullable": false, "handle": "createFields" }, { "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "minProperties": 1, "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias." }, "nullable": false, "handle": "updateFields" } ], "name": "Prepare customer fields", "moduleId": "n_93f0229f8391a2cd", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_49769715ebbed03c": { "inputs": { "search": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a9f10f6a88e26b53", "output": "search" } ] }, "start": { "kind": "value", "value": 0 }, "limit": { "kind": "value", "value": 30 } }, "name": "Find Mautic contacts by email", "kind": "task", "task": { "inputs": [ { "description": "A Mautic search expression or text filter applied to the collection.", "jsonSchema": { "type": "string", "minLength": 1, "description": "A Mautic search expression or text filter applied to the collection." }, "nullable": true, "handle": "search", "value": null }, { "description": "The zero-based starting row for the returned collection.", "jsonSchema": { "type": "integer", "minimum": 0, "description": "The zero-based starting row for the returned collection." }, "nullable": true, "handle": "start", "value": null }, { "description": "The maximum number of records to return.", "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The maximum number of records to return." }, "nullable": true, "handle": "limit", "value": null }, { "description": "The Mautic field used to order results, such as date_added or lastname.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Mautic field used to order results, such as date_added or lastname." }, "nullable": true, "handle": "orderBy", "value": null }, { "description": "The result ordering direction.", "jsonSchema": { "type": "string", "enum": [ "asc", "desc" ], "description": "The result ordering direction." }, "nullable": true, "handle": "orderByDir", "value": null }, { "description": "Whether to return only published records.", "jsonSchema": { "type": "boolean", "description": "Whether to return only published records." }, "nullable": true, "handle": "publishedOnly", "value": null } ], "outputs": [ { "description": "Contacts returned by Mautic.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "description": "Contacts returned by Mautic." }, "nullable": false, "handle": "contacts" }, { "description": "The total number of matching contacts reported by Mautic.", "jsonSchema": { "type": "integer", "minimum": 0, "description": "The total number of matching contacts reported by Mautic." }, "nullable": false, "handle": "total" } ], "name": "Find Mautic contacts by email", "executor": { "kind": "connector", "action": "mautic.list_contacts" } } }, "n_0003ad9ee7b82efb": { "inputs": { "contacts": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_49769715ebbed03c", "output": "contacts" } ] }, "email": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a9f10f6a88e26b53", "output": "email" } ] } }, "name": "Confirm one exact email match", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "description": "Contacts returned by Mautic." }, "nullable": false, "handle": "contacts" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "email" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "create" }, { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": true, "handle": "matched" } ], "name": "Confirm one exact email match", "moduleId": "n_5fc5fb52218a6cdd", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_cac58f280114830c": { "inputs": {}, "name": "Create or update the contact", "kind": "condition", "matchMode": "first", "cases": [ { "output": "create", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_0003ad9ee7b82efb", "output": "create" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_2f34ea8a6fd230c8": { "inputs": { "fields": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a9f10f6a88e26b53", "output": "createFields" } ] } }, "name": "Create a missing contact", "kind": "task", "task": { "inputs": [ { "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "minProperties": 1, "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias." }, "nullable": false, "handle": "fields" } ], "outputs": [ { "description": "Mautic contact data.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": false, "handle": "contact" } ], "name": "Create a missing contact", "executor": { "kind": "connector", "action": "mautic.create_contact" } } }, "n_63cac9e9bb6db111": { "inputs": { "matched": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0003ad9ee7b82efb", "output": "matched" } ] }, "fields": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a9f10f6a88e26b53", "output": "updateFields" } ] } }, "name": "Select the existing contact ID", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": true, "handle": "matched" }, { "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "minProperties": 1, "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias." }, "nullable": false, "handle": "fields" } ], "outputs": [ { "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "nullable": false, "handle": "contactId" }, { "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "minProperties": 1, "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias." }, "nullable": false, "handle": "fields" } ], "name": "Select the existing contact ID", "moduleId": "n_ade96d893b2403dd", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_ab3d7663f57ac111": { "inputs": { "contactId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_63cac9e9bb6db111", "output": "contactId" } ] }, "fields": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_63cac9e9bb6db111", "output": "fields" } ] } }, "name": "Update the existing contact name", "kind": "task", "task": { "inputs": [ { "description": "The numeric Mautic contact ID.", "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "nullable": false, "handle": "contactId" }, { "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "minProperties": 1, "description": "Contact field values keyed by Mautic field alias, such as email, firstname, lastname, company, or a custom field alias." }, "nullable": false, "handle": "fields" } ], "outputs": [ { "description": "Mautic contact data.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": false, "handle": "contact" } ], "name": "Update the existing contact name", "executor": { "kind": "connector", "action": "mautic.update_contact" } } }, "n_88c019e960911344": { "inputs": { "contact": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2f34ea8a6fd230c8", "output": "contact" }, { "kind": "node", "nodeId": "n_ab3d7663f57ac111", "output": "contact" } ] } }, "name": "Check the saved contact ID", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": false, "handle": "contact" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": false, "handle": "contact" } ], "name": "Check the saved contact ID", "moduleId": "n_fb362beda04783f0", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_0729ac6bcc73b8d1": { "name": "Saved Mautic contact", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "exclusiveMinimum": 0, "description": "The numeric Mautic contact ID." }, "isPublished": { "type": "boolean", "description": "Whether the contact is published." }, "points": { "type": "integer", "description": "The contact's current points total." }, "dateAdded": { "type": "string", "description": "The date and time when the contact was created." }, "dateModified": { "type": [ "string", "null" ], "description": "The date and time when the contact was last modified." }, "fields": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Contact fields grouped and returned by Mautic." }, "tags": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Mautic tag." }, "description": "Tags associated with the contact." } }, "additionalProperties": true, "description": "Mautic contact data." }, "nullable": false, "handle": "contact" } ], "outputMappings": { "contact": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_88c019e960911344", "output": "contact" } ] } } } }, "edges": [ { "source": "n_00090b70ddcc4b49", "target": "n_a9f10f6a88e26b53" }, { "source": "n_a9f10f6a88e26b53", "target": "n_49769715ebbed03c" }, { "source": "n_49769715ebbed03c", "target": "n_0003ad9ee7b82efb" }, { "source": "n_0003ad9ee7b82efb", "target": "n_cac58f280114830c" }, { "source": "n_cac58f280114830c", "target": "n_63cac9e9bb6db111", "sourceHandle": "otherwise" }, { "source": "n_cac58f280114830c", "target": "n_2f34ea8a6fd230c8", "sourceHandle": "create" }, { "source": "n_63cac9e9bb6db111", "target": "n_ab3d7663f57ac111" }, { "source": "n_2f34ea8a6fd230c8", "target": "n_88c019e960911344" }, { "source": "n_ab3d7663f57ac111", "target": "n_88c019e960911344" }, { "source": "n_88c019e960911344", "target": "n_0729ac6bcc73b8d1" } ] } }, "modules": { "n_93f0229f8391a2cd": { "name": "Prepare customer fields", "imports": [], "source": "export default function wooCommerceMauticFields({ customer }) {\n if (customer == null || typeof customer !== 'object' || Array.isArray(customer)) throw new Error('Expected a WooCommerce customer object');\n const email = typeof customer.email === 'string' ? customer.email.trim() : '';\n if (!/^[^\\s@:\"\\\\]+@[^\\s@:\"\\\\]+$/.test(email) || email.length > 254) throw new Error('Customer email is missing or invalid');\n const text = (value, field) => { if (value == null) return ''; if (typeof value !== 'string') throw new Error('Customer ' + field + ' must be text'); return value; };\n const firstname = text(customer.first_name, 'first name'), lastname = text(customer.last_name, 'last name'), company = text(customer.billing?.company, 'billing company');\n return { search: email, email, createFields: { email, firstname, lastname, company, position: '', title: '' }, updateFields: { firstname, lastname } };\n}\n" }, "n_5fc5fb52218a6cdd": { "name": "Confirm one exact email match", "imports": [], "source": "export default function mauticCustomerMatch({ contacts, email }) {\n if (!Array.isArray(contacts)) throw new Error('Mautic contact search did not return an array');\n if (contacts.length >= 30) throw new Error('Mautic search filled the 30-contact source window; narrow the data before retrying');\n const matches = contacts.filter(contact => typeof contact?.fields?.all?.email === 'string' && contact.fields.all.email.trim().toLowerCase() === email.toLowerCase());\n if (matches.length > 1) throw new Error('More than one Mautic contact has the customer email');\n if (matches.length === 0 && contacts.length > 0) throw new Error('Mautic search returned contacts without an exact customer email match');\n const matched = matches[0] ?? null;\n if (matched != null && (!Number.isSafeInteger(matched.id) || matched.id <= 0)) throw new Error('Matched Mautic contact ID is invalid');\n return { create: matched == null, matched };\n}\n" }, "n_ade96d893b2403dd": { "name": "Select the existing contact ID", "imports": [], "source": "export default function mauticCustomerUpdate({ matched, fields }) {\n if (!Number.isSafeInteger(matched?.id) || matched.id <= 0) throw new Error('A matched Mautic contact is required for an update');\n return { contactId: matched.id, fields };\n}\n" }, "n_fb362beda04783f0": { "name": "Check the saved contact ID", "imports": [], "source": "export default function mauticContactSaved({ contact }) {\n if (!contact || typeof contact !== 'object' || Array.isArray(contact) || !Number.isInteger(contact.id) || contact.id <= 0) {\n throw new Error('Mautic did not return a saved contact ID');\n }\n return { contact };\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }