使用Google Sheets检测电商平台与技术栈
这是一个Lead Generation, Multimodal AI领域的自动化工作流,包含 12 个节点。主要使用 Code, Wait, HttpRequest, GoogleSheets, ManualTrigger 等节点。 使用Google Sheets检测电商平台与技术栈
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
{
"meta": {
"instanceId": "e3b5ec7ce45da1cf94ab74617cac8e11c65b8dc9b695307ba7dd3645ddba444a",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "3c6136c1-c9e2-4645-98d7-736f0ac7606f",
"name": "当点击“执行工作流”时",
"type": "n8n-nodes-base.manualTrigger",
"position": [
144,
112
],
"parameters": {},
"typeVersion": 1
},
{
"id": "c42a5925-6485-477b-9339-e92d611c52cc",
"name": "URL 预处理器",
"type": "n8n-nodes-base.code",
"position": [
592,
16
],
"parameters": {
"jsCode": "// URL Preprocessing - Fix domain formats and add protocols\nreturn $input.all().map(item => {\n let domain = item.json.Domain || \"\";\n \n // Clean up domain\n domain = domain.trim();\n \n // Add https:// if no protocol exists\n if (domain && !domain.startsWith('http://') && !domain.startsWith('https://')) {\n domain = 'https://' + domain;\n }\n \n // Remove trailing slashes\n domain = domain.replace(/\\/$/, '');\n \n return {\n ...item.json,\n Domain: domain,\n OriginalDomain: item.json.Domain\n };\n});"
},
"typeVersion": 2
},
{
"id": "c5938528-e3e1-4ad9-8104-3b0b3e584638",
"name": "获取 sheet1 中的行",
"type": "n8n-nodes-base.googleSheets",
"position": [
368,
16
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Tog_qW5NGJwCgk1t4_IpKC4rMurEx-tXuaapWgVli7w/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Tog_qW5NGJwCgk1t4_IpKC4rMurEx-tXuaapWgVli7w",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Tog_qW5NGJwCgk1t4_IpKC4rMurEx-tXuaapWgVli7w/edit?usp=drivesdk",
"cachedResultName": "Technology Finder with Domain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "sVXuLEot0z5lO0ia",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "f5cf9fac-ee4a-4986-8161-081cb5daaf60",
"name": "批量拆分1",
"type": "n8n-nodes-base.splitInBatches",
"position": [
816,
16
],
"parameters": {
"options": {},
"batchSize": 5
},
"typeVersion": 3
},
{
"id": "704119a2-6e74-421b-ac12-76405e0d1e1a",
"name": "HTTP 请求 1",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"maxTries": 3,
"position": [
1040,
16
],
"parameters": {
"url": "={{$json['Domain']}}",
"options": {
"timeout": 20000,
"redirect": {
"redirect": {
"maxRedirects": 5
}
},
"response": {
"response": {
"responseFormat": "text",
"outputPropertyName": "html"
}
}
}
},
"retryOnFail": true,
"typeVersion": 4.2,
"alwaysOutputData": true
},
{
"id": "66488cb0-b9c0-4d72-8f45-f4e5cc642d3b",
"name": "速率限制等待1",
"type": "n8n-nodes-base.wait",
"position": [
1264,
16
],
"webhookId": "21522894-f3e5-4e51-99d3-7467704901e2",
"parameters": {
"unit": "seconds",
"amount": 2
},
"typeVersion": 1
},
{
"id": "13ea06c1-ae8a-46fc-8d71-4d0d9bc88d89",
"name": "增强技术检测1",
"type": "n8n-nodes-base.code",
"position": [
1488,
16
],
"parameters": {
"jsCode": "//Enhanced Technology Detection with Proper Domain Extraction\n\nconst processItem = (item, index) => {\n try {\n console.log(`=== Processing Item ${index + 1} ===`);\n console.log('Item structure:', JSON.stringify(Object.keys(item), null, 2));\n console.log('Item.json keys:', item.json ? Object.keys(item.json) : 'No json property');\n \n // FIXED DOMAIN EXTRACTION - Multiple approaches for n8n compatibility\n let domain = \"Unknown Domain\";\n \n // Method 1: Direct domain field access (most common in n8n)\n if (item.json?.domain && typeof item.json.domain === 'string') {\n domain = item.json.domain.trim();\n console.log('Found domain in item.json.domain:', domain);\n }\n // Method 2: Capital D Domain field\n else if (item.json?.Domain && typeof item.json.Domain === 'string') {\n domain = item.json.Domain.trim();\n console.log('Found domain in item.json.Domain:', domain);\n }\n // Method 3: URL field that might contain domain\n else if (item.json?.url && typeof item.json.url === 'string') {\n domain = item.json.url.trim();\n console.log('Found domain in item.json.url:', domain);\n }\n // Method 4: Website field\n else if (item.json?.website && typeof item.json.website === 'string') {\n domain = item.json.website.trim();\n console.log('Found domain in item.json.website:', domain);\n }\n // Method 5: Site field\n else if (item.json?.site && typeof item.json.site === 'string') {\n domain = item.json.site.trim();\n console.log('Found domain in item.json.site:', domain);\n }\n // Method 6: Check if domain is passed alongside HTML data\n else if (item.json?.originalUrl && typeof item.json.originalUrl === 'string') {\n domain = item.json.originalUrl.trim();\n console.log('Found domain in item.json.originalUrl:', domain);\n }\n // Method 7: Extract from headers or metadata if available\n else if (item.json?.headers?.host) {\n domain = item.json.headers.host;\n console.log('Found domain in headers.host:', domain);\n }\n // Method 8: Look for any field that might contain domain info\n else {\n // Search through all fields for potential domain\n for (const [key, value] of Object.entries(item.json || {})) {\n if (typeof value === 'string' && \n !key.toLowerCase().includes('html') && \n !key.toLowerCase().includes('body') &&\n !key.toLowerCase().includes('content') &&\n !key.toLowerCase().includes('data') &&\n value.length < 200) {\n \n // Check if it looks like a domain\n if (value.includes('.') && \n !value.includes('<!DOCTYPE') && \n !value.includes('<html') &&\n (value.includes('http') || value.match(/^[a-zA-Z0-9][a-zA-Z0-9-]+\\.[a-zA-Z]{2,}/))) {\n domain = value.trim();\n console.log(`Found potential domain in item.json.${key}:`, domain);\n break;\n }\n }\n }\n }\n \n // Clean domain name (remove protocols, www, paths)\n if (domain && domain !== \"Unknown Domain\") {\n const originalDomain = domain;\n domain = domain\n .replace(/^https?:\\/\\//, '') // Remove protocol\n .replace(/^www\\./, '') // Remove www\n .replace(/\\/$/, '') // Remove trailing slash\n .split('/')[0] // Remove paths\n .split('?')[0] // Remove query params\n .split('#')[0]; // Remove fragments\n \n console.log(`Cleaned domain: ${originalDomain} -> ${domain}`);\n }\n \n // If still no domain found, try to extract from HTML meta tags\n if (domain === \"Unknown Domain\") {\n const html = item.json?.html || item.json?.data || item.json?.body || \"\";\n const ogUrlMatch = html.match(/<meta\\s+property=[\"']og:url[\"']\\s+content=[\"']([^\"']+)[\"']/i);\n const canonicalMatch = html.match(/<link\\s+rel=[\"']canonical[\"']\\s+href=[\"']([^\"']+)[\"']/i);\n \n if (ogUrlMatch && ogUrlMatch[1]) {\n domain = ogUrlMatch[1]\n .replace(/^https?:\\/\\//, '')\n .replace(/^www\\./, '')\n .split('/')[0];\n console.log('Extracted domain from og:url meta tag:', domain);\n } else if (canonicalMatch && canonicalMatch[1]) {\n domain = canonicalMatch[1]\n .replace(/^https?:\\/\\//, '')\n .replace(/^www\\./, '')\n .split('/')[0];\n console.log('Extracted domain from canonical link:', domain);\n }\n }\n \n console.log(`Final domain: ${domain}`);\n \n // Get HTML content for analysis\n const raw = item.json?.html || item.json?.data || item.json?.body || item.json?.content || \"\";\n const html = String(raw).toLowerCase();\n const originalHtml = String(raw);\n \n console.log(`HTML content length: ${raw.length}`);\n \n // Enhanced error checking with specific error types\n if (item.json?.error || !raw || raw.length < 100) {\n let specificError = \"Site unreachable\";\n let errorDetails = \"\";\n \n if (item.json?.error) {\n try {\n const errorStr = typeof item.json.error === 'object' ? \n JSON.stringify(item.json.error) : String(item.json.error);\n errorDetails = errorStr.substring(0, 100);\n \n if (errorStr.includes('ENOTFOUND')) {\n specificError = \"Domain not found (DNS error)\";\n } else if (errorStr.includes('ECONNREFUSED')) {\n specificError = \"Connection refused\";\n } else if (errorStr.includes('ETIMEDOUT') || errorStr.includes('timeout')) {\n specificError = \"Request timeout\";\n } else if (errorStr.includes('certificate') || errorStr.includes('CERT')) {\n specificError = \"SSL certificate error\";\n } else if (errorStr.includes('ECONNRESET')) {\n specificError = \"Connection reset\";\n } else if (errorStr.includes('404')) {\n specificError = \"Page not found (404)\";\n } else if (errorStr.includes('403')) {\n specificError = \"Access forbidden (403)\";\n } else if (errorStr.includes('500')) {\n specificError = \"Server error (500)\";\n }\n } catch (e) {\n errorDetails = \"Error parsing failed\";\n }\n } else if (item.json?.statusCode && item.json.statusCode >= 400) {\n specificError = `HTTP ${item.json.statusCode} error`;\n } else if (!raw) {\n specificError = \"No content received\";\n } else if (raw.length < 100) {\n specificError = \"Minimal content received\";\n }\n \n return {\n Domain: domain,\n Platform: \"Error - \" + specificError,\n Catalog: \"N/A\",\n Cart: \"N/A\",\n Checkout: \"N/A\",\n Wishlist: \"N/A\",\n PWA: \"N/A\",\n Payment_Gateway: \"N/A\",\n Framework: \"N/A\",\n Confidence_Score: \"0%\",\n Last_Checked: new Date().toISOString().split('T')[0],\n Remarks: `Error: ${specificError}${errorDetails ? ' - ' + errorDetails : ''}`\n };\n }\n \n // Initialize detection arrays\n const platforms = [];\n const frameworks = [];\n const paymentGateways = [];\n let cart = \"No\", catalog = \"No\", checkout = \"No\", wishlist = \"No\", pwa = \"No\";\n \n // Safe pattern matching function\n const has = (patterns) => {\n return patterns.some(pattern => {\n try {\n if (pattern instanceof RegExp) {\n return pattern.test(html) || pattern.test(originalHtml);\n }\n return html.includes(String(pattern).toLowerCase());\n } catch (e) {\n console.log(`Pattern matching error: ${e.message}`);\n return false;\n }\n });\n };\n \n // ========== ENHANCED PLATFORM DETECTION ==========\n \n // Magento (Enhanced detection)\n if (has([\n /x-magento-init/i,\n /mage\\/bootstrap/i,\n /static\\/version\\d+\\/frontend/i,\n /var\\s+BASE_URL\\s*=.*mage/i,\n /Mage\\.Cookies/i,\n \"form_key\",\n /magento\\s?enterprise/i,\n \"requirejs/require.js\",\n \"/static/frontend/\",\n \"magento\"\n ])) platforms.push(\"Magento\");\n \n // Shopify (Enhanced detection)\n if (has([\n /cdn\\.shopify\\.com/i,\n /assets\\.shopify\\.com/i,\n /checkout\\.shopify\\.com/i,\n /Shopify\\.theme/i,\n /window\\.ShopifyAnalytics/i,\n \"x-shopify\",\n \"/cart.js\",\n \"/products.json\",\n /generator[\"'][^>]*shopify/i\n ])) platforms.push(\"Shopify\");\n \n // WooCommerce (Enhanced detection)\n if (has([\n /wp-content\\/plugins\\/woocommerce/i,\n /woocommerce_params/i,\n /wc-cart-fragments/i,\n /class=\"[^\"]*woocommerce/i,\n /woocommerce-variation/i,\n \"woocommerce\",\n \"woocommerce-cart\"\n ])) platforms.push(\"WooCommerce\");\n \n // BigCommerce\n if (has([\n \"cdn.bcapp\",\n \"bigcommerce\",\n \"stencil-utils\",\n \"cornerstone\",\n /bigcommerce/i\n ])) platforms.push(\"BigCommerce\");\n \n // Custom E-commerce Detection (for sites like HSP Diesel)\n if (has([\n /add\\s+to\\s+cart/i,\n /shopping\\s+cart/i,\n /product\\s+details/i,\n /buy\\s+now/i,\n /add\\s+to\\s+bag/i,\n /purchase/i,\n /checkout/i,\n /price/i,\n /\\$[0-9,]+/,\n /product\\s+categories/i,\n /featured\\s+products/i,\n /new\\s+products/i,\n /online\\s+store/i,\n /e-?commerce/i\n ])) {\n if (platforms.length === 0) {\n platforms.push(\"Custom E-commerce\");\n }\n }\n \n // Other major platforms\n if (has([\"static.squarespace.com\", \"sqs-layout\", /generator[^>]*squarespace/i])) platforms.push(\"Squarespace\");\n if (has([\"wixstatic.com\", \"wix-code\", \"wixapps.net\", /generator[^>]*wix/i])) platforms.push(\"Wix\");\n if (has([\"webflow.js\", \"data-wf-site\", 'class=\"w-nav', /generator[^>]*webflow/i])) platforms.push(\"Webflow\");\n if (has([\"prestashop\", \"/modules/\", \"var prestashop\", 'class=\"ps-'])) platforms.push(\"PrestaShop\");\n if (has([\"index.php?route=\", \"catalog/view/theme/\", \"opencart\"])) platforms.push(\"OpenCart\");\n \n // Enterprise platforms\n if (has([\"demandware\", \"dwanalytics\", \"dwac\", \"checkout-begin\", \"sites-\", /salesforce.*commerce/i])) platforms.push(\"Salesforce Commerce Cloud\");\n if (has([\"suitecommerce\", \".ssp\", \"touchpoints\", \"scis\", /netsuite/i])) platforms.push(\"NetSuite SuiteCommerce\");\n if (has([/sap[.\\s]hybris/i, /oracle[.\\s]commerce/i, /ibm[.\\s]websphere/i])) platforms.push(\"Enterprise Commerce\");\n \n // Additional smaller platforms\n if (has([\"oscommerce\"])) platforms.push(\"osCommerce\");\n if (has([\"/mm5/\", \"miva merchant\", \"screen=plst\"])) platforms.push(\"Miva Merchant\");\n if (has([\"volusion\", \"/v/vspfiles/\", \"checkout.asp\"])) platforms.push(\"Volusion\");\n if (has([\"ecwid.min.js\", \"app.ecwid.com\", \"data-ecwid\"])) platforms.push(\"Ecwid\");\n if (has([\"nopcommerce\", /generator[^>]*nopcommerce/i])) platforms.push(\"nopCommerce\");\n \n // ========== FRAMEWORK DETECTION ==========\n if (has([\"next.js\", \"_next/\", /Next\\.js/i])) frameworks.push(\"Next.js\");\n if (has([\"nuxt.js\", \"_nuxt/\", /Nuxt\\.js/i])) frameworks.push(\"Nuxt.js\");\n if (has([/react/i, \"react.js\", \"react.min.js\"])) frameworks.push(\"React\");\n if (has([/vue\\.js/i, \"vue.min.js\"])) frameworks.push(\"Vue.js\");\n if (has([/angular/i, \"angular.js\"])) frameworks.push(\"Angular\");\n if (has([\"gatsby\", /gatsby/i])) frameworks.push(\"Gatsby\");\n if (has([\"wordpress\", \"wp-content\", \"wp-includes\"])) frameworks.push(\"WordPress\");\n \n // ========== PAYMENT GATEWAY DETECTION ==========\n if (has([\"stripe.js\", /stripe/i, \"js.stripe.com\"])) paymentGateways.push(\"Stripe\");\n if (has([\"paypal.js\", /paypal/i, \"paypal.com\"])) paymentGateways.push(\"PayPal\");\n if (has([\"square.js\", /square/i])) paymentGateways.push(\"Square\");\n if (has([\"klarna\", /klarna/i])) paymentGateways.push(\"Klarna\");\n if (has([\"razorpay\", /razorpay/i])) paymentGateways.push(\"Razorpay\");\n if (has([\"braintree\", /braintree/i])) paymentGateways.push(\"Braintree\");\n \n // ========== ENHANCED FEATURE DETECTION ==========\n \n // Cart Detection (Enhanced)\n if (has([\n /add[\\s\\-_]?to[\\s\\-_]?(cart|bag|basket)/i,\n /shopping[\\s\\-_]?cart/i,\n /mini[\\s\\-_]?cart/i,\n /cart[\\s\\-_]?total/i,\n /quantity[\\s\\-_]?selector/i,\n /buy[\\s\\-]?now/i,\n /order[\\s\\-]?now/i,\n /add[\\s\\-]?to[\\s\\-]?bag/i,\n /purchase/i,\n /cart\\.js/i,\n /shopping.*bag/i\n ])) cart = \"Yes\";\n \n // Catalog Detection (Enhanced)\n if (has([\n /catalog(ue)?/i,\n /product[\\s\\-_]?catalog/i,\n /category/i,\n /categories/i,\n /browse[\\s\\-_]?products/i,\n /product[\\s\\-_]?filter/i,\n /search[\\s\\-_]?results/i,\n /featured[\\s\\-_]?products/i,\n /new[\\s\\-_]?products/i,\n /top[\\s\\-_]?products/i,\n /popular[\\s\\-_]?products/i,\n /product[\\s\\-_]?bundles/i\n ])) catalog = \"Yes\";\n \n // Checkout Detection\n if (has([\n /checkout/i,\n /payment/i,\n /billing[\\s\\-_]?address/i,\n /shipping[\\s\\-_]?address/i,\n /place[\\s\\-_]?order/i,\n /complete[\\s\\-_]?purchase/i,\n /secure[\\s\\-_]?checkout/i,\n /proceed[\\s\\-_]?to[\\s\\-_]?checkout/i\n ])) checkout = \"Yes\";\n \n // Wishlist Detection\n if (has([\n /wish[\\s\\-_]?list/i,\n /save[\\s\\-_]?for[\\s\\-_]?later/i,\n /favorite/i,\n /add[\\s\\-_]?to[\\s\\-_]?wishlist/i\n ])) wishlist = \"Yes\";\n \n // PWA Detection\n if (has([\n \"service-worker\",\n \"manifest.json\",\n \"workbox\",\n /pwa/i,\n \"sw.js\"\n ])) pwa = \"Yes\";\n \n // ========== CONFIDENCE SCORING ==========\n let confidenceScore = 0;\n if (platforms.length > 0) confidenceScore += 40;\n if (cart === \"Yes\") confidenceScore += 20;\n if (checkout === \"Yes\") confidenceScore += 25;\n if (catalog === \"Yes\") confidenceScore += 10;\n if (paymentGateways.length > 0) confidenceScore += 5;\n \n confidenceScore = Math.min(confidenceScore, 100);\n \n // ========== REMARKS GENERATION ==========\n let remarks = \"Basic Website\";\n if (platforms.length || cart === \"Yes\" || catalog === \"Yes\" || checkout === \"Yes\") {\n remarks = \"E-commerce Features Detected\";\n } else if (frameworks.length) {\n remarks = \"Website Framework Detected\";\n } else if (html.length > 1000) {\n remarks = \"Website Active - No E-commerce Detected\";\n }\n \n console.log(`SUCCESS: ${domain} - ${platforms.join(', ')} - ${confidenceScore}%`);\n \n // Final output\n return {\n Domain: domain,\n Platform: platforms.length ? platforms.slice(0, 2).join(\"; \") : \"Not Detected\",\n Catalog: catalog,\n Cart: cart,\n Checkout: checkout,\n Wishlist: wishlist,\n PWA: pwa,\n Payment_Gateway: paymentGateways.length ? paymentGateways.slice(0, 2).join(\"; \") : \"Not Detected\",\n Framework: frameworks.length ? frameworks.slice(0, 2).join(\"; \") : \"Not Detected\",\n Confidence_Score: `${confidenceScore}%`,\n Last_Checked: new Date().toISOString().split('T')[0],\n Remarks: remarks\n };\n \n } catch (error) {\n console.log(`CRITICAL ERROR processing item ${index}:`, error.message);\n console.log('Error stack:', error.stack);\n \n // Try to at least get the domain even in error cases\n let errorDomain = \"Processing Error\";\n try {\n if (item.json?.domain) errorDomain = item.json.domain;\n else if (item.json?.Domain) errorDomain = item.json.Domain;\n else if (item.json?.url) errorDomain = item.json.url;\n else if (item.json?.website) errorDomain = item.json.website;\n } catch (e) {\n // Keep default error domain\n }\n \n return {\n Domain: errorDomain,\n Platform: \"Processing Error\",\n Catalog: \"N/A\",\n Cart: \"N/A\",\n Checkout: \"N/A\",\n Wishlist: \"N/A\",\n PWA: \"N/A\",\n Payment_Gateway: \"N/A\",\n Framework: \"N/A\",\n Confidence_Score: \"0%\",\n Last_Checked: new Date().toISOString().split('T')[0],\n Remarks: `Critical processing error: ${error.message}`\n };\n }\n};\n\n// Process all items with error tracking\ntry {\n const results = $input.all().map(processItem);\n console.log(`Successfully processed ${results.length} domains`);\n \n // Log summary of domains processed\n console.log('\\n=== PROCESSING SUMMARY ===');\n results.forEach((result, idx) => {\n console.log(`${idx + 1}. ${result.Domain} - Platform: ${result.Platform} - Score: ${result.Confidence_Score}`);\n });\n \n return results;\n} catch (globalError) {\n console.log('GLOBAL ERROR:', globalError.message);\n // Return minimal error response\n return [{\n Domain: \"Global Error\",\n Platform: \"Processing Error\",\n Catalog: \"N/A\",\n Cart: \"N/A\",\n Checkout: \"N/A\",\n Wishlist: \"N/A\",\n PWA: \"N/A\",\n Payment_Gateway: \"N/A\",\n Framework: \"N/A\",\n Confidence_Score: \"0%\",\n Last_Checked: new Date().toISOString().split('T')[0],\n Remarks: `Global processing error: ${globalError.message}`\n }];\n}"
},
"typeVersion": 2
},
{
"id": "b7982b69-1687-4fbc-8d72-25ab8ce75252",
"name": "更新增强结果1",
"type": "n8n-nodes-base.googleSheets",
"position": [
1712,
16
],
"parameters": {
"columns": {
"value": {
"PWA": "={{ $json.PWA }}",
"Cart": "={{ $json.Cart }}",
"Domain": "={{ $json.Domain }}",
"Catalog": "={{ $json.Catalog }}",
"Remarks": "={{ $json.Remarks }}",
"Checkout": "={{ $json.Checkout }}",
"Platform": "={{ $json.Platform }}",
"Wishlist": "={{ $json.Wishlist }}",
"Framework": "={{ $json.Framework }}",
"row_number": 0,
"Last Checked": "={{ $json.Last_Checked }}",
"Payment Gateway": "={{ $json.Payment_Gateway }}",
"Confidence Score": "={{ $json.Confidence_Score }}"
},
"schema": [
{
"id": "Domain",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Domain",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Platform",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Platform",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Cart",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Cart",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Catalog",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Catalog",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Checkout",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Checkout",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Wishlist",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Wishlist",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "PWA",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "PWA",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Payment Gateway",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Payment Gateway",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Framework",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Framework",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Confidence Score",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Confidence Score",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Checked",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Last Checked",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Remarks",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Remarks",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Domain"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Tog_qW5NGJwCgk1t4_IpKC4rMurEx-tXuaapWgVli7w/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Tog_qW5NGJwCgk1t4_IpKC4rMurEx-tXuaapWgVli7w",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Tog_qW5NGJwCgk1t4_IpKC4rMurEx-tXuaapWgVli7w/edit?usp=drivesdk",
"cachedResultName": "Technology Finder with Domain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "sVXuLEot0z5lO0ia",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "2cb151c6-9e97-4542-92da-255eec3788d8",
"name": "计划触发器",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
144,
-80
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "7d45c141-4fed-457f-adb7-132dbd7ad8ca",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
96,
-240
],
"parameters": {
"content": "从计划触发器安排 Cron 任务"
},
"typeVersion": 1
},
{
"id": "02895d34-8fc2-417e-8b45-f9d20b8defca",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
208
],
"parameters": {
"content": "## Google Sheet"
},
"typeVersion": 1
},
{
"id": "a7f94b2e-d79d-42f5-bc53-3194db1c8d9c",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1680,
192
],
"parameters": {
"content": "## Google 更新表格"
},
"typeVersion": 1
}
],
"pinData": {
"When clicking 'Execute workflow'": [
{}
]
},
"connections": {
"HTTP Request1": {
"main": [
[
{
"node": "Rate Limiting Wait1",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get row(s) in sheet1",
"type": "main",
"index": 0
}
]
]
},
"URL Preprocessor": {
"main": [
[
{
"node": "Split In Batches1",
"type": "main",
"index": 0
}
]
]
},
"Split In Batches1": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
],
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
]
]
},
"Rate Limiting Wait1": {
"main": [
[
{
"node": "Enhanced Technology Detection1",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet1": {
"main": [
[
{
"node": "URL Preprocessor",
"type": "main",
"index": 0
}
]
]
},
"Enhanced Technology Detection1": {
"main": [
[
{
"node": "Update Enhanced Results1",
"type": "main",
"index": 0
}
]
]
},
"When clicking 'Execute workflow'": {
"main": [
[
{
"node": "Get row(s) in sheet1",
"type": "main",
"index": 0
}
]
]
}
}
}如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
中级 - 潜在客户开发, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
Ajay Yadav
@erplinkerERP Linker is a boutique integration consultancy specializing in end‑to‑end ERP, e‑commerce, and workflow automation, helping B2B organizations eliminate manual processes and scale with confidence. With deep expertise across NetSuite, Global Shop Solutions, MRPERP, and custom ERPs, ERP Linker connects storefronts like Shopify, BigCommerce, and WooCommerce with finance, fulfillment, and approvals to create a single source of operational truth.
分享此工作流