WordPress to ITFlow Integration - Workflow Explanation
Overview
This n8n workflow automatically processes website contact form submissions from WordPress and creates support tickets in ITFlow, your IT management system. It intelligently handles duplicate contacts and ensures clean data entry.
How It Works (Step-by-Step)
1. Website Lead (Webhook Trigger)
2. Sort Data (JavaScript Parser)
Parses incoming form data from multiple WordPress form formats
Handles different field IDs and naming conventions (supports both "old" and "kiosk" form schemas)
Extracts and normalizes:
Contact information (name, email, phone)
Ticket details (subject, description, type)
Address information (if provided)
Form metadata (form title, URL, etc.)
Smart field detection: looks for fields by ID first, then falls back to field names/types
3. Lookup Contact
4. Contact Exists? (Conditional Branch)
5a. For Existing Contacts:
- Set Existing IDs: Extracts client and contact IDs from the lookup result
5b. For New Contacts:
Create Client: Creates a new client record in ITFlow with:
- Client type: "Lead"
- Referral source: "Website Form - [Form Name]"
- Default rate: $90 CAD, Net 30 terms
Create Contact: Creates contact record linked to the new client
Set New IDs: Prepares the newly created IDs for ticket creation
6. Create Ticket (Final Step)
- Creates a support ticket in ITFlow with:
- The parsed subject and details from the form
- Linked to the correct client and contact (whether existing or new)
- Priority: Low
- Status: Unassigned
Key Features
Smart Field Detection The parser is robust and can handle different WordPress form plugins and configurations by checking multiple field IDs and names.
Duplicate Prevention The workflow checks for existing contacts before creating new records, preventing duplicate entries in your system.
Flexible Form Support Handles various form fields including:
Standard contact info (name, email, phone)
Address fields
File uploads
Agreement/consent checkboxes
Custom ticket types
Automatic Classification
New submissions are marked as "Leads"
Referral source tracks which form was used
All automated entries are tagged with "created by webform automation"
Setup Requirements
To use this workflow, you'll need to:
Replace YOUR_API_KEY_HERE
with your ITFlow API key
Replace YOUR-ITFLOW-DOMAIN
with your ITFlow installation domain
Replace YOUR-WEBHOOK-ID-HERE
with a unique webhook identifier
Configure your WordPress forms to POST to the webhook URL
API Reference
This workflow uses the ITFlow API endpoints for clients, contacts, and tickets.
{
"name": "Wordpress to ITFlow",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "YOUR-WEBHOOK-ID-HERE",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [-816, -208],
"id": "32ccd401-b2fa-4098-bfa3-999d938c9129",
"name": "Website Lead",
"webhookId": "YOUR-WEBHOOK-ID-HERE"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Robust parser for multiple WP form schemas (old + kiosk)\n// Works whether payload is at $json.body or $json directly\n\nconst src = $json.body ?? $json;\nconst formData = src.form_data ?? {};\n\nconst clean = (v) => {\n if (v === undefined || v === null) return '';\n if (typeof v === 'string') return v.trim();\n return v;\n};\n\n// Helpers\nconst firstNonEmpty = (...vals) => vals.find(v => {\n const c = clean(v);\n return (typeof c === 'string' ? c.length > 0 : !!c);\n}) ?? '';\n\nconst getFieldById = (id) => formData?.[String(id)];\nconst getFieldValue = (id) => getFieldById(id)?.value;\n\nconst findByName = (names = [], types = []) => {\n const wanted = names.map(n => String(n).toLowerCase());\n const tWanted = types.map(t => String(t).toLowerCase());\n for (const k of Object.keys(formData)) {\n const f = formData[k] || {};\n const nm = String(f.name ?? '').toLowerCase();\n const tp = String(f.type ?? '').toLowerCase();\n if ((wanted.length && wanted.includes(nm)) || (tWanted.length && tWanted.includes(tp))) {\n return f;\n }\n }\n return undefined;\n};\n\n// Name (support: old id 92, new id 72, or by name/type)\nconst nameField =\n getFieldById(92) ??\n getFieldById(72) ??\n findByName(['name'], ['name']);\n\nconst firstName = clean(nameField?.value?.first);\nconst lastName = clean(nameField?.value?.last);\nconst contact_name = `${firstName} ${lastName}`.trim();\n\n// Email (old 93, new 73, by name/type)\nconst emailField =\n getFieldById(93) ??\n getFieldById(73) ??\n findByName(['email', 'e-mail'], ['email']);\nconst contact_email = clean(emailField?.value);\n\n// Phone (old 96 or by name/type). Kiosk may not send it.\nconst phoneField =\n getFieldById(96) ??\n findByName(['phone','telephone','tel','mobile','cell'], ['phone','tel']);\nconst contact_phone = clean(phoneField?.value);\n\n// Subject (old 94 or by common names). Kiosk may lack it.\nconst subjectField =\n getFieldById(94) ??\n findByName(['subject','title']);\nconst ticket_subject = firstNonEmpty(\n clean(subjectField?.value),\n `Website Contact Form${src.form_title ? ` - ${clean(src.form_title)}` : ''}`\n);\n\n// Details / Issue (old 97, kiosk 75, or common names)\nconst detailsField =\n getFieldById(97) ??\n getFieldById(75) ??\n findByName(['issue','message','details','description','problem','body','notes']);\nconst ticket_details = firstNonEmpty(\n clean(detailsField?.value),\n clean(subjectField?.value),\n 'No details provided'\n);\n\n// Ticket type (old 98 or by name). Optional.\nconst typeField = getFieldById(98) ?? findByName(['type','category','topic']);\nconst ticket_type = clean(typeField?.value);\n\n// Address (old 95 structure). Optional.\nconst addr = getFieldById(95)?.value ?? {};\nconst address_line1 = clean(addr.line1);\nconst address_line2 = clean(addr.line2);\nconst address_city = clean(addr.city);\nconst address_state = clean(addr.state);\nconst address_zip = clean(addr.zip);\nconst address_country = clean(addr.country);\n\n// Upload URL (old 99). Optional.\nconst upload_url = clean(getFieldValue(99));\n\n// Agreement checkbox (old 103). Optional.\nconst ag = getFieldById(103)?.value ?? {};\nconst agreement_accepted = !!ag['0'];\nconst agreement_text = clean(ag['0']);\n\n// Compose address\nconst full_address = [address_line1, address_line2, address_city, address_state, address_zip, address_country]\n .filter(p => clean(p)).join(', ');\n\n// Output shape consumed by downstream nodes\nreturn {\n contact_name,\n first_name: firstName,\n last_name: lastName,\n contact_email,\n contact_phone,\n\n ticket_subject,\n ticket_details,\n ticket_type,\n\n address_line1,\n address_line2,\n address_city,\n address_state,\n address_zip,\n address_country,\n full_address,\n\n upload_url,\n agreement_accepted,\n agreement_text,\n\n // Back-compat for Create Client / Create Contact nodes\n client_name: contact_name,\n email: contact_email,\n issue: ticket_details,\n\n // Meta\n timestamp: new Date().toISOString(),\n form_id: clean(src.form_id),\n form_title: clean(src.form_title),\n form_url: clean(src.form_url)\n};\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [-624, -208],
"id": "7e03239c-7ba3-43c6-94c3-cf4e6009fef6",
"name": "Sort Data"
},
{
"parameters": {
"url": "https://YOUR-ITFLOW-DOMAIN/api/v1/contacts/read.php",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "api_key",
"value": "YOUR_API_KEY_HERE"
},
{
"name": "contact_email",
"value": "={{ $json.contact_email }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [-416, -208],
"id": "8b80abd6-e708-4c07-9e7d-1abecb46db08",
"name": "Lookup Contact"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "73cc5126-cecc-4ee5-9876-f60255053c56",
"leftValue": "={{ $json.success }}",
"rightValue": "True",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [-224, -208],
"id": "4c52d646-60b3-4afd-90b7-7da372ed5c0a",
"name": "Contact Exists?"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "a1b2c3d4",
"name": "client_id",
"value": "={{ $json.data[0].contact_client_id }}",
"type": "string"
},
{
"id": "e5f6g7h8",
"name": "ticket_contact_id",
"value": "={{ $json.data[0].contact_id }}",
"type": "string"
},
{
"id": "spreader",
"name": "=",
"value": "={{ $('Sort Data').item.json }}",
"type": "object"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [-16, -304],
"id": "8357da20-6e4d-4c9a-ab87-7a1b8b932e93",
"name": "Set Existing IDs"
},
{
"parameters": {
"method": "POST",
"url": "https://YOUR-ITFLOW-DOMAIN/api/v1/clients/create.php",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"api_key\": \"YOUR_API_KEY_HERE\",\n \"client_name\": \"{{ $('Sort Data').item.json.client_name }}\",\n \"client_email\": \"{{ $('Sort Data').item.json.email }}\",\n \"client_type\": \"Lead\",\n \"client_website\": \"\",\n \"client_referral\": \"Website Form - {{ $('Sort Data').item.json.form_title }}\",\n \"client_rate\": \"90\",\n \"client_currency_code\": \"CAD\",\n \"client_net_terms\": \"30\",\n \"client_tax_id_number\": \"\",\n \"client_is_lead\": \"0\",\n \"client_notes\": \"created by webform automation\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [-16, -112],
"id": "56c455d1-65a9-456e-91bb-9282cc78375a",
"name": "Create Client"
},
{
"parameters": {
"method": "POST",
"url": "https://YOUR-ITFLOW-DOMAIN/api/v1/contacts/create.php",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"api_key\": \"YOUR_API_KEY_HERE\",\n \"client_id\": \"{{ $('Create Client').item.json.data[0].insert_id }}\",\n \"contact_name\": \"{{ $('Sort Data').item.json.contact_name }}\",\n \"contact_title\": \"Web Lead\",\n \"contact_department\": \"\",\n \"contact_email\": \"{{ $('Sort Data').item.json.contact_email }}\",\n \"contact_phone\": \"{{ $('Sort Data').item.json.contact_phone }}\",\n \"contact_extension\": \"\",\n \"contact_mobile\": \"\",\n \"contact_notes\": \"created by webform automation\",\n \"contact_auth_method\": \"local\",\n \"contact_important\": \"0\",\n \"contact_billing\": \"0\",\n \"contact_technical\": \"0\",\n \"contact_location_id\": \"0\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [176, -112],
"id": "6b8cd9d4-66d2-4ef9-8798-c80774a660f7",
"name": "Create Contact"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "i9j0k1l2",
"name": "client_id",
"value": "={{ $('Create Client').item.json.data[0].insert_id }}",
"type": "string"
},
{
"id": "m3n4o5p6",
"name": "ticket_contact_id",
"value": "={{ $json.data[0].insert_id }}",
"type": "string"
},
{
"id": "spreader2",
"name": "=",
"value": "={{ $('Sort Data').item.json }}",
"type": "object"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [384, -112],
"id": "4f6bdcf3-4cfa-415e-95b4-1aebc514bb8f",
"name": "Set New IDs"
},
{
"parameters": {
"method": "POST",
"url": "https://YOUR-ITFLOW-DOMAIN/api/v1/tickets/create.php",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"api_key\": \"YOUR_API_KEY_HERE\",\n \"client_id\": \"{{ $json.client_id }}\",\n \"ticket_contact_id\": \"{{ $json.ticket_contact_id }}\",\n \"ticket_subject\": \"{{ $('Sort Data').item.json.ticket_subject }}\",\n \"ticket_details\": \"{{ $('Sort Data').item.json.ticket_details }}\",\n \"ticket_priority\": \"Low\",\n \"ticket_assigned_to\": \"0\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [784, -208],
"id": "1a6c36b6-098f-432c-a820-2740befff6aa",
"name": "Create Ticket"
}
],
"connections": {
"Website Lead": {
"main": [[{"node": "Sort Data", "type": "main", "index": 0}]]
},
"Sort Data": {
"main": [[{"node": "Lookup Contact", "type": "main", "index": 0}]]
},
"Lookup Contact": {
"main": [[{"node": "Contact Exists?", "type": "main", "index": 0}]]
},
"Contact Exists?": {
"main": [
[{"node": "Set Existing IDs", "type": "main", "index": 0}],
[{"node": "Create Client", "type": "main", "index": 0}]
]
},
"Set Existing IDs": {
"main": [[{"node": "Create Ticket", "type": "main", "index": 0}]]
},
"Create Client": {
"main": [[{"node": "Create Contact", "type": "main", "index": 0}]]
},
"Create Contact": {
"main": [[{"node": "Set New IDs", "type": "main", "index": 0}]]
},
"Set New IDs": {
"main": [[{"node": "Create Ticket", "type": "main", "index": 0}]]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"saveExecutionProgress": true,
"callerPolicy": "workflowsFromSameOwner"
}
}