[System]
Tu es un expert n8n. Crée des workflows JSON complets et fonctionnels.
Utilise <thinking> pour expliquer ton raisonnement avant de générer le JSON.
Structure ton thinking: analyse du besoin, choix du trigger, architecture, flux de données, points d'attention.

[User] Génère un workflow n8n: Generate & Send Quotation PDFs from Pipedrive to DottedSign for E-Signature

[Assistant]
<thinking>
**Analyse du besoin**: 📌 Overview

Description:

This powerful workflow automates your sales quotation process by connecting Pipedrive with DottedSign. When a deal is moved to a specific stage in Pipedrive, this template au...

**Choix du trigger**: Sélection basée sur le cas d'usage décrit.

**Architecture**: 0 nodes utilisant nodes natifs.
Structure: flux standard.

**Flux de données**: Connexions définies entre les nodes pour assurer le passage des données.

**Points d'attention**: Vérifier les credentials, tester chaque node individuellement.
</thinking>

{"id":"8LJ5mlndFypZh1VS","meta":{"instanceId":"cf9804b12ee62314911ec55daa0c998a73f201da1917bd31262722d206bf0f27","templateCredsSetupCompleted":true},"name":"QuotationAutomation template","tags":[],"nodes":[{"id":"2e87b077-c9bf-49c9-9d03-955bdc6615c3","name":"Pipedrive Trigger","type":"n8n-nodes-base.pipedriveTrigger","position":[-16,176],"webhookId":"988adb20-acfa-4668-858e-f89825b8bf6a","parameters":{"action":"change","entity":"deal"},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1.1},{"id":"a0076d48-fc1b-4b1c-937e-9dacb05fa9a9","name":"Get a deal","type":"n8n-nodes-base.pipedrive","position":[1104,-112],"parameters":{"dealId":"={{ $json.data.id }}","operation":"get"},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1},{"id":"351d5e24-33ba-4d98-82c4-e76c8ea7edce","name":"editFlag=True","type":"n8n-nodes-base.filter","position":[880,-304],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"01e341f6-05e7-4521-8b8e-dcba0a5e818c","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.edit_flag }}","rightValue":""}]}},"typeVersion":2.2},{"id":"b9f38e9c-428e-4ea2-a503-c927419bcf2d","name":"Get many deal products","type":"n8n-nodes-base.pipedrive","position":[880,80],"parameters":{"dealId":"={{ $json.meta.entity_id }}","resource":"dealProduct","operation":"getAll","returnAll":true},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1},{"id":"609f3763-2ce6-479c-b35d-a67da0edda07","name":"setProductRows","type":"n8n-nodes-base.code","position":[2000,176],"parameters":{"jsCode":"// n8n Code Node (or similar Javascript environment)\n\nconst items = $input.first().json.deal_products;\nlet htmlRows = '';\n\nfor (const item of items) {\n  // 修正後的版本：100% 匹配您的原版範本的結構和 CSS Class\n  let singleRowHtml = `\n
\n        \n
\n                ${item.name}\n
\n        	\n        \n
\n                ${item.quantity}\n
\n        	\n        \n
\n                ${item.currency} ${parseFloat(item.item_price).toFixed(2)}\n
\n        	\n        \n
\n                ${item.discount}%\n
\n        	\n        \n
\n                ${item.currency} ${parseFloat(item.sum).toFixed(2)}\n
\n        	\n
\n  `;\n  // 清理換行和多餘空格，確保 HTML 乾淨\n  htmlRows += singleRowHtml.replace(/\\n\\s*/g, '');\n}\n\nreturn { table_rows_html: htmlRows };"},"typeVersion":2},{"id":"8667563a-03d9-4d64-aff0-8d76deb7c853","name":"Get a person","type":"n8n-nodes-base.pipedrive","position":[1104,272],"parameters":{"personId":"={{ $json.data.person_id }}","resource":"person","operation":"get"},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1},{"id":"ee372227-55b8-40cc-800a-d9e5aa1d3d37","name":"field_mappings","type":"n8n-nodes-base.set","position":[1328,-304],"parameters":{"options":{},"assignments":{"assignments":[{"id":"6b1137c7-df7e-41be-8555-9860db142e74","name":"field_mappings","type":"object","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"0cd3669f-1e1f-4d8e-a9a2-35b39f61d132","name":"deal_details","type":"n8n-nodes-base.set","position":[1328,-112],"parameters":{"options":{},"assignments":{"assignments":[{"id":"72ee9f3f-178c-457b-981a-09ae60fca3ea","name":"deal_details","type":"object","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"8b6c48fa-451e-45d6-b86f-4a15782d60af","name":"person_details","type":"n8n-nodes-base.set","position":[1328,272],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b779769c-f9b4-48a1-8bfe-7827baf990b1","name":"person_details","type":"object","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"1c0268a7-490b-4b3f-a7db-458bace5c6d1","name":"deal_products","type":"n8n-nodes-base.set","position":[1328,80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"13d41759-702c-4639-a184-615096f89a02","name":"deal_products","type":"object","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"e37cb8c9-fc54-4cad-973c-921fd1f7392c","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[1104,-304],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"74ff239d-aff4-462f-96b6-57ebf65df4c4","name":"Aggregate1","type":"n8n-nodes-base.aggregate","position":[1104,80],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"9465410d-f738-4d0d-bbf5-7132a440c21e","name":"Get an organization","type":"n8n-nodes-base.pipedrive","position":[1104,464],"parameters":{"resource":"organization","operation":"get","organizationId":"={{ $json.data.org_id }}"},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1},{"id":"a11a4440-9c19-4d22-bdc9-09cc26a7ab74","name":"org_details","type":"n8n-nodes-base.set","position":[1328,464],"parameters":{"options":{},"assignments":{"assignments":[{"id":"baad2fc7-b3e8-45af-a45f-1bebf88dbf79","name":"org_details","type":"object","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"14ba18cc-36cd-41f8-8c2d-42c263c7364a","name":"Convert to HTML","type":"n8n-nodes-base.convertToFile","position":[2448,176],"parameters":{"options":{"encoding":"utf8","fileName":"index.html","mimeType":"text/html","dataIsBase64":false},"operation":"toBinary","sourceProperty":"html"},"typeVersion":1},{"id":"b1005793-6c53-429c-afac-c957994391f5","name":"Create a file","type":"n8n-nodes-base.pipedrive","position":[3120,272],"parameters":{"resource":"file","additionalFields":{"deal_id":"={{ $('Clean & Map Data').item.json.id }}","activity_id":"={{ $('Create an activity').item.json.id }}"},"binaryPropertyName":"=data"},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1},{"id":"25e7bbe7-3bd6-4968-aff5-92e1a2c48876","name":"Create an activity","type":"n8n-nodes-base.pipedrive","position":[1104,656],"parameters":{"type":"Quoatation","subject":"=Quotation/ {{ $json.data.id }}/{{ $json.data.update_time.toDateTime().format('yyyyMMdd') }}","resource":"activity","additionalFields":{"deal_id":"={{ $json.data.id }}"}},"credentials":{"pipedriveApi":{"id":"M0Osgaz0uW0e047E","name":"Pipedrive account Sandbox"}},"typeVersion":1},{"id":"276e0728-344b-4ef3-bf31-16b6aeacc898","name":"activity_details","type":"n8n-nodes-base.set","position":[1328,656],"parameters":{"options":{},"assignments":{"assignments":[{"id":"baad2fc7-b3e8-45af-a45f-1bebf88dbf79","name":"activity_details","type":"object","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"ab6a37ee-a249-46ea-b335-3b9c20bcc8ab","name":"DottedSign-CreateTask","type":"n8n-nodes-base.httpRequest","position":[3792,176],"parameters":{"url":"https://api.sandbox.dottedsign.com/v1/sign_tasks","method":"POST","options":{},"jsonBody":"={\n    \"has_order\": false,\n    \"start\": true,\n    \"stages\": [\n        {\n            \"field_settings\": [\n                {\n                    \"field_type\": \"signature\",\n                    \"coord\": [92.0, 237.0, 353.0, 274.0],\n                    \"options\": { \"placeholder\": \"signhere\" },\n                    \"page\": 1\n                }\n            ],\n            \"stage_setting\": {\n                \"informable\": true,\n                \"reviewed_skip_confirm\": true\n            },\n            \"name\": \"{{ $('Clean & Map Data').item.json.person_details.name }}\",\n            \"email\": \"{{ $('Clean & Map Data').item.json.person_details.email[0].value }}\",\n            \"stage_type\": \"sign\"\n        }\n    ],\n    \"task_setting\": {\n        \"cc_infos\": [\n            {\n                \"email\": \"{{ $('Clean & Map Data').item.json.person_details.owner_id.email }}\",\n                \"name\": \"{{ $('Clean & Map Data').item.json.person_details.owner_id.name }}\" }],\n        \"receiver_lang\": \"en\",\n        \"owner_informable\": true\n    },\n    \"base64_file\": \"{{ $json.data }}\",\n    \"file_name\": \"{{ $('Clean & Map Data').item.json.title.replace(/[\\\"*:<>\\?\\/\\\\|~#%&{}]/g, '_') }}.pdf\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"Authorization","value":"=Bearer {{ $json.access_token }}"},{"name":"content-type","value":"application/json"}]}},"typeVersion":4.2},{"id":"60cc6b34-70f4-4900-a7cb-0a16ee987344","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[3344,80],"parameters":{"options":{},"operation":"binaryToPropery"},"typeVersion":1,"alwaysOutputData":true},{"id":"de55a7d7-c151-4270-b356-ff6600ced25a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1200,-560],"parameters":{"width":1056,"height":752,"content":"## 📌 Overview\n**Title:** `Automate Quotation Generation from Pipedrive to DottedSign`\n**Description:**\nThis powerful workflow automates your sales quotation process by connecting Pipedrive with DottedSign. When a deal is moved to a specific stage in Pipedrive, this template automatically generates a professional PDF quotation, uploads it back to the deal, and sends it out for e-signature via DottedSign service, saving your sales team valuable time and eliminating manual work.\n## What it does\nWhen a Pipedrive deal moves to a designated stage (e.g., \"Quotation Stage\"), this workflow triggers and performs the following actions:\n1.  **Gathers Data:** It collects all relevant information, including deal details, client contacts, organization info, and associated products from Pipedrive.\n2.  **Generates PDF Quote:** It populates a customizable HTML template with the collected data and uses a PDF generation service (Gotenberg) to create a polished PDF document.\n3.  **Uploads to Pipedrive:** The generated PDF quote is automatically uploaded to the \"Files\" section of the corresponding Pipedrive deal for record-keeping.\n4.  **Sends for E-Signature:** It creates a new signing task in DottedSign, sending the quotation to the client for their electronic signature.\n## Requirements\n-   A Pipedrive account with admin permissions.\n-   A DottedSign developer account to obtain API credentials.\n-   A self-hosted instance of [Gotenberg](https://gotenberg.dev/docs/getting-started/installation) for HTML to PDF conversion.\n## How to set up\n1.  **Pipedrive Trigger Stage:** In the `If` node, change the stage ID `7` to the ID of the pipeline stage you want to use as the trigger.\n2.  **PDF Conversion Service:** In the `Gotenberg to PDF` (HTTP Request) node, replace the placeholder URL with the endpoint of your running Gotenberg instance.\n3.  **DottedSign Credentials:** In the `Get DottedSign Access Token` node, enter your `client_id` and `client_secret` in the request body.\n4.  **DottedSign Signature Field:** In the `Create DottedSign Task` node, you **must** adjust the `page` and `coord` values under `field_settings` to match the desired signature location on your PDF template.\n## How to customize the workflow\n-   **Quotation Template:** Edit the `Generate Quotation HTML` node to modify the quote's appearance, text, company logo, and terms. The `{{ ... }}` expressions are placeholders that are filled with Pipedrive data.\n-   **Trigger:** Replace the Pipedrive Trigger with another trigger, such as a webhook or a form submission, to adapt the workflow to different needs.\n-   **Notifications:** Add a Slack or email node at the end of the workflow to notify the sales team once the quotation has been sent."},"typeVersion":1},{"id":"cc8f8665-c85f-4e05-bdba-fcd560a7aba0","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-48,-560],"parameters":{"color":3,"width":1504,"height":1504,"content":"## **STEP 1: Trigger & Data Collection**\n\n*   **Pipedrive Trigger**: Watches for any change in a Pipedrive deal.\n*   **If**: Checks if the deal was moved to Specific Stage . The workflow will start execute.\n*   **Data Collection**: If the condition is true, it fetches all necessary data: Deal details, Person, Organization, Products, and Custom Field definitions (Optional)."},"typeVersion":1},{"id":"ffe36349-2631-4001-94cb-33068ef48be8","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1520,-144],"parameters":{"width":640,"height":752,"content":"## **STEP 2: Data Processing** \n\n*   **Set Nodes**: Rename different data streams for clarity (e.g., `deal_details`, `person_details`).\n*   **Merge**: Combines all the separate data into a single object.\n*   **Code (Main)** It cleans up the data and converts technical customfieldIDs mapping with string text."},"typeVersion":1},{"id":"bfb48e6f-0b00-438b-a5e1-ec79d703508f","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[2176,-32],"parameters":{"color":4,"width":848,"height":464,"content":"## **STEP 3: PDF Generation**\n\n*   **setProductRows**: This Code node dynamically creates the HTML table rows for the product list.\n*   **HTML**: This is the main template. It takes the processed data and fills it into the HTML layout.\n*   **Convert to HTML -> convert to PDF**: Turns the final HTML into a binary file, then sends it to the Gotenberg service to create the PDF."},"typeVersion":1},{"id":"02b99292-f1df-4343-a2d6-e29b7d96b147","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[3072,-128],"parameters":{"width":944,"height":688,"content":"## **STEP 4: Final Actions**\n\n*   **Create a file**: Uploads the newly created PDF to the Pipedrive deal's \"Files\" section.\n*   **Extract from File**: Converts the PDF into Base64 format, which is required by the DottedSign API.\n*   **DottedSign-GetAccessToken**: Gets a temporary API token from DottedSign.\n*   **DottedSign-CreateTask**: Sends the PDF and signer info to DottedSign to start the e-signature process."},"typeVersion":1},{"id":"891f3d99-0b53-468c-a95e-ea84fa420ef9","name":"MergeAllData","type":"n8n-nodes-base.merge","position":[1552,112],"parameters":{"mode":"combine","options":{"includeUnpaired":true},"combineBy":"combineByPosition","numberInputs":6},"typeVersion":3.2},{"id":"6a653173-a497-4fa0-88ae-ffdee6cb14ed","name":"MergeForDS","type":"n8n-nodes-base.merge","position":[3568,176],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3.2,"alwaysOutputData":true},{"id":"647168e9-bd89-4cfb-b314-2375f9123d18","name":"Clean & Map Data","type":"n8n-nodes-base.code","position":[1776,176],"parameters":{"jsCode":"\nconst inputData = $input.item.json;\n\n\nconst dealData = inputData.deal_details;\nconst personData = inputData.person_details;\nconst orgData = inputData.org_details;\n// 從聚合後的物件中提取陣列\nconst dealProducts = inputData.deal_products?.data || [];\nconst fieldMappingsArray = inputData.field_mappings?.data || [];\n\n\nif (!dealData) {\n    throw new Error(\"Deal data (deal_details) is missing from the input. Check the Merge node and its inputs.\");\n}\n\n\nconst fieldMapping = {};\nfor (const field of fieldMappingsArray) {\n    if (field.key && field.name) {\n        fieldMapping[field.key] = field.name;\n\n        if ((field.field_type === 'enum' || field.field_type === 'set') && field.options) {\n            fieldMapping[field.key + '_options'] = field.options;\n        }\n    }\n}\n\n\nconst cleanedDeal = {};\n\n\nfor (const key in dealData) {\n    if (dealData.hasOwnProperty(key)) {\n        let value = dealData[key];\n\n\n        if (fieldMapping[key]) {\n            const fieldName = fieldMapping[key];\n            const options = fieldMapping[key + '_options'];\n\n\n            if (options && (typeof value === 'string' || typeof value === 'number')) {\n                const valueArray = String(value).split(',').map(s => s.trim());\n                const labels = valueArray.map(val => {\n                    const option = options.find(opt => String(opt.id) === val);\n                    return option ? option.label : val; \n                });\n                cleanedDeal[fieldName] = (valueArray.length > 1) ? labels : labels[0];\n            } else if (value && typeof value === 'object' && value !== null && value.name !== undefined) {\n                cleanedDeal[fieldName] = value.name;\n            } else if (value && typeof value === 'object' && value !== null && value.value !== undefined) {\n                cleanedDeal[fieldName] = value.value;\n            } else {\n                cleanedDeal[fieldName] = value;\n            }\n\n        } else if (key.endsWith('_id') && typeof value === 'object' && value !== null && value.name !== undefined) {\n            cleanedDeal[key.replace('_id', '_name')] = value.name;\n\n        } else {\n            cleanedDeal[key] = value;\n        }\n    }\n}\n\n\nif (personData) {\n    cleanedDeal.person_details = personData;\n}\nif (orgData) {\n    cleanedDeal.org_details = orgData;\n}\nif (dealProducts.length > 0) {\n    cleanedDeal.deal_products = dealProducts;\n}\n\n\nreturn [{\n    json: cleanedDeal\n}];"},"typeVersion":2},{"id":"c7724bac-4f45-4d31-96ab-78e09e9604e5","name":"Generate Quote HTML","type":"n8n-nodes-base.html","position":[2224,176],"parameters":{"html":"<meta content=\"text/html; charset=UTF-8\" http-equiv=\"content-type\">
YOUR COMPANY NAME.

YOUR COMPANY ADDRESS,

YOUR COMPANY ADDRESS

Phone: YOUR COMPANY PHONE

YOUR COMPANY WEBSITE

Contact Person： n8n-user_name:{{ $('Clean & Map Data').item.json.user_name }}

QUOTATION

QUO-NO # n8n-deal_id:{{ $('Clean & Map Data').item.json.id }}

DATE： n8n-date:{{ $('Clean & Map Data').item.json.update_time.toDateTime().format('yyyy-MM-dd') }}

Quote To：_____n8n-org_name:{{ $('Clean & Map Data').item.json.org_name }}______(“You”or “Your”)

Description

Quantity

Unit Price

Discount

Amount

{{ $('setProductRows').item.json.table_rows_html }}

Sub Total

{{ $('Clean & Map Data').item.json.currency }} {{ $('Clean & Map Data').item.json.value }}

Shipping

{{ $('Clean & Map Data').item.json.currency }}

Tax (5%)

{{ $('Clean & Map Data').item.json.currency }}

Total

{{ $('Clean & Map Data').item.json.currency }} {{ $('Clean & Map Data').item.json.value }}

Note:

This quotation takes effect when You have completed the signing and return the electronic files (including scanned files or PDFs) of the quotation by facsimile or electronic transmission or other means to Kdan Mobile Software Ltd (“we”,”us”, or”our”). Upon the effective date of this quotation, if You would like to postpone the activation date of the service license(s) or adjust the number of activated licenses within the licensed quantity due to Your internal considerations or other reasons not attributable to us, You shall notify us in writing or by email and obtain our consent. However, You understand and agree that under such circumstances, the Licensed Period stipulated in this Quotation shall remain unaffected. If there are any licenses that remain unactivated upon the expiration of the Licensed Period, You acknowledge and agree that we shall no longer activate such remaining licenses and shall not provide any refund or extension. You shall not assert any claim against us in this regard. The foregoing shall not affect Your payment obligations under this Quotation, and You shall still make full payment in accordance with the relevant provisions herein.

If neither party raises any objections 30 days prior to the expiration of DottedSign licensing period, this quotation will be automatically renewed for one year under the same terms and conditions."

When You use DottedSign, You agree to comply with the “Terms of Use” (https://www.dottedsign.com/terms_of_service) in our official website.

Unless otherwise specified in this quotation, you have the right to terminate the quotation without any reason within the period, which starting fromMM/DD/YYYY to 30 days after the date of account activation by us (the “Termination Period”). Once You terminate the quotation within the Termination Period, You should provide notice in writing or electronically to us and You must pay equal to 20% of the total License Fee to us(the “Termination Fee”); however, if You terminate the quotation before the date of account activation, the Termination Fee would be deducted to equal to 15% of the total License Fee. After the Termination Period, You are not entitled to terminate the quotation.

The quotation terminate from the date we receive Your termination notice (the” termination day”). We have the right to deduct the Termination fee, the subscription fee incurred by You in accessing our service before the termination date(Less than one day, shall be calculate as one day), and any other damages from the refund. All refunds are not eligible for interest.

Payment instructions: we must received full amount of the payment, You agree to pay all charges incurred by the transaction.

Within thirty(30) days after You sign and return the quotation to us, You must pay the total amount to the payment link designated by us by credit card. Under the condition that "to pay the service fee within a specified period after the issuance of the invoice," if the payment is not made within the agreed period, we reserves the right to calculate late payment interest at an annual rate of 5%, temporarily suspend the provision of services, and, if deemed necessary, unilaterally terminate this quotation. Under the other condition that "to prepay the service fee before the issuance of the invoice," if the payment is not made within the agreed period, we reserves the right to withhold the account activation and unilaterally terminate this quotation.

You hereby grant to us as well as the subsidiaries and affiliates of us( hereinafter collectively referred to as “Kdan Group Companies”) a royalty-free and perpetual license to use Your corporation mark (including trademarks, trade names, and logos ) in marketing, sales, and public relations material to identify You as a Kdan Group Companies’ partner.

Both parties agree that this quotation shall be presented in electronic records. And this quotation could be signed using an electronic signature.

In the event of any conflict or inconsistency between the terms and conditions of this quotation and the terms of contracts agreed by both parties someday, the provisions of those contracts shall prevail.

During the performance of the quotation, both parties agree to enter into written supplementary agreement for any matter not covered by this quotation.

If You do not sign and return the quotation within one month after we send it to You, the quotation will lapse automatically.

This quotation shall be construed in accordance with the laws of the Republic of China (Taiwan). The Parties agree that the conditions set forth hereunder shall be performed in the utmost spirit of goodwill and good faith. In the event of a dispute, the Parties agree that the Taiwan Taipei District Court shall be the court of first instance.

We are committed to protecting the security of Your personal data and information. Any personal data provided by You, as well as any information obtained through the use of our website or services, is managed and protected in accordance with our Privacy Policy and Security Policy. You acknowledge and agree that any information You obtain about others through the use of our website or services will also be subject to the regulations of our Privacy Policy and Security Policy. For more details, please refer to the following link:

Privacy Policy:https://dottedsign.com/privacy_policy

Security Policy:https://dottedsign.com/security

Both parties shall conduct their business activities based on the principles of integrity. Both parties agree that during the process of signing and fulfilling the purpose of this quotation, neither party nor its directors, managers, employees, agents, or persons with substantial control (collectively referred to as "Personnel") shall directly or indirectly offer, promise, give, request, or accept any improper money, gifts, loans, commissions, positions, services, advantages, sponsorships, rewards, bribes, travel fees, hospitality, or any form of benefit. If either party is aware that any Personnel may violate the principles of integrity, they shall immediately notify the other party in writing or by email, provide relevant evidence, and cooperate with the investigation. If either party or its Personnel violates this clause, the other party may unconditionally terminate this quotation at any time and request compensation for damages. The amount of damages may be deducted from any amounts payable under this quotation. If the quotation is terminated under this clause, the provisions of Clause 5 shall not apply.

The service license(s) granted under this quotation shall be effective from【DD/MM/YYYY】to【DD/MM/YYYY】(“Licensed Period”). By singing below, You acknowledge that You have read and agree to be bound by these terms and conditions.

                  DATE:________/_________/_________

Authorized Signatory: n8n-person_name:{{ $('Clean & Map Data').item.json.person_details.name }}

Title: n8n-job title:{{ $('Clean & Map Data').item.json.person_details?.job_title || '' }}

GUI No. [          ]

Address: n8n-address:{{ $('Clean & Map Data').item.json.org_details.address || '' }}

Contact Person: n8n-person_name:{{ $('Clean & Map Data').item.json.person_details.name || '' }}

Tel: n8n-tel:{{ $('Clean & Map Data').item.json.person_details.phone[0].value || ''}}

"},"typeVersion":1.2},{"id":"1c66eeae-b758-4500-8324-d2a6f15f1003","name":"Gotenberg to PDF","type":"n8n-nodes-base.httpRequest","position":[2672,176],"parameters":{"url":"http://gotenberggotenberg.yourhost/forms/chromium/convert/html","method":"POST","options":{"response":{"response":{"responseFormat":"file"}}},"sendBody":true,"contentType":"multipart-form-data","bodyParameters":{"parameters":[{"name":"files","parameterType":"formBinaryData","inputDataFieldName":"data"}]}},"typeVersion":4.2},{"id":"0c56eade-f38e-48f8-87b7-e4f8386803df","name":"Rename PDF","type":"n8n-nodes-base.code","position":[2896,176],"parameters":{"jsCode":"$input.item.binary.data.fileName = 'result.pdf'\n return $input.item;"},"typeVersion":2},{"id":"b7da5d6e-6a44-4b4c-b9e2-bb3aeed78de9","name":"Get Pipedrive Custom Fields","type":"n8n-nodes-base.httpRequest","position":[432,-304],"parameters":{"url":"https://kdanmobile.pipedrive.com/api/v1/dealFields","options":{},"jsonHeaders":"{\n  \"Content-Type\": \"application/json\"\n}","sendHeaders":true,"authentication":"genericCredentialType","specifyHeaders":"json","genericAuthType":"httpQueryAuth"},"credentials":{"httpQueryAuth":{"id":"fQptBLiBdOmeIEzd","name":"Pipedrive API token"}},"typeVersion":4.2},{"id":"9fc8335e-a975-4326-a416-345669ca90d5","name":"Split Out Custom Fields","type":"n8n-nodes-base.splitOut","position":[656,-304],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"e1e9f24e-9093-45ce-a928-bbd73d43ad82","name":"If Stage is 'Quotation'","type":"n8n-nodes-base.if","position":[208,176],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"f6710bca-9bff-4c8d-8cea-ab9b8a517437","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $json.data.stage_id }}","rightValue":7},{"id":"6a9b26ee-fd35-441f-9826-665fe8373992","operator":{"type":"number","operation":"lt"},"leftValue":"={{ $json.previous.stage_id }}","rightValue":7}]}},"typeVersion":2.2},{"id":"5d15907b-19f3-4d45-9320-b5404685c541","name":"Get DottedSign Access Token","type":"n8n-nodes-base.httpRequest","position":[3344,272],"parameters":{"url":"https://api.sandbox.dottedsign.com/v1/oauth/token","method":"POST","options":{},"sendBody":true,"sendQuery":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"grant_type","value":"client_credentials"},{"name":"client_id"},{"name":"client_secret"},{"name":"code"}]},"queryParameters":{"parameters":[{}]},"headerParameters":{"parameters":[{"name":"accept","value":"application/json"},{"name":"content-type","value":"application/json"}]}},"typeVersion":4.2}],"active":false,"pinData":{"Pipedrive Trigger":[{"json":{"data":{"id":1102,"title":"Deal 1","value":1950,"org_id":1214,"origin":"ManuallyCreated","status":"open","channel":null,"add_time":"2025-10-20T06:21:54Z","currency":"TWD","owner_id":5674782,"stage_id":7,"won_time":null,"label_ids":[],"lost_time":null,"origin_id":null,"person_id":1222,"channel_id":null,"close_time":null,"visible_to":"3","is_archived":false,"lost_reason":null,"pipeline_id":1,"probability":null,"update_time":"2025-10-21T02:29:56Z","archive_time":null,"custom_fields":{"085376a710a76b86622293222b048cc9c8b5809f":null,"10b0419f6153971fb927c1bc1e33004d37248377":null,"1631567a12a8c9848f7a38039ea59058711c9c81":{"id":21,"type":"enum"},"36444d22ff7c91a05ad6b13002169d7552bbce68":null,"3a1c7b49c503c0a07cd4bbc1cce0832259b1848d":{"type":"double","value":20},"3ecef3e85ac838325cacbbce9a6b3543101bb638":null,"4957db5a993971ca8ebdc5a18a4bfbdb95c631bf":{"type":"set","values":[{"id":32},{"id":35},{"id":36},{"id":37},{"id":57}]},"503bc5554fbcf7456ab01388ee8d922d72652b74":null,"631dce0ea3082a5f163572a006f5c5f0f2039b64":{"id":42,"type":"enum"},"85f55b6fcd3367a917675f8d4a33bb27b9d8213c":null,"a1c0492d8e2c34f14bc26e19c1ec9147d195130a":null,"ada6959920cefc4cea5439642d74199a7dc9ddee":{"id":14,"type":"enum"},"e0a4944818826f6ffd2ee931b698d02ff3b755bf":{"type":"set","values":[{"id":31}]},"e1047f3eaffd194e52ae51ff4a9a45247821b2d6":null,"e24d56403c4134cb88b116145de99745e3488c25":null,"ee54481d542236715af422ce8517559d60c814b5":{"id":47,"type":"enum"},"f1a31a7081c7e11be09f04ca262bf10d73970942":null},"first_won_time":null,"creator_user_id":5674782,"stage_change_time":"2025-10-21T02:29:56Z","expected_close_date":null},"meta":{"id":"3758a221-51e4-4d90-8a75-341ab1cbf550","host":"kdanmobilesoftwareltd-sandbox.pipedrive.com","type":"general","action":"change","entity":"deal","attempt":1,"user_id":"5674782","version":"2.0","entity_id":"1102","timestamp":"2025-10-21T02:29:56.276Z","company_id":"7827175","webhook_id":"2104704","is_bulk_edit":false,"change_source":"app","correlation_id":"5d8eaa57-65a7-4a11-8e7f-843500fbd7c4","webhook_owner_id":"23549028","permitted_user_ids":["5674782","11584359","11775123","16932806","22135506","23549028"]},"previous":{"stage_id":6}}}]},"settings":{"executionOrder":"v1"},"versionId":"4e0adb96-9b29-428b-a0e4-4d45a1b430f3","connections":{"Aggregate":{"main":[[{"node":"field_mappings","type":"main","index":0}]]},"Aggregate1":{"main":[[{"node":"deal_products","type":"main","index":0}]]},"Get a deal":{"main":[[{"node":"deal_details","type":"main","index":0}]]},"MergeForDS":{"main":[[{"node":"DottedSign-CreateTask","type":"main","index":0}]]},"Rename PDF":{"main":[[{"node":"Create a file","type":"main","index":0},{"node":"Extract from File","type":"main","index":0}]]},"org_details":{"main":[[{"node":"MergeAllData","type":"main","index":4}]]},"Get a person":{"main":[[{"node":"person_details","type":"main","index":0}]]},"MergeAllData":{"main":[[{"node":"Clean & Map Data","type":"main","index":0}]]},"deal_details":{"main":[[{"node":"MergeAllData","type":"main","index":1}]]},"Create a file":{"main":[[{"node":"Get DottedSign Access Token","type":"main","index":0}]]},"deal_products":{"main":[[{"node":"MergeAllData","type":"main","index":2}]]},"editFlag=True":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"field_mappings":{"main":[[{"node":"MergeAllData","type":"main","index":0}]]},"person_details":{"main":[[{"node":"MergeAllData","type":"main","index":3}]]},"setProductRows":{"main":[[{"node":"Generate Quote HTML","type":"main","index":0}]]},"Convert to HTML":{"main":[[{"node":"Gotenberg to PDF","type":"main","index":0}]]},"Clean & Map Data":{"main":[[{"node":"setProductRows","type":"main","index":0}]]},"Gotenberg to PDF":{"main":[[{"node":"Rename PDF","type":"main","index":0}]]},"activity_details":{"main":[[{"node":"MergeAllData","type":"main","index":5}]]},"Extract from File":{"main":[[{"node":"MergeForDS","type":"main","index":0}]]},"Pipedrive Trigger":{"main":[[{"node":"If Stage is 'Quotation'","type":"main","index":0}]]},"Create an activity":{"main":[[{"node":"activity_details","type":"main","index":0}]]},"Generate Quote HTML":{"main":[[{"node":"Convert to HTML","type":"main","index":0}]]},"Get an organization":{"main":[[{"node":"org_details","type":"main","index":0}]]},"DottedSign-CreateTask":{"main":[[]]},"Get many deal products":{"main":[[{"node":"Aggregate1","type":"main","index":0}]]},"If Stage is 'Quotation'":{"main":[[{"node":"Get Pipedrive Custom Fields","type":"main","index":0},{"node":"Get a deal","type":"main","index":0},{"node":"Get many deal products","type":"main","index":0},{"node":"Get a person","type":"main","index":0},{"node":"Get an organization","type":"main","index":0},{"node":"Create an activity","type":"main","index":0}]]},"Split Out Custom Fields":{"main":[[{"node":"editFlag=True","type":"main","index":0}]]},"Get DottedSign Access Token":{"main":[[{"node":"MergeForDS","type":"main","index":1}]]},"Get Pipedrive Custom Fields":{"main":[[{"node":"Split Out Custom Fields","type":"main","index":0}]]}}}


[System]
Tu es un expert n8n. Crée des workflows JSON complets et fonctionnels.
Utilise <thinking> pour expliquer ton raisonnement avant de générer le JSON.
Structure ton thinking: analyse du besoin, choix du trigger, architecture, flux de données, points d'attention.

[User] Crée un workflow n8n pour: Overview This comprehensive n8n workflow automatically transforms trending Google search queries into engaging LinkedIn posts using AI. The system runs autonomously, discovering viral topics, researching content, and publishing professionally formatted posts to grow your social media presence. Workflow Description Automate your entire social media content pipeline - from trend discovery to publication. This workflow monitors Google Trends, selects high-potential topics, creates human-like content using advanced AI, and publishes across multiple social platforms with built-in tracking. Key Features Automated Trend Discovery: Pulls trending topics from Google Trends API with customizable filters Intelligent Topic Selection: AI chooses the most relevant trending topic for your niche Multi-AI

[Assistant]
<thinking>
**Analyse du besoin**: Overview

This comprehensive n8n workflow automatically transforms trending Google search queries into engaging LinkedIn posts using AI. The system runs autonomously, discovering viral topics, researc...

**Choix du trigger**: Sélection basée sur le cas d'usage décrit.

**Architecture**: 12 nodes utilisant ai, google, http.
Structure: traitement par lots, code personnalisé, intégration IA.

**Flux de données**: Connexions définies entre les nodes pour assurer le passage des données.

**Points d'attention**: Vérifier les credentials, tester chaque node individuellement.
</thinking>

{"id":"vJw8YoQhdA5CXGeB","meta":{"instanceId":"f2cf6301a998e16084609c8635767c7f2fe71603e7ba21b5457aa517ce5164cb","templateCredsSetupCompleted":true},"name":"Social_media_post _automation_from_google_trends_and _perplexity copy","tags":[],"nodes":[{"id":"39b1272c-3700-4ce6-9aea-46b3a647fc26","name":"X1","type":"n8n-nodes-base.twitter","position":[-1500,0],"parameters":{"additionalFields":{}},"typeVersion":2},{"id":"4bab1fd3-1c21-4438-8cc1-e0d0fdde390e","name":"Facebook Graph API1","type":"n8n-nodes-base.facebookGraphApi","position":[-1500,-400],"parameters":{"options":{},"httpRequestMethod":"POST"},"typeVersion":1},{"id":"ffcd9aa8-daef-41dc-8ad3-b9a55a817b8b","name":"LinkedIn1","type":"n8n-nodes-base.linkedIn","position":[-1480,-200],"parameters":{"text":"={{ $json['choices[0].message.content'] }}","person":"[CONFIGURE_YOUR_LINKEDIN_PERSON_ID]","authentication":"communityManagement","additionalFields":{}},"typeVersion":1},{"id":"a2c2c5e5-e9b1-4744-9883-c63cda3306c9","name":"Google Sheets2","type":"n8n-nodes-base.googleSheets","position":[-1280,-200],"parameters":{"columns":{"value":{"Topic":"={{ $('Choosing Topic').item.json.message.content }}","Status":"Posted","AI Output":"={{ $json['choices[0].message.content'] }}","Date Posted":"={{ $('Schedule Trigger').item.json.timestamp }}"},"schema":[{"id":"Topic","type":"string","display":true,"removed":false,"required":false,"displayName":"Topic","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Status","type":"string","display":true,"required":false,"displayName":"Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"AI Output","type":"string","display":true,"required":false,"displayName":"AI Output","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Date Posted","type":"string","display":true,"required":false,"displayName":"Date Posted","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Topic"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"[YOUR_GOOGLE_SHEETS_URL]","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"[YOUR_GOOGLE_SHEETS_DOCUMENT_ID]","cachedResultUrl":"[YOUR_GOOGLE_SHEETS_URL]","cachedResultName":"LinkedIn Automation"}},"typeVersion":4.5},{"id":"51d3733a-004c-4938-9575-d227588140b7","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-1720,-200],"parameters":{"options":{},"fieldToSplitOut":"choices[0].message.content"},"typeVersion":1},{"id":"cc9b1e41-aaeb-43fb-a283-e3faf397cc73","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-3420,-200],"parameters":{"rule":{"interval":[{"triggerAtHour":6},{"triggerAtHour":18}]}},"typeVersion":1.2},{"id":"01d0a3b7-66db-4032-b7d7-7a7b273920a7","name":"Research Topic- Perplexity","type":"n8n-nodes-base.httpRequest","position":[-2160,-200],"parameters":{"url":"https://api.perplexity.ai/chat/completions","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"sonar-pro\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Act as a skilled editor revising AI-generated text to sound authentically human. Follow these rules:\\n\\n1. Punctuation Adjustments\\n   - Replace em dashes, semicolons, or rephrase sentences where appropriate.\\n   - Avoid semicolons in casual contexts; use periods or conjunctions (e.g., 'and,' 'but').\\n   - Remove mid-sentence ellipses unless mimicking deliberate hesitation.\\n   - Limit parenthetical asides; integrate explanations into the main sentence.\\n   - Use colons sparingly.\\n\\n2. Language\\n   - Replace hedging phrases with direct statements.\\n   - Avoid stock transitions.\\n   - Vary repetitive terms.\\n   - Use contractions in informal contexts.\\n   - Replace overly formal words with simpler alternatives.\\n\\n3. Style\\n   - Prioritize concise, varied sentence lengths.\\n   - Allow minor imperfections.\\n   - Maintain the core message but adjust tone to match the audience.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"You are a researcher and expert copywriter in a business development team of an AI Automation Agency. Generate exactly one LinkedIn post that adheres to LinkedIn's API formatting guidelines and is easy for humans to read. Follow these rules:\\n\\nStructure:\\n1. Hook: Start with a bold opening line using Unicode characters (e.g., \\\"𝐁𝐎𝐋𝐃 𝐒𝐓𝐀𝐓𝐄𝐌𝐄𝐍𝐓\\\").\\n2. Body: Use short paragraphs (1-3 sentences) separated by \\\\n\\\\n.\\n3. Use bullet points (•) for key features or highlights.\\n4. End with a clear call-to-action (e.g., \\\"Comment below with your thoughts!\\\").\\n\\nFormatting Requirements:\\n- Remove all numeric citation brackets like [2], [3], [4] from the text.\\n- Instead of citation brackets, if needed, add a brief phrase like \\\"according to Google I/O 2025\\\" or \\\"as reported by DeepMind\\\" naturally within the sentence.\\n- No Markdown or rich text formatting.\\n- Use Unicode characters or emojis for emphasis (e.g., ★, 🚀).\\n- Include up to 3 relevant hashtags at the end (e.g., #AI #Automation).\\n- For URLs or references, use placeholders like [Link] instead of raw URLs.\\n- If mentioning users or companies, use official LinkedIn URN format (e.g., \\\"urn:li:organization:123456\\\").\\n\\nContent Rules:\\n- Max 1,200 characters.\\n- Avoid promotional language.\\n- Include one statistical claim or industry insight.\\n- Add one personal anecdote or professional observation.\\n\\nReturn the post as plain text without additional commentary.\\n\\nInput: {{ $json.message.content }}\"\n    }\n  ]\n}\n","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"typeVersion":4.2},{"id":"1b226459-7dc7-46c2-9b02-769cd213e927","name":"2 Most Trending","type":"n8n-nodes-base.set","position":[-2980,-200],"parameters":{"mode":"raw","options":{},"jsonOutput":"={\n  \"most-trending\": {\n\n    \"#1\": { \n\n      \"query\":\"{{ $json.related_queries.rising[0].query }}\",\n      \"score\":\"{{ $json.related_queries.rising[0].extracted_value }}\"\n\n    },\n\n\n    \"#2\": { \n\n      \"query\":\"{{ $json.related_queries.rising[1].query }}\",\n      \"score\":\"{{ $json.related_queries.rising[1].extracted_value }}\"\n\n    }\n  }\n}"},"typeVersion":3.4},{"id":"75ccf42a-7dc8-4cc8-9d5d-202ff4b2b795","name":"High search volume keywords","type":"n8n-nodes-base.code","position":[-2760,-200],"parameters":{"jsCode":"// Get the top array from your JSON\nconst topItems = $('Google Trends').first().json.related_queries.top;\n\n// Filter the items to only include those with extracted_value > 30\nconst filtered = topItems.filter(item => item.extracted_value > 30);\n\n// Map the filtered items to their query values and join them with commas\nconst resultString = filtered.map(item => item.query).join(', ');\n\n// Return the result in a new JSON property\nreturn [{ json: { result: resultString } }];\n"},"typeVersion":2},{"id":"c85503d1-76e7-4dd7-a2e3-69966f69e0cd","name":"Choosing Topic","type":"@n8n/n8n-nodes-langchain.openAi","position":[-2540,-200],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-3.5-turbo","cachedResultName":"GPT-3.5-TURBO"},"options":{},"messages":{"values":[{"content":"=You are part of a team that creates world class blog posts. Your job is to choose the topic for each blog post. \n\nThe blog posts are posted on the website of a [COMPANY NAME + DESCRIPTION + PRODUCTS + TARGET MARKET]. The blog posts are mainly posted as part of an SEO campaign to get [YOUR_COMPANY] to rank high for its products and services.\n\nIn this instance, you are given a list of 2 keywords which have been trending the most on Google news search over the past few days. \n\nYour job is to pick one which you think would make for the most relevant blog post with the best SEO outcomes for the client. \n\nThe keywords have two attributes: \n\n1. query: This attribute determines the search query that users have been searching for which is trending. \n\n2. value: This attribute determines what percentage increase the keyword has seen compared to previous periods (i.e. the increase in search volume). \n\nYou must choose one out of the taking into consideration both the relevance of the keyword for [YOUR_COMPANY]'s SEO efforts and the comparative trendiness determined by the value attribute. \n\nOutput the keyword you decided to post a blog on and nothing else. Don't explain your reasoning. Just output the keyword. \n\nThis instance: \n\nKeyword 1:\n{{ $('2 Most Trending').item.json['most-trending']['#1'].toJsonString() }} \n\nKeyword2: \n{{ $('2 Most Trending').item.json['most-trending']['#2'].toJsonString() }} "}]}},"typeVersion":1.8},{"id":"089fdbf7-f1a0-4cd5-9769-caf94b05a939","name":"Google Trends","type":"n8n-nodes-base.httpRequest","position":[-3200,-200],"parameters":{"url":"https://serpapi.com/search","options":{},"sendQuery":true,"queryParameters":{"parameters":[{"name":"q","value":"=ai agents"},{"name":"geo","value":"US"},{"name":"hl","value":"en"},{"name":"date","value":"={{ $now.minus({ days: 3 }).format('yyyy-MM-dd') }} {{ $now.format('yyyy-MM-dd') }}"},{"name":"data_type","value":"RELATED_QUERIES"},{"name":"engine","value":"google_trends"},{"name":"api_key","value":"[YOUR_SERPAPI_KEY]"}]}},"typeVersion":4.2},{"id":"13f0ea49-1dbe-4b33-9c73-ebe9d3099003","name":"Wait","type":"n8n-nodes-base.wait","position":[-1940,-200],"webhookId":"[GENERATED_WEBHOOK_ID]","parameters":{"amount":10},"typeVersion":1.1}],"active":false,"settings":{"executionOrder":"v1"},"connections":{"Wait":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"LinkedIn1":{"main":[[{"node":"Google Sheets2","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"X1","type":"main","index":0},{"node":"Facebook Graph API1","type":"main","index":0},{"node":"LinkedIn1","type":"main","index":0}]]},"Google Trends":{"main":[[{"node":"2 Most Trending","type":"main","index":0}]]},"Choosing Topic":{"main":[[{"node":"Research Topic- Perplexity","type":"main","index":0}]]},"2 Most Trending":{"main":[[{"node":"High search volume keywords","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Google Trends","type":"main","index":0}]]},"Research Topic- Perplexity":{"main":[[{"node":"Wait","type":"main","index":0}]]},"High search volume keywords":{"main":[[{"node":"Choosing Topic","type":"main","index":0}]]}}}


[System]
Tu es un expert n8n. Crée des workflows JSON complets et fonctionnels.
Utilise <thinking> pour expliquer ton raisonnement avant de générer le JSON.
Structure ton thinking: analyse du besoin, choix du trigger, architecture, flux de données, points d'attention.

[User] Génère un workflow n8n: AI-Powered Multi-Social Media Post Automation: Google Trends & Perplexity AI

[Assistant]
<thinking>
**Analyse du besoin**: Overview

This comprehensive n8n workflow automatically transforms trending Google search queries into engaging LinkedIn posts using AI. The system runs autonomously, discovering viral topics, researc...

**Choix du trigger**: Sélection basée sur le cas d'usage décrit.

**Architecture**: 12 nodes utilisant ai, google, http.
Structure: traitement par lots, code personnalisé, intégration IA.

**Flux de données**: Connexions définies entre les nodes pour assurer le passage des données.

**Points d'attention**: Vérifier les credentials, tester chaque node individuellement.
</thinking>

{"id":"vJw8YoQhdA5CXGeB","meta":{"instanceId":"f2cf6301a998e16084609c8635767c7f2fe71603e7ba21b5457aa517ce5164cb","templateCredsSetupCompleted":true},"name":"Social_media_post _automation_from_google_trends_and _perplexity copy","tags":[],"nodes":[{"id":"39b1272c-3700-4ce6-9aea-46b3a647fc26","name":"X1","type":"n8n-nodes-base.twitter","position":[-1500,0],"parameters":{"additionalFields":{}},"typeVersion":2},{"id":"4bab1fd3-1c21-4438-8cc1-e0d0fdde390e","name":"Facebook Graph API1","type":"n8n-nodes-base.facebookGraphApi","position":[-1500,-400],"parameters":{"options":{},"httpRequestMethod":"POST"},"typeVersion":1},{"id":"ffcd9aa8-daef-41dc-8ad3-b9a55a817b8b","name":"LinkedIn1","type":"n8n-nodes-base.linkedIn","position":[-1480,-200],"parameters":{"text":"={{ $json['choices[0].message.content'] }}","person":"[CONFIGURE_YOUR_LINKEDIN_PERSON_ID]","authentication":"communityManagement","additionalFields":{}},"typeVersion":1},{"id":"a2c2c5e5-e9b1-4744-9883-c63cda3306c9","name":"Google Sheets2","type":"n8n-nodes-base.googleSheets","position":[-1280,-200],"parameters":{"columns":{"value":{"Topic":"={{ $('Choosing Topic').item.json.message.content }}","Status":"Posted","AI Output":"={{ $json['choices[0].message.content'] }}","Date Posted":"={{ $('Schedule Trigger').item.json.timestamp }}"},"schema":[{"id":"Topic","type":"string","display":true,"removed":false,"required":false,"displayName":"Topic","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Status","type":"string","display":true,"required":false,"displayName":"Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"AI Output","type":"string","display":true,"required":false,"displayName":"AI Output","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Date Posted","type":"string","display":true,"required":false,"displayName":"Date Posted","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Topic"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"[YOUR_GOOGLE_SHEETS_URL]","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"[YOUR_GOOGLE_SHEETS_DOCUMENT_ID]","cachedResultUrl":"[YOUR_GOOGLE_SHEETS_URL]","cachedResultName":"LinkedIn Automation"}},"typeVersion":4.5},{"id":"51d3733a-004c-4938-9575-d227588140b7","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-1720,-200],"parameters":{"options":{},"fieldToSplitOut":"choices[0].message.content"},"typeVersion":1},{"id":"cc9b1e41-aaeb-43fb-a283-e3faf397cc73","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-3420,-200],"parameters":{"rule":{"interval":[{"triggerAtHour":6},{"triggerAtHour":18}]}},"typeVersion":1.2},{"id":"01d0a3b7-66db-4032-b7d7-7a7b273920a7","name":"Research Topic- Perplexity","type":"n8n-nodes-base.httpRequest","position":[-2160,-200],"parameters":{"url":"https://api.perplexity.ai/chat/completions","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"sonar-pro\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Act as a skilled editor revising AI-generated text to sound authentically human. Follow these rules:\\n\\n1. Punctuation Adjustments\\n   - Replace em dashes, semicolons, or rephrase sentences where appropriate.\\n   - Avoid semicolons in casual contexts; use periods or conjunctions (e.g., 'and,' 'but').\\n   - Remove mid-sentence ellipses unless mimicking deliberate hesitation.\\n   - Limit parenthetical asides; integrate explanations into the main sentence.\\n   - Use colons sparingly.\\n\\n2. Language\\n   - Replace hedging phrases with direct statements.\\n   - Avoid stock transitions.\\n   - Vary repetitive terms.\\n   - Use contractions in informal contexts.\\n   - Replace overly formal words with simpler alternatives.\\n\\n3. Style\\n   - Prioritize concise, varied sentence lengths.\\n   - Allow minor imperfections.\\n   - Maintain the core message but adjust tone to match the audience.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"You are a researcher and expert copywriter in a business development team of an AI Automation Agency. Generate exactly one LinkedIn post that adheres to LinkedIn's API formatting guidelines and is easy for humans to read. Follow these rules:\\n\\nStructure:\\n1. Hook: Start with a bold opening line using Unicode characters (e.g., \\\"𝐁𝐎𝐋𝐃 𝐒𝐓𝐀𝐓𝐄𝐌𝐄𝐍𝐓\\\").\\n2. Body: Use short paragraphs (1-3 sentences) separated by \\\\n\\\\n.\\n3. Use bullet points (•) for key features or highlights.\\n4. End with a clear call-to-action (e.g., \\\"Comment below with your thoughts!\\\").\\n\\nFormatting Requirements:\\n- Remove all numeric citation brackets like [2], [3], [4] from the text.\\n- Instead of citation brackets, if needed, add a brief phrase like \\\"according to Google I/O 2025\\\" or \\\"as reported by DeepMind\\\" naturally within the sentence.\\n- No Markdown or rich text formatting.\\n- Use Unicode characters or emojis for emphasis (e.g., ★, 🚀).\\n- Include up to 3 relevant hashtags at the end (e.g., #AI #Automation).\\n- For URLs or references, use placeholders like [Link] instead of raw URLs.\\n- If mentioning users or companies, use official LinkedIn URN format (e.g., \\\"urn:li:organization:123456\\\").\\n\\nContent Rules:\\n- Max 1,200 characters.\\n- Avoid promotional language.\\n- Include one statistical claim or industry insight.\\n- Add one personal anecdote or professional observation.\\n\\nReturn the post as plain text without additional commentary.\\n\\nInput: {{ $json.message.content }}\"\n    }\n  ]\n}\n","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"typeVersion":4.2},{"id":"1b226459-7dc7-46c2-9b02-769cd213e927","name":"2 Most Trending","type":"n8n-nodes-base.set","position":[-2980,-200],"parameters":{"mode":"raw","options":{},"jsonOutput":"={\n  \"most-trending\": {\n\n    \"#1\": { \n\n      \"query\":\"{{ $json.related_queries.rising[0].query }}\",\n      \"score\":\"{{ $json.related_queries.rising[0].extracted_value }}\"\n\n    },\n\n\n    \"#2\": { \n\n      \"query\":\"{{ $json.related_queries.rising[1].query }}\",\n      \"score\":\"{{ $json.related_queries.rising[1].extracted_value }}\"\n\n    }\n  }\n}"},"typeVersion":3.4},{"id":"75ccf42a-7dc8-4cc8-9d5d-202ff4b2b795","name":"High search volume keywords","type":"n8n-nodes-base.code","position":[-2760,-200],"parameters":{"jsCode":"// Get the top array from your JSON\nconst topItems = $('Google Trends').first().json.related_queries.top;\n\n// Filter the items to only include those with extracted_value > 30\nconst filtered = topItems.filter(item => item.extracted_value > 30);\n\n// Map the filtered items to their query values and join them with commas\nconst resultString = filtered.map(item => item.query).join(', ');\n\n// Return the result in a new JSON property\nreturn [{ json: { result: resultString } }];\n"},"typeVersion":2},{"id":"c85503d1-76e7-4dd7-a2e3-69966f69e0cd","name":"Choosing Topic","type":"@n8n/n8n-nodes-langchain.openAi","position":[-2540,-200],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-3.5-turbo","cachedResultName":"GPT-3.5-TURBO"},"options":{},"messages":{"values":[{"content":"=You are part of a team that creates world class blog posts. Your job is to choose the topic for each blog post. \n\nThe blog posts are posted on the website of a [COMPANY NAME + DESCRIPTION + PRODUCTS + TARGET MARKET]. The blog posts are mainly posted as part of an SEO campaign to get [YOUR_COMPANY] to rank high for its products and services.\n\nIn this instance, you are given a list of 2 keywords which have been trending the most on Google news search over the past few days. \n\nYour job is to pick one which you think would make for the most relevant blog post with the best SEO outcomes for the client. \n\nThe keywords have two attributes: \n\n1. query: This attribute determines the search query that users have been searching for which is trending. \n\n2. value: This attribute determines what percentage increase the keyword has seen compared to previous periods (i.e. the increase in search volume). \n\nYou must choose one out of the taking into consideration both the relevance of the keyword for [YOUR_COMPANY]'s SEO efforts and the comparative trendiness determined by the value attribute. \n\nOutput the keyword you decided to post a blog on and nothing else. Don't explain your reasoning. Just output the keyword. \n\nThis instance: \n\nKeyword 1:\n{{ $('2 Most Trending').item.json['most-trending']['#1'].toJsonString() }} \n\nKeyword2: \n{{ $('2 Most Trending').item.json['most-trending']['#2'].toJsonString() }} "}]}},"typeVersion":1.8},{"id":"089fdbf7-f1a0-4cd5-9769-caf94b05a939","name":"Google Trends","type":"n8n-nodes-base.httpRequest","position":[-3200,-200],"parameters":{"url":"https://serpapi.com/search","options":{},"sendQuery":true,"queryParameters":{"parameters":[{"name":"q","value":"=ai agents"},{"name":"geo","value":"US"},{"name":"hl","value":"en"},{"name":"date","value":"={{ $now.minus({ days: 3 }).format('yyyy-MM-dd') }} {{ $now.format('yyyy-MM-dd') }}"},{"name":"data_type","value":"RELATED_QUERIES"},{"name":"engine","value":"google_trends"},{"name":"api_key","value":"[YOUR_SERPAPI_KEY]"}]}},"typeVersion":4.2},{"id":"13f0ea49-1dbe-4b33-9c73-ebe9d3099003","name":"Wait","type":"n8n-nodes-base.wait","position":[-1940,-200],"webhookId":"[GENERATED_WEBHOOK_ID]","parameters":{"amount":10},"typeVersion":1.1}],"active":false,"settings":{"executionOrder":"v1"},"connections":{"Wait":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"LinkedIn1":{"main":[[{"node":"Google Sheets2","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"X1","type":"main","index":0},{"node":"Facebook Graph API1","type":"main","index":0},{"node":"LinkedIn1","type":"main","index":0}]]},"Google Trends":{"main":[[{"node":"2 Most Trending","type":"main","index":0}]]},"Choosing Topic":{"main":[[{"node":"Research Topic- Perplexity","type":"main","index":0}]]},"2 Most Trending":{"main":[[{"node":"High search volume keywords","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Google Trends","type":"main","index":0}]]},"Research Topic- Perplexity":{"main":[[{"node":"Wait","type":"main","index":0}]]},"High search volume keywords":{"main":[[{"node":"Choosing Topic","type":"main","index":0}]]}}}


[System]
Tu es un expert n8n. Crée des workflows JSON complets et fonctionnels.
Utilise <thinking> pour expliquer ton raisonnement avant de générer le JSON.
Structure ton thinking: analyse du besoin, choix du trigger, architecture, flux de données, points d'attention.

[User] Crée un workflow n8n pour: Introduction Automate price monitoring for e-commerce competitors—ideal for retailers, analysts, and pricing teams. Scrapes competitor sites, extracts pricing/stock data via AI, detects changes, and sends instant alerts for dynamic pricing strategies. How It Works Scrapes competitor URLs via Firecrawl and Apify, extracts data with AI, detects price/stock changes, logs to Google Sheets, and sends Telegram alerts. Workflow Template Trigger → Scrape URL → AI Extract → Parse → Merge Historical → Detect Changes → Update Sheets + Send Telegram Alert Workflow Steps Trigger & Scrape → Manual/scheduled trigger → Firecrawl + Apify fetch competitor data AI Processing → Claude extracts product details → Parses and structures data Change Detection → Reads historical prices → Merges with current data →

[Assistant]
<thinking>
**Analyse du besoin**: Introduction

Automate price monitoring for e-commerce competitors—ideal for retailers, analysts, and pricing teams. Scrapes competitor sites,
extracts pricing/stock data via AI, detects changes, and ...

**Choix du trigger**: Sélection basée sur le cas d'usage décrit.

**Architecture**: 17 nodes utilisant ai, google, http.
Structure: traitement par lots, code personnalisé, intégration IA.

**Flux de données**: Connexions définies entre les nodes pour assurer le passage des données.

**Points d'attention**: Vérifier les credentials, tester chaque node individuellement.
</thinking>

{"id":"YnD0kvM9AYMjYxmj","meta":{"instanceId":"b91e510ebae4127f953fd2f5f8d40d58ca1e71c746d4500c12ae86aad04c1502","templateCredsSetupCompleted":true},"name":"Multi-Site Product Price Monitor: Claude-Sonnet , Google Sheets & Telegram Alert","tags":[{"id":"7zsdOA50QGm7RNqx","name":"Monitoring","createdAt":"2025-10-23T16:41:17.031Z","updatedAt":"2025-10-23T16:41:17.031Z"},{"id":"BL8TsHYj5FkNYzfi","name":"E-commerce","createdAt":"2025-10-23T16:41:16.985Z","updatedAt":"2025-10-23T16:41:16.985Z"},{"id":"dlf9zFSN3j6s2jgO","name":"Business Intelligence","createdAt":"2025-10-23T16:41:17.008Z","updatedAt":"2025-10-23T16:41:17.008Z"},{"id":"lpozR2Ct8reF9bCk","name":"AI","createdAt":"2025-10-23T16:41:17.062Z","updatedAt":"2025-10-23T16:41:17.062Z"}],"nodes":[{"id":"306294b3-27b8-4821-9b04-0e8d210af07e","name":"⏰ Monitor Every 6 Hours","type":"n8n-nodes-base.scheduleTrigger","notes":"Triggers the workflow every 6 hours to check competitor data","position":[-832,352],"parameters":{"rule":{"interval":[{"field":"hours","hoursInterval":6}]}},"typeVersion":1.2},{"id":"8b934690-1e26-4810-820d-8ff785691adf","name":"Scrape a url and get its content","type":"@mendable/n8n-nodes-firecrawl.firecrawl","position":[-1408,96],"parameters":{"url":"https://www.on.com/en-sg/shop/mens/shoes","operation":"scrape","scrapeOptions":{"options":{"formats":{"format":[{"type":"json","prompt":"price of the shoe"}]},"headers":{}}},"requestOptions":{}},"typeVersion":1},{"id":"90ed5eb7-6236-47e1-88c6-c5278efe24fa","name":"Message a model","type":"n8n-nodes-base.perplexity","position":[-1568,0],"parameters":{"model":"sonar","options":{},"messages":{"message":[{"content":"Price of the shoe  "}]},"requestOptions":{}},"typeVersion":1},{"id":"e1e006de-d363-4e5a-adbd-77ffc901f42d","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-1296,0],"parameters":{"options":{},"fieldToSplitOut":"citations"},"typeVersion":1},{"id":"11fdf8bc-aa37-4f42-8bbe-8e16c47c8b47","name":"Get Results Apify","type":"n8n-nodes-base.httpRequest","position":[-1216,272],"parameters":{"url":"https://api.apify.com/v2/acts/compass~google-maps-extractor/runs/last/dataset/items?token=YOUR API KEY","options":{},"authentication":"genericCredentialType","genericAuthType":"httpBearerAuth"},"typeVersion":4.2,"alwaysOutputData":true},{"id":"b6a20e25-d82a-493b-b305-066e043f6ba1","name":"Start Actor Apify","type":"n8n-nodes-base.httpRequest","position":[-1616,272],"parameters":{"url":"https://api.apify.com/v2/acts/compass~google-maps-extractor/runs?token=YOUR API KEY","method":"POST","options":{},"jsonBody":"{\n    \"language\": \"en\",\n    \"locationQuery\": \"worldwide\",\n    \"maxCrawledPlacesPerSearch\": 50,\n    \"searchStringsArray\": [\n        \"shoe stores\",\n        \"shoe shops\"\n    ],\n    \"skipClosedPlaces\": false\n}","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpBearerAuth"},"typeVersion":4.2,"alwaysOutputData":true},{"id":"47a1e71a-6bbf-4cfe-82f1-b46744d247ee","name":"Converts unstructured AI text into organized, usable data fields","type":"n8n-nodes-base.code","notes":"Parses and validates the AI extracted data","position":[-576,192],"parameters":{"jsCode":"// Parse AI response and clean data\nconst items = [];\n\nfor (const item of $input.all()) {\n  try {\n    // Parse the AI response\n    let parsed;\n    const response = item.json.choices?.[0]?.message?.content || item.json.message || '';\n    \n    // Remove markdown code blocks if present\n    const cleaned = response.replace(/```json\\n?|```\\n?/g, '').trim();\n    \n    try {\n      parsed = JSON.parse(cleaned);\n    } catch (e) {\n      // Try to extract JSON from the response\n      const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n      if (jsonMatch) {\n        parsed = JSON.parse(jsonMatch[0]);\n      } else {\n        throw new Error('Could not parse JSON from AI response');\n      }\n    }\n    \n    // Enrich with metadata\n    items.push({\n      json: {\n        ...parsed,\n        scrapedAt: new Date().toISOString(),\n        priceChange: 0, // Will be calculated in comparison\n        priceChangePercent: 0,\n        isNewLow: false,\n        alertLevel: 'none'\n      }\n    });\n  } catch (error) {\n    console.error('Failed to parse item:', error.message);\n    // Add error item for debugging\n    items.push({\n      json: {\n        error: error.message,\n        rawResponse: item.json,\n        competitorName: 'Parse Error',\n        scrapedAt: new Date().toISOString()\n      }\n    });\n  }\n}\n\nreturn items;"},"typeVersion":2},{"id":"3e8d7348-ccef-4cb5-aca4-d5ed6f210199","name":"🔀 Merge Current with Historical1","type":"n8n-nodes-base.merge","notes":"Combines current scrape with historical data for comparison","position":[-384,224],"parameters":{"mode":"combine","options":{},"fieldsToMatchString":"rawResponse.message.content"},"typeVersion":3},{"id":"7e24cbab-31e4-47ba-97f2-9a7a71335905","name":"🔍 Detect Price & Stock Changes1","type":"n8n-nodes-base.code","notes":"Intelligent change detection with alert level classification","position":[-208,224],"parameters":{"jsCode":"// Compare current prices with historical and detect changes\nconst results = [];\n\nfor (const item of $input.all()) {\n  const current = item.json;\n  \n  // Skip error items\n  if (current.error) {\n    results.push({ json: current });\n    continue;\n  }\n  \n  // Find historical data for this competitor\n  const historical = $('📊 Read Historical Data').all()\n    .find(h => h.json.competitorName === current.competitorName);\n  \n  let alertLevel = 'none';\n  let changes = [];\n  \n  if (historical && historical.json.currentPrice) {\n    const oldPrice = parseFloat(historical.json.currentPrice);\n    const newPrice = parseFloat(current.currentPrice);\n    const priceChange = newPrice - oldPrice;\n    const priceChangePercent = ((priceChange / oldPrice) * 100).toFixed(2);\n    \n    current.priceChange = priceChange;\n    current.priceChangePercent = parseFloat(priceChangePercent);\n    current.previousPrice = oldPrice;\n    \n    // Determine alert level based on price changes\n    if (Math.abs(priceChangePercent) >= 20) {\n      alertLevel = 'critical';\n      changes.push(`Price ${priceChange > 0 ? 'increased' : 'decreased'} by ${Math.abs(priceChangePercent)}%`);\n    } else if (Math.abs(priceChangePercent) >= 10) {\n      alertLevel = 'warning';\n      changes.push(`Price ${priceChange > 0 ? 'increased' : 'decreased'} by ${Math.abs(priceChangePercent)}%`);\n    } else if (Math.abs(priceChangePercent) >= 5) {\n      alertLevel = 'info';\n      changes.push(`Minor price change: ${priceChangePercent}%`);\n    }\n    \n    // Check if it's a new low price\n    const historicalLow = parseFloat(historical.json.lowestPrice || oldPrice);\n    if (newPrice < historicalLow) {\n      current.isNewLow = true;\n      alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n      changes.push('🎯 NEW LOWEST PRICE!');\n    }\n    current.lowestPrice = Math.min(newPrice, historicalLow);\n    \n    // Stock level changes\n    if (historical.json.stockLevel !== current.stockLevel) {\n      if (current.stockLevel === 'Out of Stock') {\n        alertLevel = 'critical';\n        changes.push('📦 Product went OUT OF STOCK');\n      } else if (current.stockLevel === 'Low Stock') {\n        alertLevel = alertLevel === 'none' ? 'warning' : alertLevel;\n        changes.push('⚠ Stock level is LOW');\n      } else if (historical.json.stockLevel === 'Out of Stock' && current.inStock) {\n        alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n        changes.push('✅ Back in stock!');\n      }\n    }\n    \n    // Rating changes\n    const oldRating = parseFloat(historical.json.rating || 0);\n    const newRating = parseFloat(current.rating || 0);\n    const ratingChange = newRating - oldRating;\n    \n    if (Math.abs(ratingChange) >= 0.5) {\n      alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n      changes.push(`⭐ Rating ${ratingChange > 0 ? 'improved' : 'dropped'} by ${Math.abs(ratingChange).toFixed(1)} stars`);\n    }\n    \n    // Review count changes\n    const oldReviews = parseInt(historical.json.reviewCount || 0);\n    const newReviews = parseInt(current.reviewCount || 0);\n    const reviewDiff = newReviews - oldReviews;\n    \n    if (reviewDiff > 0) {\n      changes.push(`💬 ${reviewDiff} new review${reviewDiff > 1 ? 's' : ''}`);\n    }\n  } else {\n    // First time seeing this competitor\n    alertLevel = 'info';\n    changes.push('🆕 First time tracking this competitor');\n    current.lowestPrice = current.currentPrice;\n  }\n  \n  current.alertLevel = alertLevel;\n  current.changesSummary = changes.join(' | ');\n  current.hasChanges = alertLevel !== 'none';\n  \n  results.push({ json: current });\n}\n\nreturn results;"},"typeVersion":2},{"id":"4b8b4578-e6aa-461a-ae0a-7289bd0bf7e3","name":"💾 Update Historical Data1","type":"n8n-nodes-base.googleSheets","notes":"Saves current data to historical tracking sheet","position":[-32,320],"parameters":{"columns":{"value":{"rating":"={{ $json.rating }}","inStock":"={{ $json.inStock }}","currency":"={{ $json.currency }}","scrapedAt":"={{ $json.scrapedAt }}","productUrl":"={{ $json.productUrl }}","stockLevel":"={{ $json.stockLevel }}","lowestPrice":"={{ $json.lowestPrice }}","productName":"={{ $json.productName }}","reviewCount":"={{ $json.reviewCount }}","currentPrice":"={{ $json.currentPrice }}","originalPrice":"={{ $json.originalPrice }}","competitorName":"={{ $json.competitorName }}"},"mappingMode":"defineBelow"},"options":{},"operation":"append","sheetName":{"mode":"name","value":"Historical Data"},"documentId":{"__rl":true,"mode":"id","value":"= {{ $env.GOOGLE_SHEET_ID }}"}},"typeVersion":4.7},{"id":"28d2de55-ef62-40cd-a22b-a13eee3c2dc8","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-1760,144],"parameters":{},"typeVersion":1},{"id":"62cf73d2-a328-463b-9ea5-0d3fa8e3ba56","name":"🤖 AI Extract Product Data using Claude-Sonnet 4.5","type":"@n8n/n8n-nodes-langchain.anthropic","position":[-864,192],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"claude-sonnet-4-5-20250929","cachedResultName":"claude-sonnet-4-5-20250929"},"options":{},"messages":{"values":[{"content":"You are an accurate e-commerce data parser. From the provided HTML, extract shoe details and output a pure JSON object—no markdown or extra text.\n\nInclude the following fields:\n\n- productName: string \n- currentPrice: number (numeric value only, no currency symbols) \n- originalPrice: number (if discounted, otherwise same as currentPrice) \n- currency: string (USD, EUR, etc.) \n- inStock: boolean \n- stockLevel: string (\"In Stock\", \"Low Stock\", \"Out of Stock\", \"Limited\", etc.) \n- rating: number (0-5 scale) \n- reviewCount: number \n- lastUpdated: string (current ISO timestamp) \n- productUrl: string (from context) \n- competitorName: string (from context)\n\nOutput only the JSON object—no notes, comments, or formatting.\n"}]}},"typeVersion":1},{"id":"e5998861-2d29-4fdb-a5c0-445cf79ac50e","name":"🔀 Merge Current with Historical","type":"n8n-nodes-base.merge","notes":"Combines current scrape with historical data for comparison","position":[-1024,176],"parameters":{"numberInputs":3},"typeVersion":3},{"id":"6815d6c1-43c5-49a8-8f41-eafa0ee83363","name":"📊 Read Historical Data","type":"n8n-nodes-base.googleSheets","notes":"Loads previous scan data for comparison","position":[-624,352],"parameters":{"options":{},"sheetName":{"mode":"name","value":"Historical Data"},"documentId":{"__rl":true,"mode":"id","value":"={{ $env.GOOGLE_SHEET_ID }}"}},"typeVersion":4.7},{"id":"0c300e39-74da-4947-ab75-1360158f48a1","name":"📝 Log Alert Details","type":"n8n-nodes-base.googleSheets","notes":"Logs all alerts to separate tracking sheet","position":[-48,160],"parameters":{"columns":{"value":{"rating":"={{ $json.rating }}","timestamp":"={{ $json.scrapedAt }}","alertLevel":"={{ $json.alertLevel }}","productUrl":"={{ $json.productUrl }}","stockLevel":"={{ $json.stockLevel }}","priceChange":"={{ $json.priceChange || 0 }}","productName":"={{ $json.productName }}","currentPrice":"={{ $json.currentPrice }}","previousPrice":"={{ $json.previousPrice || 'N/A' }}","changesSummary":"={{ $json.changesSummary }}","competitorName":"={{ $json.competitorName }}","priceChangePercent":"={{ $json.priceChangePercent || 0 }}"},"mappingMode":"defineBelow"},"options":{},"operation":"append","sheetName":{"mode":"name","value":"Alert Log"},"documentId":{"__rl":true,"mode":"id","value":"={{ $env.GOOGLE_SHEET_ID }}"}},"typeVersion":4.7},{"id":"1833ee8f-13ca-40f3-a3ce-e7c09bbff5fc","name":"Send a text message","type":"n8n-nodes-base.telegram","position":[112,240],"webhookId":"ae976d33-11d1-4d92-9289-fc86a1525828","parameters":{"text":"The competitors’ pricing has been finalized.","additionalFields":{}},"typeVersion":1.2},{"id":"864886e9-21d0-402f-8f1f-46216a5e1373","name":"Pause the workflow to let the Apify scraping task finish","type":"n8n-nodes-base.wait","position":[-1424,272],"webhookId":"426f22d5-31db-4344-ae7a-13dedfc46bf4","parameters":{"amount":25},"typeVersion":1.1}],"active":false,"settings":{"executionOrder":"v1"},"connections":{"Split Out":{"main":[[{"node":"🔀 Merge Current with Historical","type":"main","index":0}]]},"Message a model":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Get Results Apify":{"main":[[{"node":"🔀 Merge Current with Historical","type":"main","index":2}]]},"Start Actor Apify":{"main":[[{"node":"Pause the workflow to let the Apify scraping task finish","type":"main","index":0}]]},"📝 Log Alert Details":{"main":[[{"node":"Send a text message","type":"main","index":0}]]},"⏰ Monitor Every 6 Hours":{"main":[[{"node":"📊 Read Historical Data","type":"main","index":0}]]},"📊 Read Historical Data":{"main":[[{"node":"🔀 Merge Current with Historical1","type":"main","index":1}]]},"💾 Update Historical Data1":{"main":[[{"node":"Send a text message","type":"main","index":0}]]},"Scrape a url and get its content":{"main":[[{"node":"🔀 Merge Current with Historical","type":"main","index":1}]]},"🔀 Merge Current with Historical":{"main":[[{"node":"🤖 AI Extract Product Data using Claude-Sonnet 4.5","type":"main","index":0}]]},"🔍 Detect Price & Stock Changes1":{"main":[[{"node":"💾 Update Historical Data1","type":"main","index":0},{"node":"📝 Log Alert Details","type":"main","index":0}]]},"🔀 Merge Current with Historical1":{"main":[[{"node":"🔍 Detect Price & Stock Changes1","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Message a model","type":"main","index":0},{"node":"Scrape a url and get its content","type":"main","index":0},{"node":"Start Actor Apify","type":"main","index":0}]]},"🤖 AI Extract Product Data using Claude-Sonnet 4.5":{"main":[[{"node":"Converts unstructured AI text into organized, usable data fields","type":"main","index":0}]]},"Pause the workflow to let the Apify scraping task finish":{"main":[[{"node":"Get Results Apify","type":"main","index":0}]]},"Converts unstructured AI text into organized, usable data fields":{"main":[[{"node":"🔀 Merge Current with Historical1","type":"main","index":0}]]}}}


[System]
Tu es un expert n8n. Crée des workflows JSON complets et fonctionnels.
Utilise <thinking> pour expliquer ton raisonnement avant de générer le JSON.
Structure ton thinking: analyse du besoin, choix du trigger, architecture, flux de données, points d'attention.

[User] Génère un workflow n8n: E-commerce Price Monitor with Firecrawl, Claude-Sonnet AI & Telegram Alerts

[Assistant]
<thinking>
**Analyse du besoin**: Introduction

Automate price monitoring for e-commerce competitors—ideal for retailers, analysts, and pricing teams. Scrapes competitor sites,
extracts pricing/stock data via AI, detects changes, and ...

**Choix du trigger**: Sélection basée sur le cas d'usage décrit.

**Architecture**: 17 nodes utilisant ai, google, http.
Structure: traitement par lots, code personnalisé, intégration IA.

**Flux de données**: Connexions définies entre les nodes pour assurer le passage des données.

**Points d'attention**: Vérifier les credentials, tester chaque node individuellement.
</thinking>

{"id":"YnD0kvM9AYMjYxmj","meta":{"instanceId":"b91e510ebae4127f953fd2f5f8d40d58ca1e71c746d4500c12ae86aad04c1502","templateCredsSetupCompleted":true},"name":"Multi-Site Product Price Monitor: Claude-Sonnet , Google Sheets & Telegram Alert","tags":[{"id":"7zsdOA50QGm7RNqx","name":"Monitoring","createdAt":"2025-10-23T16:41:17.031Z","updatedAt":"2025-10-23T16:41:17.031Z"},{"id":"BL8TsHYj5FkNYzfi","name":"E-commerce","createdAt":"2025-10-23T16:41:16.985Z","updatedAt":"2025-10-23T16:41:16.985Z"},{"id":"dlf9zFSN3j6s2jgO","name":"Business Intelligence","createdAt":"2025-10-23T16:41:17.008Z","updatedAt":"2025-10-23T16:41:17.008Z"},{"id":"lpozR2Ct8reF9bCk","name":"AI","createdAt":"2025-10-23T16:41:17.062Z","updatedAt":"2025-10-23T16:41:17.062Z"}],"nodes":[{"id":"306294b3-27b8-4821-9b04-0e8d210af07e","name":"⏰ Monitor Every 6 Hours","type":"n8n-nodes-base.scheduleTrigger","notes":"Triggers the workflow every 6 hours to check competitor data","position":[-832,352],"parameters":{"rule":{"interval":[{"field":"hours","hoursInterval":6}]}},"typeVersion":1.2},{"id":"8b934690-1e26-4810-820d-8ff785691adf","name":"Scrape a url and get its content","type":"@mendable/n8n-nodes-firecrawl.firecrawl","position":[-1408,96],"parameters":{"url":"https://www.on.com/en-sg/shop/mens/shoes","operation":"scrape","scrapeOptions":{"options":{"formats":{"format":[{"type":"json","prompt":"price of the shoe"}]},"headers":{}}},"requestOptions":{}},"typeVersion":1},{"id":"90ed5eb7-6236-47e1-88c6-c5278efe24fa","name":"Message a model","type":"n8n-nodes-base.perplexity","position":[-1568,0],"parameters":{"model":"sonar","options":{},"messages":{"message":[{"content":"Price of the shoe  "}]},"requestOptions":{}},"typeVersion":1},{"id":"e1e006de-d363-4e5a-adbd-77ffc901f42d","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-1296,0],"parameters":{"options":{},"fieldToSplitOut":"citations"},"typeVersion":1},{"id":"11fdf8bc-aa37-4f42-8bbe-8e16c47c8b47","name":"Get Results Apify","type":"n8n-nodes-base.httpRequest","position":[-1216,272],"parameters":{"url":"https://api.apify.com/v2/acts/compass~google-maps-extractor/runs/last/dataset/items?token=YOUR API KEY","options":{},"authentication":"genericCredentialType","genericAuthType":"httpBearerAuth"},"typeVersion":4.2,"alwaysOutputData":true},{"id":"b6a20e25-d82a-493b-b305-066e043f6ba1","name":"Start Actor Apify","type":"n8n-nodes-base.httpRequest","position":[-1616,272],"parameters":{"url":"https://api.apify.com/v2/acts/compass~google-maps-extractor/runs?token=YOUR API KEY","method":"POST","options":{},"jsonBody":"{\n    \"language\": \"en\",\n    \"locationQuery\": \"worldwide\",\n    \"maxCrawledPlacesPerSearch\": 50,\n    \"searchStringsArray\": [\n        \"shoe stores\",\n        \"shoe shops\"\n    ],\n    \"skipClosedPlaces\": false\n}","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpBearerAuth"},"typeVersion":4.2,"alwaysOutputData":true},{"id":"47a1e71a-6bbf-4cfe-82f1-b46744d247ee","name":"Converts unstructured AI text into organized, usable data fields","type":"n8n-nodes-base.code","notes":"Parses and validates the AI extracted data","position":[-576,192],"parameters":{"jsCode":"// Parse AI response and clean data\nconst items = [];\n\nfor (const item of $input.all()) {\n  try {\n    // Parse the AI response\n    let parsed;\n    const response = item.json.choices?.[0]?.message?.content || item.json.message || '';\n    \n    // Remove markdown code blocks if present\n    const cleaned = response.replace(/```json\\n?|```\\n?/g, '').trim();\n    \n    try {\n      parsed = JSON.parse(cleaned);\n    } catch (e) {\n      // Try to extract JSON from the response\n      const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n      if (jsonMatch) {\n        parsed = JSON.parse(jsonMatch[0]);\n      } else {\n        throw new Error('Could not parse JSON from AI response');\n      }\n    }\n    \n    // Enrich with metadata\n    items.push({\n      json: {\n        ...parsed,\n        scrapedAt: new Date().toISOString(),\n        priceChange: 0, // Will be calculated in comparison\n        priceChangePercent: 0,\n        isNewLow: false,\n        alertLevel: 'none'\n      }\n    });\n  } catch (error) {\n    console.error('Failed to parse item:', error.message);\n    // Add error item for debugging\n    items.push({\n      json: {\n        error: error.message,\n        rawResponse: item.json,\n        competitorName: 'Parse Error',\n        scrapedAt: new Date().toISOString()\n      }\n    });\n  }\n}\n\nreturn items;"},"typeVersion":2},{"id":"3e8d7348-ccef-4cb5-aca4-d5ed6f210199","name":"🔀 Merge Current with Historical1","type":"n8n-nodes-base.merge","notes":"Combines current scrape with historical data for comparison","position":[-384,224],"parameters":{"mode":"combine","options":{},"fieldsToMatchString":"rawResponse.message.content"},"typeVersion":3},{"id":"7e24cbab-31e4-47ba-97f2-9a7a71335905","name":"🔍 Detect Price & Stock Changes1","type":"n8n-nodes-base.code","notes":"Intelligent change detection with alert level classification","position":[-208,224],"parameters":{"jsCode":"// Compare current prices with historical and detect changes\nconst results = [];\n\nfor (const item of $input.all()) {\n  const current = item.json;\n  \n  // Skip error items\n  if (current.error) {\n    results.push({ json: current });\n    continue;\n  }\n  \n  // Find historical data for this competitor\n  const historical = $('📊 Read Historical Data').all()\n    .find(h => h.json.competitorName === current.competitorName);\n  \n  let alertLevel = 'none';\n  let changes = [];\n  \n  if (historical && historical.json.currentPrice) {\n    const oldPrice = parseFloat(historical.json.currentPrice);\n    const newPrice = parseFloat(current.currentPrice);\n    const priceChange = newPrice - oldPrice;\n    const priceChangePercent = ((priceChange / oldPrice) * 100).toFixed(2);\n    \n    current.priceChange = priceChange;\n    current.priceChangePercent = parseFloat(priceChangePercent);\n    current.previousPrice = oldPrice;\n    \n    // Determine alert level based on price changes\n    if (Math.abs(priceChangePercent) >= 20) {\n      alertLevel = 'critical';\n      changes.push(`Price ${priceChange > 0 ? 'increased' : 'decreased'} by ${Math.abs(priceChangePercent)}%`);\n    } else if (Math.abs(priceChangePercent) >= 10) {\n      alertLevel = 'warning';\n      changes.push(`Price ${priceChange > 0 ? 'increased' : 'decreased'} by ${Math.abs(priceChangePercent)}%`);\n    } else if (Math.abs(priceChangePercent) >= 5) {\n      alertLevel = 'info';\n      changes.push(`Minor price change: ${priceChangePercent}%`);\n    }\n    \n    // Check if it's a new low price\n    const historicalLow = parseFloat(historical.json.lowestPrice || oldPrice);\n    if (newPrice < historicalLow) {\n      current.isNewLow = true;\n      alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n      changes.push('🎯 NEW LOWEST PRICE!');\n    }\n    current.lowestPrice = Math.min(newPrice, historicalLow);\n    \n    // Stock level changes\n    if (historical.json.stockLevel !== current.stockLevel) {\n      if (current.stockLevel === 'Out of Stock') {\n        alertLevel = 'critical';\n        changes.push('📦 Product went OUT OF STOCK');\n      } else if (current.stockLevel === 'Low Stock') {\n        alertLevel = alertLevel === 'none' ? 'warning' : alertLevel;\n        changes.push('⚠ Stock level is LOW');\n      } else if (historical.json.stockLevel === 'Out of Stock' && current.inStock) {\n        alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n        changes.push('✅ Back in stock!');\n      }\n    }\n    \n    // Rating changes\n    const oldRating = parseFloat(historical.json.rating || 0);\n    const newRating = parseFloat(current.rating || 0);\n    const ratingChange = newRating - oldRating;\n    \n    if (Math.abs(ratingChange) >= 0.5) {\n      alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n      changes.push(`⭐ Rating ${ratingChange > 0 ? 'improved' : 'dropped'} by ${Math.abs(ratingChange).toFixed(1)} stars`);\n    }\n    \n    // Review count changes\n    const oldReviews = parseInt(historical.json.reviewCount || 0);\n    const newReviews = parseInt(current.reviewCount || 0);\n    const reviewDiff = newReviews - oldReviews;\n    \n    if (reviewDiff > 0) {\n      changes.push(`💬 ${reviewDiff} new review${reviewDiff > 1 ? 's' : ''}`);\n    }\n  } else {\n    // First time seeing this competitor\n    alertLevel = 'info';\n    changes.push('🆕 First time tracking this competitor');\n    current.lowestPrice = current.currentPrice;\n  }\n  \n  current.alertLevel = alertLevel;\n  current.changesSummary = changes.join(' | ');\n  current.hasChanges = alertLevel !== 'none';\n  \n  results.push({ json: current });\n}\n\nreturn results;"},"typeVersion":2},{"id":"4b8b4578-e6aa-461a-ae0a-7289bd0bf7e3","name":"💾 Update Historical Data1","type":"n8n-nodes-base.googleSheets","notes":"Saves current data to historical tracking sheet","position":[-32,320],"parameters":{"columns":{"value":{"rating":"={{ $json.rating }}","inStock":"={{ $json.inStock }}","currency":"={{ $json.currency }}","scrapedAt":"={{ $json.scrapedAt }}","productUrl":"={{ $json.productUrl }}","stockLevel":"={{ $json.stockLevel }}","lowestPrice":"={{ $json.lowestPrice }}","productName":"={{ $json.productName }}","reviewCount":"={{ $json.reviewCount }}","currentPrice":"={{ $json.currentPrice }}","originalPrice":"={{ $json.originalPrice }}","competitorName":"={{ $json.competitorName }}"},"mappingMode":"defineBelow"},"options":{},"operation":"append","sheetName":{"mode":"name","value":"Historical Data"},"documentId":{"__rl":true,"mode":"id","value":"= {{ $env.GOOGLE_SHEET_ID }}"}},"typeVersion":4.7},{"id":"28d2de55-ef62-40cd-a22b-a13eee3c2dc8","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-1760,144],"parameters":{},"typeVersion":1},{"id":"62cf73d2-a328-463b-9ea5-0d3fa8e3ba56","name":"🤖 AI Extract Product Data using Claude-Sonnet 4.5","type":"@n8n/n8n-nodes-langchain.anthropic","position":[-864,192],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"claude-sonnet-4-5-20250929","cachedResultName":"claude-sonnet-4-5-20250929"},"options":{},"messages":{"values":[{"content":"You are an accurate e-commerce data parser. From the provided HTML, extract shoe details and output a pure JSON object—no markdown or extra text.\n\nInclude the following fields:\n\n- productName: string \n- currentPrice: number (numeric value only, no currency symbols) \n- originalPrice: number (if discounted, otherwise same as currentPrice) \n- currency: string (USD, EUR, etc.) \n- inStock: boolean \n- stockLevel: string (\"In Stock\", \"Low Stock\", \"Out of Stock\", \"Limited\", etc.) \n- rating: number (0-5 scale) \n- reviewCount: number \n- lastUpdated: string (current ISO timestamp) \n- productUrl: string (from context) \n- competitorName: string (from context)\n\nOutput only the JSON object—no notes, comments, or formatting.\n"}]}},"typeVersion":1},{"id":"e5998861-2d29-4fdb-a5c0-445cf79ac50e","name":"🔀 Merge Current with Historical","type":"n8n-nodes-base.merge","notes":"Combines current scrape with historical data for comparison","position":[-1024,176],"parameters":{"numberInputs":3},"typeVersion":3},{"id":"6815d6c1-43c5-49a8-8f41-eafa0ee83363","name":"📊 Read Historical Data","type":"n8n-nodes-base.googleSheets","notes":"Loads previous scan data for comparison","position":[-624,352],"parameters":{"options":{},"sheetName":{"mode":"name","value":"Historical Data"},"documentId":{"__rl":true,"mode":"id","value":"={{ $env.GOOGLE_SHEET_ID }}"}},"typeVersion":4.7},{"id":"0c300e39-74da-4947-ab75-1360158f48a1","name":"📝 Log Alert Details","type":"n8n-nodes-base.googleSheets","notes":"Logs all alerts to separate tracking sheet","position":[-48,160],"parameters":{"columns":{"value":{"rating":"={{ $json.rating }}","timestamp":"={{ $json.scrapedAt }}","alertLevel":"={{ $json.alertLevel }}","productUrl":"={{ $json.productUrl }}","stockLevel":"={{ $json.stockLevel }}","priceChange":"={{ $json.priceChange || 0 }}","productName":"={{ $json.productName }}","currentPrice":"={{ $json.currentPrice }}","previousPrice":"={{ $json.previousPrice || 'N/A' }}","changesSummary":"={{ $json.changesSummary }}","competitorName":"={{ $json.competitorName }}","priceChangePercent":"={{ $json.priceChangePercent || 0 }}"},"mappingMode":"defineBelow"},"options":{},"operation":"append","sheetName":{"mode":"name","value":"Alert Log"},"documentId":{"__rl":true,"mode":"id","value":"={{ $env.GOOGLE_SHEET_ID }}"}},"typeVersion":4.7},{"id":"1833ee8f-13ca-40f3-a3ce-e7c09bbff5fc","name":"Send a text message","type":"n8n-nodes-base.telegram","position":[112,240],"webhookId":"ae976d33-11d1-4d92-9289-fc86a1525828","parameters":{"text":"The competitors’ pricing has been finalized.","additionalFields":{}},"typeVersion":1.2},{"id":"864886e9-21d0-402f-8f1f-46216a5e1373","name":"Pause the workflow to let the Apify scraping task finish","type":"n8n-nodes-base.wait","position":[-1424,272],"webhookId":"426f22d5-31db-4344-ae7a-13dedfc46bf4","parameters":{"amount":25},"typeVersion":1.1}],"active":false,"settings":{"executionOrder":"v1"},"connections":{"Split Out":{"main":[[{"node":"🔀 Merge Current with Historical","type":"main","index":0}]]},"Message a model":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Get Results Apify":{"main":[[{"node":"🔀 Merge Current with Historical","type":"main","index":2}]]},"Start Actor Apify":{"main":[[{"node":"Pause the workflow to let the Apify scraping task finish","type":"main","index":0}]]},"📝 Log Alert Details":{"main":[[{"node":"Send a text message","type":"main","index":0}]]},"⏰ Monitor Every 6 Hours":{"main":[[{"node":"📊 Read Historical Data","type":"main","index":0}]]},"📊 Read Historical Data":{"main":[[{"node":"🔀 Merge Current with Historical1","type":"main","index":1}]]},"💾 Update Historical Data1":{"main":[[{"node":"Send a text message","type":"main","index":0}]]},"Scrape a url and get its content":{"main":[[{"node":"🔀 Merge Current with Historical","type":"main","index":1}]]},"🔀 Merge Current with Historical":{"main":[[{"node":"🤖 AI Extract Product Data using Claude-Sonnet 4.5","type":"main","index":0}]]},"🔍 Detect Price & Stock Changes1":{"main":[[{"node":"💾 Update Historical Data1","type":"main","index":0},{"node":"📝 Log Alert Details","type":"main","index":0}]]},"🔀 Merge Current with Historical1":{"main":[[{"node":"🔍 Detect Price & Stock Changes1","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Message a model","type":"main","index":0},{"node":"Scrape a url and get its content","type":"main","index":0},{"node":"Start Actor Apify","type":"main","index":0}]]},"🤖 AI Extract Product Data using Claude-Sonnet 4.5":{"main":[[{"node":"Converts unstructured AI text into organized, usable data fields","type":"main","index":0}]]},"Pause the workflow to let the Apify scraping task finish":{"main":[[{"node":"Get Results Apify","type":"main","index":0}]]},"Converts unstructured AI text into organized, usable data fields":{"main":[[{"node":"🔀 Merge Current with Historical1","type":"main","index":0}]]}}}