AutomationFlowsSlack & Telegram › Create Personalized Loom Video Scripts From Upwork Jobs with Claude AI

Create Personalized Loom Video Scripts From Upwork Jobs with Claude AI

ByNitin Garg @nitin-animoautomation on n8n.io

This n8n template transforms Upwork job postings into personalized Loom video outreach assets in under 60 seconds. Paste a job description and get a complete outreach package: video script, before/after comparison, automation flow diagram, and proposal snippet.

Event trigger★★★★☆ complexity17 nodesForm TriggerHTTP RequestGoogle DocsGoogle SheetsSlack
Slack & Telegram Trigger: Event Nodes: 17 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #11965 — we link there as the canonical source.

This workflow follows the Form Trigger → Google Docs recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "9eoFUHt3yUATmT3L",
  "name": "Generate Loom Outreach Assets from Upwork Jobs with AI",
  "tags": [],
  "nodes": [
    {
      "id": "c00dda7f-3584-4645-ad1e-39c7fcb0ca85",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -32
      ],
      "parameters": {
        "color": 4,
        "width": 380,
        "height": 892,
        "content": "## Generate Loom Outreach Assets from Upwork Jobs with AI\n\nThis workflow transforms Upwork job postings into personalized Loom video outreach assets in ~60 seconds. Paste a job description and get a complete outreach package.\n\n### How it works\n1. **Submit job** via web form (title, description, client name)\n2. **AI analyzes** the job - extracts industry, pain points, tools, budget/urgency signals\n3. **AI generates** complete Loom script, before/after comparison, flow diagram, proposal snippet\n4. **Saves** all assets to Google Doc, logs lead to Sheets, notifies via Slack\n\n### Setup\n\u2610 Add **Anthropic API** credential (HTTP Header Auth, header: `x-api-key`)\n\u2610 Add **Google Docs** and **Google Sheets** OAuth2 credentials\n\u2610 Add **Slack API** credential\n\u2610 Update `Create Output Doc` \u2192 Set your Google Drive folder ID\n\u2610 Update `Log Lead to Sheets` \u2192 Set your spreadsheet ID\n\u2610 Update both Slack nodes \u2192 Set your channel ID\n\u2610 Create Sheet with columns: Timestamp | Prospect Name | Industry | Business Function | Pain Point | Tokens Used | Google Doc Link | Version\n\n### Customize\n- Edit \"MY BACKGROUND\" in `Generate Loom Script with AI` node\n- Adjust industry hourly rates and time savings\n- Modify pricing guidance and CTA"
      },
      "typeVersion": 1
    },
    {
      "id": "e382b039-9b3e-4b27-ad68-ea05571d4abb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        -32
      ],
      "parameters": {
        "width": 200,
        "height": 296,
        "content": "## 1. Capture Job\nUser submits Upwork job details via web form"
      },
      "typeVersion": 1
    },
    {
      "id": "b04631c8-2602-47d2-9f3c-0fce11fd4cd9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        -32
      ],
      "parameters": {
        "width": 588,
        "height": 296,
        "content": "## 2. Analyze  Upwork Job Description\nClaude extracts industry, pain points, tools, budget & urgency signals"
      },
      "typeVersion": 1
    },
    {
      "id": "d8e55aa9-696a-4df0-b7e1-62107ec83064",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        -32
      ],
      "parameters": {
        "width": 396,
        "height": 296,
        "content": "## 3. Generate Assets\nClaude creates Loom script, before/after, flow diagram, proposal snippet"
      },
      "typeVersion": 1
    },
    {
      "id": "47bc46da-3112-422e-8bfb-0ccdeef39162",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        -32
      ],
      "parameters": {
        "width": 792,
        "height": 296,
        "content": "## 4. Save & Notify\nSaves to Google Doc, logs to Sheets, sends Slack notification"
      },
      "typeVersion": 1
    },
    {
      "id": "0363eed7-2506-4e2a-99c8-5051eef8d720",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1216,
        304
      ],
      "parameters": {
        "color": 6,
        "width": 296,
        "height": 280,
        "content": "## Error Path\nNotifies via Slack if job parsing fails"
      },
      "typeVersion": 1
    },
    {
      "id": "61efa1e3-ff44-43d6-8390-e5f32256242c",
      "name": "Job Intake Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        368,
        96
      ],
      "parameters": {
        "path": "upwork-loom-generator",
        "options": {
          "respondWithOptions": {
            "values": {
              "formSubmittedText": "\u2705 Analyzing job description... Assets will be ready in ~45 seconds. Check Slack!"
            }
          }
        },
        "formTitle": "Upwork Job \u2192 Loom Assets",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Job Title",
              "placeholder": "e.g., Need Notion CRM Expert for Pipeline Automation",
              "requiredField": true
            },
            {
              "fieldLabel": "Client Name (if known)",
              "placeholder": "e.g., John or leave blank if not visible"
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Job Description",
              "placeholder": "Paste the full Upwork job description here...",
              "requiredField": true
            },
            {
              "fieldLabel": "Upwork Job URL (Optional)",
              "placeholder": "https://www.upwork.com/jobs/..."
            }
          ]
        },
        "formDescription": "Paste an Upwork job description and generate personalized Loom outreach assets automatically."
      },
      "typeVersion": 2.1
    },
    {
      "id": "638d92f9-11d8-46d4-a287-b3971f14415c",
      "name": "Analyze Job with AI",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        624,
        96
      ],
      "parameters": {
        "url": "https://api.anthropic.com/v1/messages",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ (() => {\n  const jobTitle = ($json['Job Title'] || '').replace(/[\\n\\r]/g, ' ').replace(/\"/g, \"'\").trim();\n  const clientName = ($json['Client Name (if known)'] || '').replace(/[\\n\\r]/g, ' ').replace(/\"/g, \"'\").trim();\n  const jobDescription = ($json['Job Description'] || '').replace(/[\\n\\r]/g, ' ').replace(/\"/g, \"'\").trim();\n  const jobUrl = $json['Upwork Job URL (Optional)'] || '';\n\n  const prompt = `You are an expert at analyzing Upwork job postings to identify automation opportunities.\n\nAnalyze this job description and extract structured data for a cold outreach Loom video.\n\n## JOB DETAILS\nTitle: ${jobTitle}\nClient Name: ${clientName || 'Not provided'}\nJob URL: ${jobUrl || 'Not provided'}\n\n## FULL JOB DESCRIPTION\n${jobDescription}\n\n## YOUR TASK\nExtract the following information. Be specific and actionable.\n\n## EXTRACTION RULES\n1. Industry: Infer from the job description. Choose the BEST match from:\n   - Recruiting / Staffing\n   - MSP / IT Services\n   - Coaching / Consulting\n   - Accounting / Bookkeeping\n   - Marketing Agency\n   - Real Estate\n   - Healthcare\n   - E-commerce\n   - Legal Services\n   - Investment / M&A\n   - Professional Services\n   - Other (specify)\n\n2. Business Function: What do they primarily need automated? Choose BEST match:\n   - CRM / Pipeline Management\n   - Lead Management / Sales Pipeline\n   - Accounts Receivable / Invoicing\n   - Customer Support / Ticketing\n   - Client Onboarding\n   - Document Generation / Processing\n   - Email / Communication Automation\n   - Reporting / Dashboards\n   - Workflow / Process Automation\n   - Data Integration / Sync\n   - Other (specify)\n\n3. Pain Points: List the specific problems they mention or imply (bullet points)\n\n4. Tools Mentioned: List any specific tools/platforms mentioned\n\n5. Automation Opportunities: What specific automations could you build for them?\n\n6. Prospect Name: Use client name if provided, otherwise use a professional placeholder\n\n7. Hook Angle: What specific pain or desire should the Loom video address first?\n\n8. Budget Signal: Any indication of budget (budget mentioned, hourly rate, project complexity)\n\n9. Urgency Signal: Any indication of timeline urgency?\n\n10. Competition Risk: Is this a job many people will apply to? (High/Medium/Low)\n\n## RESPOND IN THIS EXACT JSON FORMAT (no markdown, no code blocks):\n{\n  \"prospect_name\": \"[Client name or 'Upwork Client']\",\n  \"industry\": \"[Best match industry]\",\n  \"business_function\": \"[Primary function to automate]\",\n  \"pain_point\": \"[Main pain point - 1-2 sentences max]\",\n  \"pain_points_detailed\": [\"pain 1\", \"pain 2\", \"pain 3\"],\n  \"tools_mentioned\": [\"tool1\", \"tool2\"],\n  \"tools_string\": \"[Comma-separated tools or 'Not specified']\",\n  \"automation_opportunities\": [\"opportunity 1\", \"opportunity 2\", \"opportunity 3\"],\n  \"hook_angle\": \"[Specific angle for Loom opening]\",\n  \"budget_signal\": \"[Low/Medium/High/Unknown]\",\n  \"urgency_signal\": \"[Low/Medium/High/Unknown]\",\n  \"competition_risk\": \"[Low/Medium/High]\",\n  \"job_title\": \"${jobTitle}\",\n  \"job_url\": \"${jobUrl}\",\n  \"recommended_approach\": \"[1-2 sentence strategy for this specific job]\"\n}\n\nRespond with ONLY the JSON object. No explanations, no markdown formatting.`;\n\n  return JSON.stringify({\n    model: \"claude-sonnet-4-20250514\",\n    max_tokens: 1500,\n    messages: [\n      {\n        role: \"user\",\n        content: prompt\n      }\n    ]\n  });\n})() }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "085b850d-1a50-4bbd-a872-a4c403f98ce6",
      "name": "Validate AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        816,
        96
      ],
      "parameters": {
        "jsCode": "// Parse the job description analysis from Claude\nconst item = $input.first().json;\n\ntry {\n  // Get the text content from Claude response\n  let responseText = '';\n  if (item.content && item.content[0] && item.content[0].text) {\n    responseText = item.content[0].text;\n  } else {\n    throw new Error('No content in Claude response');\n  }\n  \n  // Clean up the response (remove any markdown formatting if present)\n  responseText = responseText.trim();\n  if (responseText.startsWith('```json')) {\n    responseText = responseText.replace(/```json\\n?/, '').replace(/\\n?```$/, '');\n  } else if (responseText.startsWith('```')) {\n    responseText = responseText.replace(/```\\n?/, '').replace(/\\n?```$/, '');\n  }\n  \n  // Parse the JSON\n  const parsed = JSON.parse(responseText);\n  \n  // Validate required fields\n  const required = ['prospect_name', 'industry', 'business_function', 'pain_point'];\n  for (const field of required) {\n    if (!parsed[field]) {\n      throw new Error(`Missing required field: ${field}`);\n    }\n  }\n  \n  return [{\n    json: {\n      valid: true,\n      prospect_name: parsed.prospect_name,\n      industry: parsed.industry,\n      business_function: parsed.business_function,\n      pain_point: parsed.pain_point,\n      pain_points_detailed: parsed.pain_points_detailed || [],\n      known_tools: parsed.tools_string || 'Not specified',\n      tools_array: parsed.tools_mentioned || [],\n      automation_opportunities: parsed.automation_opportunities || [],\n      hook_angle: parsed.hook_angle || parsed.pain_point,\n      budget_signal: parsed.budget_signal || 'Unknown',\n      urgency_signal: parsed.urgency_signal || 'Unknown',\n      competition_risk: parsed.competition_risk || 'Medium',\n      job_title: parsed.job_title || 'Upwork Job',\n      job_url: parsed.job_url || '',\n      recommended_approach: parsed.recommended_approach || '',\n      source: 'Upwork',\n      timestamp: new Date().toISOString()\n    }\n  }];\n  \n} catch (error) {\n  return [{\n    json: {\n      valid: false,\n      error: error.message,\n      raw_response: item.content ? item.content[0].text : 'No response'\n    }\n  }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "2b94b54a-8588-46d7-a730-d94110265316",
      "name": "Analysis Valid?",
      "type": "n8n-nodes-base.if",
      "position": [
        992,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "valid-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.valid }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ae4dcd7a-c239-4569-88e1-45d6826210c9",
      "name": "Generate Loom Script with AI",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1232,
        80
      ],
      "parameters": {
        "url": "https://api.anthropic.com/v1/messages",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ (() => {\n  const prospectName = $json.prospect_name || 'Prospect';\n  const industry = $json.industry || 'Business';\n  const businessFunction = $json.business_function || 'Operations';\n  const painPoint = ($json.pain_point || '').replace(/[\\n\\r]/g, ' ').replace(/\"/g, \"'\").trim();\n  const knownTools = ($json.known_tools || 'their current systems').replace(/[\\n\\r]/g, ' ').replace(/\"/g, \"'\").trim();\n  const hookAngle = ($json.hook_angle || painPoint).replace(/[\\n\\r]/g, ' ').replace(/\"/g, \"'\").trim();\n  const automationOpps = ($json.automation_opportunities || []).join(', ');\n\n  const prompt = `You are helping me create assets for a cold outreach Loom video to an Upwork prospect.\n\n## INTERNAL REASONING (Do this first, but do NOT include in output)\nBefore generating:\n1. This is an UPWORK JOB - they are actively looking for help\n2. Identify the High-Value Friction Point for this industry\n3. Design the automation to specifically solve their stated needs\n4. Ensure the Before process feels tedious and manual\n5. Ensure the After process feels like exactly what they asked for\n6. Use vocabulary specific to their industry\n7. Apply INDUSTRY-SPECIFIC time savings and hourly rates\n8. Frame ROI as BOTH time recovered AND problem solved\n9. Remember: This person POSTED A JOB - they want solutions\n\n## INDUSTRY-SPECIFIC PARAMETERS\n\n### Time Savings by Industry:\n- Recruiting/Staffing: 5-8 hours/week\n- MSP/IT Services: 4-6 hours/week\n- Coaching/Consulting: 2-4 hours/week\n- Accounting/Bookkeeping: 3-5 hours/week\n- Marketing Agency: 4-6 hours/week\n- Investment/M&A: 4-6 hours/week\n- Professional Services: 3-5 hours/week\n- Other: 4-6 hours/week\n\n### Hourly Value by Industry:\n- Recruiting/Staffing: $75/hour\n- MSP/IT Services: $100/hour\n- Coaching/Consulting: $75/hour\n- Accounting/Bookkeeping: $50/hour\n- Marketing Agency: $75/hour\n- Investment/M&A: $150/hour\n- Professional Services: $75/hour\n- Other: $50/hour\n\n## PROSPECT DETAILS (FROM UPWORK JOB)\n- Name/Company: ${prospectName}\n- Industry: ${industry}\n- Business function: ${businessFunction}\n- Their main problem: ${painPoint}\n- Hook angle: ${hookAngle}\n- Tools they mentioned: ${knownTools}\n- Specific things they want: ${automationOpps}\n\n## MY BACKGROUND (CUSTOMIZE THIS SECTION)\n- [Your years of experience and expertise]\n- [Your specialization or unique approach]\n- [Key differentiator - e.g., no monthly fees, enterprise methodology, etc.]\n- [Why you're uniquely qualified to help]\n\n## CONSTRAINTS\n- Use EXACTLY: 1 Trigger \u2192 4 Process Steps \u2192 1 Output\n- Time saved: Use INDUSTRY-SPECIFIC ranges\n- ROI: Use INDUSTRY-SPECIFIC hourly rates\n- This is UPWORK - mention you saw their job posting\n- Be specific to what THEY asked for in their job description\n- Keep language conversational and non-technical\n\n## GENERATE THE FOLLOWING:\n\n---\n\n## 1. AUTOMATION FLOW DIAGRAM\n\n[TRIGGER] \u2192 [STEP 1] \u2192 [STEP 2] \u2192 [STEP 3] \u2192 [STEP 4] \u2192 [OUTPUT]\n\nExpand each box with bullets. Make it SPECIFIC to what they asked for.\n\n**Estimated time saved**: [Industry-specific range] hours per week\n\n---\n\n## 2. BEFORE vs AFTER\n\n### BEFORE (Manual Process)\n- Step 1-4: What they described as their current pain\n- **Time spent**: [X] hours/week\n- **Problems**: [From their job description]\n\n### AFTER (Automated)\n- Step 1-4: Specifically what they asked for\n- **Time spent**: [X] minutes/week\n- **Result**: [What they said they wanted]\n\n---\n\n## 3. WHY THIS MATTERS\n\n[One sentence connecting to their SPECIFIC job posting and pain points]\n\n---\n\n## 4. LOOM SCRIPT (90-120 seconds)\n\n**[HOOK - 10 seconds]**\n\"Hey ${prospectName}, I saw your Upwork post about ${hookAngle}. This is exactly the kind of system I specialize in building.\"\n\n**[CREDIBILITY - 12 seconds]**\n\"[Your background/credibility statement]\"\n\n**[TRANSITION - 5 seconds]**\n\"Let me show you exactly what Id build for you.\"\n\n**[FLOW WALKTHROUGH - 50 seconds]**\n[Walk through the flow, specifically addressing what they asked for]\n\n**[OBJECTION HANDLER - 8 seconds]**\n[Address their most likely concern based on job description]\n\n**[BEFORE/AFTER + ROI - 12 seconds]**\n[Show transformation with industry-specific numbers]\n\n**[CTA - 10 seconds]**\n\"Id love to chat more about this. If youre interested, just reply here on Upwork or hit the 'Hire' button and we can set up a quick call to discuss the specifics. Talk soon.\"\n\n---\n\n## 5. UPWORK PROPOSAL SNIPPET\n\nWrite a 2-3 sentence opening for an Upwork proposal that:\n- Shows I read their job description carefully\n- Mentions a specific thing from their post\n- Positions my background as relevant\n- Invites them to watch the Loom video\n\n---\n\n## 6. VISUAL PROMPTS FOR WHIMSICAL/FIGMA\n\n### 6A. BEFORE FLOW PROMPT:\n[Customized to their specific manual process]\n\n### 6B. AFTER FLOW PROMPT:\n[Customized to what they asked for]\n\n---\n\n## 7. QUICK REFERENCE CARD\n\n**One-liner pitch:** [Specific to their job]\n\n**Key stats:**\n- Time saved: [Industry range]\n- Dollar value: [Industry rate calculation]\n- Implementation: ~2 weeks\n- Ongoing fees: [Your pricing model]\n\n**Pricing guidance:**\n- For fixed-price: [Your range]\n- For hourly: [Your range]\n- Include: [What's included]\n\n---\n\nGenerated by Loom Asset Generator`;\n\n  return JSON.stringify({\n    model: \"claude-sonnet-4-20250514\",\n    max_tokens: 4500,\n    messages: [\n      {\n        role: \"user\",\n        content: prompt\n      }\n    ]\n  });\n})() }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "cf5a5fef-c10d-43f7-8e89-30e4f57d4d8d",
      "name": "Structure Generated Content",
      "type": "n8n-nodes-base.code",
      "position": [
        1424,
        80
      ],
      "parameters": {
        "jsCode": "// Parse the generated assets from Claude\nconst item = $input.first().json;\nconst inputData = $('Validate AI Response').first().json;\n\ntry {\n  let generatedContent = '';\n  let tokensUsed = 0;\n  \n  if (item.content && item.content[0] && item.content[0].text) {\n    generatedContent = item.content[0].text;\n  }\n  \n  if (item.usage) {\n    tokensUsed = (item.usage.input_tokens || 0) + (item.usage.output_tokens || 0);\n  }\n  \n  return [{\n    json: {\n      prospect_name: inputData.prospect_name,\n      industry: inputData.industry,\n      business_function: inputData.business_function,\n      pain_point: inputData.pain_point,\n      known_tools: inputData.known_tools,\n      hook_angle: inputData.hook_angle,\n      job_title: inputData.job_title,\n      job_url: inputData.job_url,\n      budget_signal: inputData.budget_signal,\n      urgency_signal: inputData.urgency_signal,\n      competition_risk: inputData.competition_risk,\n      recommended_approach: inputData.recommended_approach,\n      automation_opportunities: inputData.automation_opportunities,\n      generated_content: generatedContent,\n      tokens_used: tokensUsed,\n      source: 'Upwork',\n      timestamp: inputData.timestamp\n    }\n  }];\n  \n} catch (error) {\n  return [{\n    json: {\n      error: error.message,\n      prospect_name: inputData.prospect_name || 'Unknown',\n      generated_content: 'Error generating content'\n    }\n  }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "5f47654d-211d-45dd-8dd1-3df730d385b0",
      "name": "Create Output Doc",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        1648,
        80
      ],
      "parameters": {
        "title": "={{ $('Structure Generated Content').item.json.prospect_name }} - Upwork Loom Assets",
        "folderId": "YOUR_GOOGLE_DRIVE_FOLDER_ID"
      },
      "typeVersion": 2
    },
    {
      "id": "0142f3d9-1b07-4a69-a409-6381b261432f",
      "name": "Add Content to Doc",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        1840,
        80
      ],
      "parameters": {
        "actionsUi": {
          "actionFields": [
            {
              "text": "={{ $('Structure Generated Content').item.json.generated_content }}",
              "action": "insert"
            }
          ]
        },
        "operation": "update",
        "documentURL": "={{ $('Create Output Doc').item.json.id }}"
      },
      "typeVersion": 2
    },
    {
      "id": "24870b1f-326e-4975-a00a-72181cabca98",
      "name": "Log Lead to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2016,
        80
      ],
      "parameters": {
        "columns": {
          "value": {
            "Version": "v2.2",
            "Industry": "={{ $('Structure Generated Content').item.json.industry }}",
            "Timestamp": "={{ $now.format('yyyy-MM-dd HH:mm:ss') }}",
            "Pain Point": "={{ $('Structure Generated Content').item.json.pain_point }}",
            "Tokens Used": "={{ $('Generate Loom Script with AI').item.json.usage.input_tokens + $('Generate Loom Script with AI').item.json.usage.output_tokens }}",
            "Prospect Name": "={{ $('Structure Generated Content').item.json.prospect_name }}",
            "Google Doc Link": "=https://docs.google.com/document/d/{{ $('Create Output Doc').item.json.id }}/edit",
            "Business Function": "={{ $('Structure Generated Content').item.json.business_function }}"
          },
          "schema": [
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Prospect Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Prospect Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Business Function",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Business Function",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pain Point",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pain Point",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tokens Used",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tokens Used",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Google Doc Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Google Doc Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Version",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Version",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Lead Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "d6387088-4838-49ed-a07b-6fec6364fc6c",
      "name": "Send Success Notification",
      "type": "n8n-nodes-base.slack",
      "position": [
        2192,
        80
      ],
      "parameters": {
        "text": "=\u2705 *Upwork Loom Assets Generated!*\n\n\ud83d\udccb *Job:* {{ $('Structure Generated Content').item.json.job_title }}\n\ud83d\udc64 *Prospect:* {{ $('Structure Generated Content').item.json.prospect_name }}\n\ud83c\udfe2 *Industry:* {{ $('Structure Generated Content').item.json.industry }}\n\ud83c\udfaf *Function:* {{ $('Structure Generated Content').item.json.business_function }}\n\n\ud83d\udcca *Signals:*\n\u2022 Budget: {{ $('Structure Generated Content').item.json.budget_signal }}\n\u2022 Urgency: {{ $('Structure Generated Content').item.json.urgency_signal }}\n\u2022 Competition: {{ $('Structure Generated Content').item.json.competition_risk }}\n\n\ud83d\udd17 *Google Doc:* https://docs.google.com/document/d/{{ $('Create Output Doc').item.json.id }}/edit\n\ud83d\udd17 *Job URL:* {{ $('Structure Generated Content').item.json.job_url || 'Not provided' }}\n\n\ud83d\udca1 *Recommended Approach:* {{ $('Structure Generated Content').item.json.recommended_approach }}\n\n\ud83d\udd22 Tokens used: {{ $('Structure Generated Content').item.json.tokens_used }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SLACK_CHANNEL_ID"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "029df60e-5820-4273-a0e2-1da4eed42324",
      "name": "Send Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        1248,
        400
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f *Job Description Parse Error*\n\nError: {{ $json.error }}\n\nRaw response:\n```{{ $json.raw_response }}```",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SLACK_CHANNEL_ID"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "2367a4cb-424e-4525-8918-b7b866beee3c",
  "connections": {
    "Analysis Valid?": {
      "main": [
        [
          {
            "node": "Generate Loom Script with AI",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Job Intake Form": {
      "main": [
        [
          {
            "node": "Analyze Job with AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Output Doc": {
      "main": [
        [
          {
            "node": "Add Content to Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Content to Doc": {
      "main": [
        [
          {
            "node": "Log Lead to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Lead to Sheets": {
      "main": [
        [
          {
            "node": "Send Success Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Job with AI": {
      "main": [
        [
          {
            "node": "Validate AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate AI Response": {
      "main": [
        [
          {
            "node": "Analysis Valid?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structure Generated Content": {
      "main": [
        [
          {
            "node": "Create Output Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Loom Script with AI": {
      "main": [
        [
          {
            "node": "Structure Generated Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This n8n template transforms Upwork job postings into personalized Loom video outreach assets in under 60 seconds. Paste a job description and get a complete outreach package: video script, before/after comparison, automation flow diagram, and proposal snippet.

Source: https://n8n.io/workflows/11965/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

Automatically detect when your champion contacts change companies and respond with intelligent, personalized AI outreach before your competitors do.

Google Sheets, @Exploriumai/N8N Nodes Explorium Ai, HTTP Request +1
Slack & Telegram

Expenses Tracker (video). Uses httpRequest, splitInBatches, googleSheets, googleDrive. Event-driven trigger; 21 nodes.

HTTP Request, Google Sheets, Google Drive +2
Slack & Telegram

Transform your lead list into an AI-powered calling machine. This workflow automates your entire cold calling process using Vapi's conversational AI to initiate calls, qualify leads, capture detailed

Google Sheets, HTTP Request, Slack
Slack & Telegram

Type in Slack. Walk away. Get a professional PDF report and a structured Excel fix sheet delivered to Google Drive and posted back in your Slack thread — fully automated, zero manual work.

Compression, HTTP Request, Google Drive +3
Slack & Telegram

This template monitors Google Drive folder for new files, extracts text from PDFs, images, text files, CSVs, and Google Docs., reads images with meta/llama-3.2-11b-vision-instruct, structures the resu

Google Drive Trigger, Google Drive, Google Docs +3