This workflow corresponds to n8n.io template #5590 — we link there as the canonical source.
This workflow follows the HTTP Request → Notion recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "h7YubkTUmnZrsMQs",
"name": "Sync Contacts from Notion to Google Contacts with Group Labels",
"tags": [],
"nodes": [
{
"id": "9884a0d6-5969-4e36-9d1e-e9026cfd2fae",
"name": "Get All Contacts from Notion",
"type": "n8n-nodes-base.notion",
"position": [
260,
240
],
"parameters": {
"options": {},
"resource": "databasePage",
"operation": "getAll",
"returnAll": true,
"databaseId": {
"__rl": true,
"mode": "id",
"value": "Enter your Notion database ID here."
}
},
"credentials": {},
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "14397583-f0e6-4bc4-9bf1-ac87f80e701a",
"name": "Find Match Labels",
"type": "n8n-nodes-base.code",
"position": [
1400,
240
],
"parameters": {
"jsCode": "// Get raw label from Edit Fields\nconst rawLabel = $('Loop Over Contacts').first().json.label || '';\nconsole.log(\"rawLabel:\", rawLabel);\n\n// Parse if it\u2019s a stringified array, otherwise treat as array or single value\nlet labelNames;\nif (typeof rawLabel === 'string') {\n try {\n labelNames = JSON.parse(rawLabel); // Convert \"['Gelatin 180-200']\" to [\"Gelatin 180-200\"]\n } catch (e) {\n labelNames = [rawLabel]; // If not valid JSON, treat as single string\n }\n} else if (Array.isArray(rawLabel)) {\n labelNames = rawLabel; // Already an array\n} else {\n labelNames = rawLabel ? [rawLabel] : []; // Fallback\n}\n\nconst contactGroups = $input.first().json.contactGroups || [];\n\nconsole.log(\"labelNames (parsed):\", labelNames);\nconsole.log(\"contactGroups:\", contactGroups);\n\n// Match labels and extract resourceName\nconst matchedLabels = labelNames.map(label => {\n const group = contactGroups.find(g => \n g.name.trim().toLowerCase() === label.trim().toLowerCase() && \n g.groupType === \"USER_CONTACT_GROUP\"\n );\n console.log(`Searching for: \"${label}\", Found:`, group);\n return {\n name: label,\n resourceName: group ? [group.resourceName] : null // Wrap resourceName in an array\n };\n});\n\nconsole.log(\"matchedLabels:\", matchedLabels);\n\nreturn matchedLabels.map(label => ({\n json: {\n name: label.name,\n resourceName: label.resourceName // Now an array like [\"contactGroups/40cf29798a92c131\"]\n }\n}));"
},
"executeOnce": true,
"typeVersion": 2
},
{
"id": "bc13d96d-951e-4d7a-90ed-af96617647ef",
"name": "Add Contact to Google Contacts",
"type": "n8n-nodes-base.googleContacts",
"position": [
1880,
240
],
"parameters": {
"givenName": "={{ $('Loop Over Contacts').item.json.firstName }}",
"additionalFields": {
"group": "={{ $json.resourceName }}",
"phoneUi": {
"phoneValues": [
{
"type": "home",
"value": "={{ $('Loop Over Contacts').item.json.phone }}"
}
]
}
}
},
"credentials": {},
"executeOnce": false,
"typeVersion": 1
},
{
"id": "d61f9032-9982-4aaf-ab68-c827c345c14d",
"name": "Workflow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-40,
-540
],
"parameters": {
"width": 1600,
"height": 520,
"content": "# Sync Notion Contacts to Google Contacts with Group Labels\nThis workflow syncs contacts from a Notion database to Google Contacts, assigning group labels based on Notion properties. It triggers on new or updated contacts, retrieves details (name, phone, labels), checks/creates Google Contact groups, adds the contact, and updates Notion to mark it as synced.\n\n**Setup Instructions:**\n1. Connect Notion and Google Contacts via OAuth2 in n8n\u2019s credential settings.\n2. Set your Notion database ID in the Notion Trigger node (find it in your Notion database URL, e.g., 0427eb01ed3b4947873382c566f23785).\n3. Ensure Notion database has fields: name, phone, labels, and \u201cAdded to Contacts\u201d checkbox.\n4. Test the workflow to confirm syncing.\n\n**Requirements:**\n- Notion account with a contact database.\n- Google Contacts account with OAuth2.\n- **Self-hosted n8n instance required (uses community nodes).**\n\nFor advanced setups, see [Notion\u2019s API guide](https://developers.notion.com/)."
},
"typeVersion": 1
},
{
"id": "1c52ad45-98ff-4f32-b58e-81dfe4eda13d",
"name": "Trigger Explanation",
"type": "n8n-nodes-base.stickyNote",
"position": [
-40,
20
],
"parameters": {
"color": 6,
"width": 260,
"height": 520,
"content": "Triggers the workflow when a new contact is added or an existing contact is updated in the specified Notion database."
},
"typeVersion": 1
},
{
"id": "61818fe5-608c-4410-b8fe-f76a203b0123",
"name": "Field Mapping Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
440,
20
],
"parameters": {
"color": 6,
"width": 220,
"height": 400,
"content": "Maps Notion fields (name, phone, labels, added status) to variables for further processing. Customize here to add more fields like email."
},
"typeVersion": 1
},
{
"id": "12fb9b67-4b5a-40b0-90f1-f7e896cd47d9",
"name": "Label Matching Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
1340,
20
],
"parameters": {
"color": 6,
"width": 220,
"height": 400,
"content": "Matches Notion labels to existing Google Contact groups, parsing labels from Notion\u2019s property_buy field."
},
"typeVersion": 1
},
{
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Already Synced Check Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
920,
20
],
"parameters": {
"color": 6,
"width": 220,
"height": 400,
"content": "Checks if the contact has already been synced to Google Contacts using the 'Already Added' field in Notion."
},
"typeVersion": 1
},
{
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Group Existence Check Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
1580,
20
],
"parameters": {
"color": 6,
"width": 220,
"height": 400,
"content": "Verifies if the specified group label exists in Google Contacts. If not, a new group is created."
},
"typeVersion": 1
},
{
"id": "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f",
"name": "Create Group Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
1580,
-160
],
"parameters": {
"color": 6,
"width": 220,
"height": 400,
"content": "Creates a new group in Google Contacts if the specified label doesn\u2019t exist."
},
"typeVersion": 1
},
{
"id": "d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a",
"name": "Add Contact Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
1820,
20
],
"parameters": {
"color": 6,
"width": 220,
"height": 400,
"content": "Adds the contact to Google Contacts with the specified name, phone, and group labels."
},
"typeVersion": 1
},
{
"id": "566b7be5-6090-48eb-acb2-71c0844c240b",
"name": "Map Notion Contact Fields",
"type": "n8n-nodes-base.set",
"position": [
500,
240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cf7632d2-9983-4c09-8021-7043b8606c48",
"name": "firstName",
"type": "string",
"value": "={{ $json.name }}"
},
{
"id": "bc1f218c-bd1b-4b07-b812-1569f483a838",
"name": "label",
"type": "string",
"value": "={{ $json.property_buy }}"
},
{
"id": "d62010cd-2768-40a4-9279-c4742575a7bd",
"name": "phone",
"type": "string",
"value": "={{ $json.property_phone }}"
},
{
"id": "71fe5268-8798-4641-9395-1c2295c83ae0",
"name": "Already Added",
"type": "string",
"value": "={{ $json.property_added_to_contacts }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8f91fe10-353f-4a03-8ddf-18c8958188aa",
"name": "Loop Over Contacts",
"type": "n8n-nodes-base.splitInBatches",
"position": [
760,
240
],
"parameters": {
"options": {
"reset": false
}
},
"typeVersion": 3
},
{
"id": "2d832694-f231-4201-8432-9d032e000d7f",
"name": "Fetch Google Contact Groups",
"type": "n8n-nodes-base.httpRequest",
"position": [
1180,
240
],
"parameters": {
"url": "https://people.googleapis.com/v1/contactGroups",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "pageSize",
"value": "1000"
}
]
},
"nodeCredentialType": "googleContactsOAuth2Api"
},
"credentials": {},
"typeVersion": 4.2
},
{
"id": "d9660c1f-9672-4cf0-8196-fee0b0acb8d3",
"name": "Check Google Contact Group Exists",
"type": "n8n-nodes-base.if",
"position": [
1640,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f8e38a64-ace8-49e8-b400-c6609db670e9",
"operator": {
"type": "array",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.resourceName }}",
"rightValue": "null"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c913cf75-f9eb-4b27-b5f3-5bae32ee0d86",
"name": "Mark Contact as Synced in Notion",
"type": "n8n-nodes-base.notion",
"position": [
2080,
240
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "url",
"value": "={{ $('Get All Contacts from Notion').item.json.url }}"
},
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "Added to Contacts|checkbox",
"checkboxValue": true
}
]
}
},
"credentials": {},
"typeVersion": 2.2
},
{
"id": "d8f8f322-26c2-4c22-bc74-22db9c67cfd3",
"name": "Create New Google Contact Group",
"type": "n8n-nodes-base.httpRequest",
"position": [
1640,
40
],
"parameters": {
"url": "https://people.googleapis.com/v1/contactGroups",
"method": "POST",
"options": {},
"jsonBody": "={\n \"contactGroup\": {\n \"name\": \"{{ $json.name }}\"\n }\n} ",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleContactsOAuth2Api"
},
"credentials": {},
"typeVersion": 4.2
},
{
"id": "8e01eb00-ba8b-495b-bcec-38c50d631357",
"name": "Check if Contact Already Synced",
"type": "n8n-nodes-base.if",
"position": [
980,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a707ab4a-4300-4626-bc72-d0bd6126f733",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('Map Notion Contact Fields').item.json['Already Added'].toBoolean() }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "7a218d3f-9a76-4f21-a599-f550f3642159",
"name": "Trigger on New Notion Contact",
"type": "n8n-nodes-base.notionTrigger",
"position": [
40,
160
],
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyWeek"
}
]
},
"databaseId": {
"__rl": true,
"mode": "id",
"value": "Enter your Notion database ID here."
}
},
"credentials": {},
"typeVersion": 1
},
{
"id": "871cfdb2-8353-4347-8b96-23d0deacb3cd",
"name": "Trigger on Updated Notion Contact",
"type": "n8n-nodes-base.notionTrigger",
"position": [
40,
360
],
"parameters": {
"event": "pagedUpdatedInDatabase",
"pollTimes": {
"item": [
{
"mode": "everyWeek"
}
]
},
"databaseId": {
"__rl": true,
"mode": "id",
"value": "Enter your Notion database ID here."
}
},
"credentials": {},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "c0a0f606-780f-4f03-95d9-6d7ad6c12790",
"connections": {
"Find Match Labels": {
"main": [
[
{
"node": "Check Google Contact Group Exists",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Contacts": {
"main": [
[],
[
{
"node": "Check if Contact Already Synced",
"type": "main",
"index": 0
}
]
]
},
"Map Notion Contact Fields": {
"main": [
[
{
"node": "Loop Over Contacts",
"type": "main",
"index": 0
}
]
]
},
"Fetch Google Contact Groups": {
"main": [
[
{
"node": "Find Match Labels",
"type": "main",
"index": 0
}
]
]
},
"Get All Contacts from Notion": {
"main": [
[
{
"node": "Map Notion Contact Fields",
"type": "main",
"index": 0
}
]
]
},
"Trigger on New Notion Contact": {
"main": [
[
{
"node": "Get All Contacts from Notion",
"type": "main",
"index": 0
}
]
]
},
"Add Contact to Google Contacts": {
"main": [
[
{
"node": "Mark Contact as Synced in Notion",
"type": "main",
"index": 0
}
]
]
},
"Check if Contact Already Synced": {
"main": [
[
{
"node": "Loop Over Contacts",
"type": "main",
"index": 0
}
],
[
{
"node": "Fetch Google Contact Groups",
"type": "main",
"index": 0
}
]
]
},
"Create New Google Contact Group": {
"main": [
[
{
"node": "Loop Over Contacts",
"type": "main",
"index": 0
}
]
]
},
"Mark Contact as Synced in Notion": {
"main": [
[
{
"node": "Loop Over Contacts",
"type": "main",
"index": 0
}
]
]
},
"Check Google Contact Group Exists": {
"main": [
[
{
"node": "Create New Google Contact Group",
"type": "main",
"index": 0
}
],
[
{
"node": "Add Contact to Google Contacts",
"type": "main",
"index": 0
}
]
]
},
"Trigger on Updated Notion Contact": {
"main": [
[
{
"node": "Get All Contacts from Notion",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Overview Seamlessly transfer your Notion contacts to Google Contacts with organized group labels, simplifying your CRM management.
Source: https://n8n.io/workflows/5590/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Sync your Google Contacts with your Notion database.
This enables webhooks for nearly realtime updates (every 5 seconds) from Notion Databases.
This workflow is perfect for productivity-focused teams, remote workers, virtual assistants, and digital knowledge managers who receive documents, images, or notes through Telegram and want to automat
This template takes approved Notion pages and syncs them to a Webflow CMS collection as draft items. It reads pages marked Status = Ready for publish in a specific Notion database/project, merges JSON
Sync Notion Database Pages As Clickup Tasks. Uses notionTrigger, clickUp, clickUpTrigger, notion. Event-driven trigger; 5 nodes.