Describe the problem/error/question
Whenever I try to map the salesforce accountID to the accountID field within the create a Salesforce contact
, I get a perpetual loading error.
What is the error message (if any)?
Please share your workflow
{
“nodes”: [
{
“parameters”: {
“public”: true,
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.chatTrigger”,
“typeVersion”: 1.1,
“position”: [
1800,
-20
],
“id”: “7bb6c87d-e012-41bf-88ce-ca313fcfef25”,
“name”: “When chat message received”,
“webhookId”: “c1bac28a-289a-4a31-8ecf-d764dbf28148”
},
{
“parameters”: {
“assignments”: {
“assignments”: [
{
“id”: “16ab2d5f-17c5-4f89-b8a7-d1b22b5296c7”,
“name”: “inputData”,
“value”: “={{$json.chatInput}}”,
“type”: “string”
}
]
},
“includeOtherFields”: true,
“options”: {}
},
“type”: “n8n-nodes-base.set”,
“typeVersion”: 3.4,
“position”: [
2000,
-20
],
“id”: “f5ea1034-6fbc-4adf-bd0f-b29cb44ffab3”,
“name”: “Parse Input”
},
{
“parameters”: {
“resource”: “account”,
“operation”: “get”,
“accountId”: “={{ $json.inputData }}”
},
“type”: “n8n-nodes-base.salesforce”,
“typeVersion”: 1,
“position”: [
2180,
-20
],
“id”: “90543825-5623-4e3a-b46e-29ab4e2ce63f”,
“name”: “Get Salesforce Account”,
“credentials”: {
“salesforceOAuth2Api”: {
“id”: “hjHTvez00sOqWDBB”,
“name”: “Salesforce account”
}
}
},
{
“parameters”: {
“jsCode”: “// Combine account data with website info\nconst website = $input.first().json.Website;\nconst accountId = $input.first().json.Id;\n\n// Create structured data for the next node\nreturn [{\n json: {\n website: website,\n accountId: accountId,\n prompt: #CONTEXT# Research an organization and find email contacts on its website. #OBJECTIVE# Identify and extract any email addresses available on the ${website}'s website. #INSTRUCTIONS# 1. Visit the official website of the ${accountId} at ${website}. 2. Scrutinize the website's pages (such as contact, about, support, etc.) for any visible email addresses. 3. Compile a list of all email addresses found. 4. Return the list of email addresses as the output. 5. If no email addresses are found, return a message stating \"None\" 6. Ignore any emails that look related to the website developer. #EXAMPLES# Example of expected output when email addresses are found: [\"[email protected]\", \"[email protected]\"] If no emails are found, return \"None\" Also return the website / url visited and the rationale for the email return. If a name is listed with the email (i.e. in proximity to the email), return that as a separate part of the array. If no name is found, return \"Generic Email\"
\n }\n}];”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 1,
“position”: [
2380,
-20
],
“id”: “b0f4c83e-8408-4452-9e12-8187fc83b45b”,
“name”: “Prepare Search Prompt”
},
{
“parameters”: {
“jsCode”: “// Parse the OpenAI response and prepare Salesforce contact creation data\ntry {\n // Log the entire input for debugging\n console.log("Complete input:", JSON.stringify(items[0], null, 2));\n \n // First get the accountId - need to handle all possible locations\n let accountId;\n \n // Try all possible paths where accountId might be\n if (items[0].json.accountId) {\n accountId = items[0].json.accountId;\n } else if (items[0].json.json && items[0].json.json.accountId) {\n accountId = items[0].json.json.accountId;\n } else if (items[0].additional && items[0].additional.accountId) {\n accountId = items[0].additional.accountId;\n } else if (items[0].json.message && items[0].json.message.content && \n typeof items[0].json.message.content === ‘string’) {\n // Try to extract accountId from the message content string\n const accountIdMatch = items[0].json.message.content.match(/"accountId"\s*:\s*"([^"]+)"/);\n if (accountIdMatch && accountIdMatch[1]) {\n accountId = accountIdMatch[1];\n console.log("Found accountId in message content:", accountId);\n } else {\n console.error("Could not find accountId in message content");\n accountId = "unknown-account";\n }\n } else {\n // Set a default or fetch from previous nodes if needed\n console.error("Could not find accountId in input!");\n accountId = "unknown-account";\n }\n \n console.log("Using account ID:", accountId);\n \n // Extract emails from the response\n let emails = ;\n let website = "";\n let rationale = "";\n \n // Check if emails are directly in message.content (which might be pre-parsed JSON)\n if (items[0].json.message && items[0].json.message.content) {\n console.log("Found content in message");\n \n if (typeof items[0].json.message.content === ‘string’) {\n // Content is a string, need to parse JSON from it\n try {\n // Try to extract JSON from the string\n let contentStr = items[0].json.message.content;\n const jsonMatch = contentStr.match(/\{[\s\S]*\}/);\n if (jsonMatch) {\n contentStr = jsonMatch[0];\n }\n \n const contentObj = JSON.parse(contentStr);\n emails = contentObj.emails || ;\n website = contentObj.website || "";\n rationale = contentObj.rationale || "";\n } catch (parseError) {\n console.error("Error parsing content string:", parseError);\n \n // Try to extract emails using regex as fallback\n const emailRegex = /[a-zA-Z0-9._%±]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;\n const matches = items[0].json.message.content.match(emailRegex);\n \n if (matches) {\n emails = matches.map(email => ({ email, name: "Generic Email" }));\n }\n }\n } else if (typeof items[0].json.message.content === ‘object’) {\n // Content is already an object\n if (items[0].json.message.content.emails) {\n emails = items[0].json.message.content.emails;\n website = items[0].json.message.content.website || "";\n rationale = items[0].json.message.content.rationale || "";\n }\n }\n } else if (items[0].json.content) {\n // Try the original expected path\n try {\n const result = JSON.parse(items[0].json.content);\n emails = result.emails || ;\n website = result.website || "";\n rationale = result.rationale || "";\n } catch (parseError) {\n console.error("Error parsing content:", parseError);\n }\n }\n \n console.log("Extracted emails:", emails);\n \n // Check if we found any emails\n if (!emails || emails.length === 0) {\n console.log("No emails found");\n // Return a message with accountId to show the process ran\n return [{\n json: {\n accountId: accountId,\n message: "No email addresses found",\n website: website,\n rationale: rationale\n }\n }];\n }\n \n // Log the emails found\n console.log(Found ${emails.length} emails to process for account ${accountId}
);\n \n // Create a contact item for each email found\n return emails.map(emailItem => {\n // Log each email item for debugging\n console.log("Processing email item for account", accountId, ":", emailItem);\n \n return {\n json: {\n accountId: accountId,\n email: emailItem.email || ‘’,\n name: emailItem.name && emailItem.name !== "Generic Email" ? emailItem.name : null,\n website: website || ‘’,\n rationale: rationale || ‘’\n }\n };\n });\n} catch (error) {\n console.error("Error processing emails:", error.message);\n console.error("Error stack:", error.stack);\n \n // Find accountId even in error case\n let errorAccountId = "unknown-account";\n if (items[0] && items[0].json) {\n errorAccountId = items[0].json.accountId || errorAccountId;\n }\n \n // Return error info with accountId\n return [{\n json: {\n error: true,\n message: Failed to process emails: ${error.message}
,\n accountId: errorAccountId\n }\n }];\n}”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 1,
“position”: [
2780,
-300
],
“id”: “fd9cf11f-8aa4-41cf-ba0a-dcfc2411f906”,
“name”: “Process Email Results”
},
{
“parameters”: {
“options”: {}
},
“type”: “n8n-nodes-base.splitInBatches”,
“typeVersion”: 3,
“position”: [
2860,
-80
],
“id”: “0d90298c-e50c-4891-8681-d2bdc82b6315”,
“name”: “Loop Over Emails”
},
{
“parameters”: {
“jsCode”: “// Format the contact data for Salesforce\nconst contactData = items[0].json;\n\n// Split full name if available\nlet firstName = "";\nlet lastName = "Website Contact";\n\nif (contactData.name) {\n const nameParts = contactData.name.split(’ ‘);\n if (nameParts.length > 1) {\n // Take the last part as the last name, everything else as first name\n lastName = nameParts.pop();\n firstName = nameParts.join(’ ');\n } else if (nameParts.length === 1) {\n // Only one part, use as last name\n lastName = nameParts[0];\n }\n}\n\nreturn [{\n json: {\n FirstName: firstName,\n LastName: lastName,\n Email: contactData.email,\n AccountId: contactData.accountId,\n Description: Found via website scan of ${contactData.website}. Rationale: ${contactData.rationale}
\n }\n}];”
},
“type”: “n8n-nodes-base.code”,
“typeVersion”: 1,
“position”: [
3040,
-40
],
“id”: “1a8aaea8-253b-4756-89dd-195dd5bc5254”,
“name”: “Format Contact Data”
},
{
“parameters”: {
“resource”: “contact”,
“lastname”: “={{ $json.LastName }}”,
“additionalFields”: {
“acconuntId”: “”,
“email”: “={{ $json.Email }}”
}
},
“type”: “n8n-nodes-base.salesforce”,
“typeVersion”: 1,
“position”: [
3200,
-40
],
“id”: “9ba91e72-09e2-4ab5-941e-580d6f82d2d4”,
“name”: “Create Salesforce Contact”,
“credentials”: {
“salesforceOAuth2Api”: {
“id”: “hjHTvez00sOqWDBB”,
“name”: “Salesforce account”
}
}
},
{
“parameters”: {
“respondWith”: “json”,
“options”: {}
},
“type”: “n8n-nodes-base.respondToWebhook”,
“typeVersion”: 1,
“position”: [
3380,
-40
],
“id”: “3d4981b1-fbbd-4642-9a6f-d95c5c1cdca9”,
“name”: “Send Success Message”
},
{
“parameters”: {},
“type”: “n8n-nodes-base.noOp”,
“typeVersion”: 1,
“position”: [
3600,
-40
],
“id”: “92c8846d-3a11-48ae-9886-77fda8f9621f”,
“name”: “Loop Continuation”
},
{
“parameters”: {
“respondWith”: “json”,
“options”: {}
},
“type”: “n8n-nodes-base.respondToWebhook”,
“typeVersion”: 1,
“position”: [
3160,
-200
],
“id”: “f3d6e0d4-8bcf-4711-a25e-51f85821f2c1”,
“name”: “Send Completion Message”
},
{
“parameters”: {
“modelId”: {
“__rl”: true,
“mode”: “list”,
“value”: “gpt-4o”
},
“messages”: {
“values”: [
{
“content”: “You are a helpful assistant that searches websites to find email addresses. Return your findings in valid JSON format with the following structure: {"emails": [{"email": "[email protected]", "name": "Person Name or Generic Email"}], "website": "url_visited", "rationale": "explanation of findings", "accountId": "the_account_id_provided_in_the_request"}”,
“role”: “system”
},
{
“content”: “={{ $json.prompt }}”
}
]
},
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.openAi”,
“typeVersion”: 1.8,
“position”: [
2380,
280
],
“id”: “42d680dd-6bdb-4279-99c6-4a74256fab1f”,
“name”: “GPT4o Search for Emails”,
“credentials”: {
“openAiApi”: {
“id”: “BJvqRr76R3hHEdNk”,
“name”: “OpenAi account 3”
}
}
}
],
“connections”: {
“When chat message received”: {
“main”: [
[
{
“node”: “Parse Input”,
“type”: “main”,
“index”: 0
}
]
]
},
“Parse Input”: {
“main”: [
[
{
“node”: “Get Salesforce Account”,
“type”: “main”,
“index”: 0
}
]
]
},
“Get Salesforce Account”: {
“main”: [
[
{
“node”: “Prepare Search Prompt”,
“type”: “main”,
“index”: 0
}
]
]
},
“Prepare Search Prompt”: {
“main”: [
[
{
“node”: “GPT4o Search for Emails”,
“type”: “main”,
“index”: 0
}
]
]
},
“Process Email Results”: {
“main”: [
[
{
“node”: “Loop Over Emails”,
“type”: “main”,
“index”: 0
}
]
]
},
“Loop Over Emails”: {
“main”: [
[
{
“node”: “Send Completion Message”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Format Contact Data”,
“type”: “main”,
“index”: 0
}
]
]
},
“Format Contact Data”: {
“main”: [
[
{
“node”: “Create Salesforce Contact”,
“type”: “main”,
“index”: 0
}
]
]
},
“Create Salesforce Contact”: {
“main”: [
[
{
“node”: “Send Success Message”,
“type”: “main”,
“index”: 0
}
]
]
},
“Send Success Message”: {
“main”: [
[
{
“node”: “Loop Continuation”,
“type”: “main”,
“index”: 0
}
]
]
},
“Loop Continuation”: {
“main”: [
[
{
“node”: “Loop Over Emails”,
“type”: “main”,
“index”: 0
}
]
]
},
“GPT4o Search for Emails”: {
“main”: [
[
{
“node”: “Process Email Results”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“instanceId”: “0ec985192c605966c0abc9ac864deca8882e58030eae30cf54b2e12b1187a079”
}
}
Share the output returned by the last node
Information on your n8n setup
- n8n version:
- Version 1.84.3
- Running n8n via (Docker, npm, n8n cloud, desktop app):
- n8n Cloud
- Operating system:
- Mac