AutomationFlowsGeneral › AI Social Media Content Analyzer

AI Social Media Content Analyzer

Original n8n title: Code Http (http Request)

Code Http. Uses httpRequest, lmChatOpenAi, outputParserStructured, chainLlm. Event-driven trigger; 19 nodes.

Event trigger★★★★☆ complexityAI-powered19 nodesHTTP RequestOpenAI ChatOutput Parser StructuredChain LlmEmail SendGoogle Sheets TriggerGoogle Sheets
General Trigger: Event Nodes: 19 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Chainllm → Emailsend 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
{
  "nodes": [
    {
      "id": "a768bce6-ae26-464c-95fc-009edea4f94d",
      "name": "Set your company's variables",
      "type": "n8n-nodes-base.set",
      "position": [
        440,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "6a8063b6-1fd8-429a-9f13-b7512066c702",
              "name": "your_company_name",
              "type": "string",
              "value": "Pollup Data Services"
            },
            {
              "id": "3e6780d6-86d0-4353-aa17-8470a91f63a8",
              "name": "your_company_activity",
              "type": "string",
              "value": "Whether it\u2019s automating recurring tasks, analysing data faster, or personalising customer interactions, we build bespoke AI agents to help your workforce work smarter."
            },
            {
              "id": "1b42f1b3-20ed-4278-952d-f28fe0f03fa3",
              "name": "your_email",
              "type": "string",
              "value": "thomas@pollup.net"
            },
            {
              "id": "7c109ba2-d855-49d5-8700-624b01a05bc1",
              "name": "your_name",
              "type": "string",
              "value": "Justin"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ca729f8d-cab8-4221-addb-aa23813d80b4",
      "name": "Get linkedin Posts",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1300,
        0
      ],
      "parameters": {
        "url": "https://fresh-linkedin-profile-data.p.rapidapi.com/get-profile-posts",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "linkedin_url",
              "value": "={{ $('Google Sheets Trigger').item.json.linkedin_url }}"
            },
            {
              "name": "type",
              "value": "posts"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "fresh-linkedin-profile-data.p.rapidapi.com"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b9559958-f8ac-4ab6-93c6-50eb04113808",
      "name": "Get twitter ID",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        680,
        0
      ],
      "parameters": {
        "url": "https://twitter-api47.p.rapidapi.com/v2/user/by-username",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "username",
              "value": "={{ $('Google Sheets Trigger').item.json.twitter_handler }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "twitter-api47.p.rapidapi.com"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3e85565f-ebfa-4568-9391-869961c5b3ed",
      "name": "Get tweets",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        880,
        0
      ],
      "parameters": {
        "url": "https://twitter-api47.p.rapidapi.com/v2/user/tweets",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "userId",
              "value": "={{ $json.rest_id }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "twitter-api47.p.rapidapi.com"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6e060b21-9eaf-49e6-9665-c051b3f2397e",
      "name": "Extract and limit Linkedin",
      "type": "n8n-nodes-base.code",
      "position": [
        1520,
        0
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\noutput = []\nmax_posts = 10\nlet counter = 0\nfor (const item of $input.all()[0].json.data) {\n let post = {\n title: item.article_title,\n text: item.text\n }\n output.push(post)\n if(counter++ >= max_posts) break;\n}\n\nreturn {\"linkedIn posts\": output};"
      },
      "typeVersion": 2
    },
    {
      "id": "e65bc472-e7c6-43c5-8e84-fe8c4512e92f",
      "name": "Exract and limit X",
      "type": "n8n-nodes-base.code",
      "position": [
        1100,
        0
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\noutput = []\nmax_posts = 10\nlet counter = 0\nfor (const item of $input.all()[0].json.tweets) {\n if(!item.content.hasOwnProperty('itemContent')) continue\n let post = {\n text: item.content.itemContent?.tweet_results?.result.legacy?.full_text\n }\n console.log(post)\n output.push(post)\n if(counter++ >= max_posts) break;\n}\n\nreturn {\"Twitter tweets\": output};"
      },
      "typeVersion": 2
    },
    {
      "id": "10f088a0-0479-428e-96cf-fe0df9b37877",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1740,
        200
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9adfd648-8348-4a0a-8b9b-d54dc3b715bb",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1920,
        220
      ],
      "parameters": {
        "jsonSchemaExample": "{\n \"subject\": \"\",\n \"cover_letter\": \"\"\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "af96003c-539d-4728-832c-4819d85bbbcc",
      "name": "Generate Subject and cover letter based on match",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1720,
        0
      ],
      "parameters": {
        "text": "=## Me\n- My company name is: {{ $('Set your company\\'s variables').item.json.your_company_name }}\n- My company's activity is: {{ $('Set your company\\'s variables').item.json.your_company_activity }}\n- My name is: {{ $('Set your company\\'s variables').item.json.your_name }}\n- My email is: {{ $('Set your company\\'s variables').item.json.your_email }}\n\n## My lead:\nHis name: {{ $('Google Sheets Trigger').item.json.name }}\n\n## What I want you to do\n- According to the info about me, and the linkedin posts an twitter post of a user given below, I want you to find a common activity that I could propose to this person and generate a cover letter about it\n- Return ONLY the cover letter and the subject as a json like this:\n{\n \"subject\": \"\",\n \"cover_letter\": \"\"\n}\n\nTHe cover letter should be in HTML format\n\n## The Linkedin Posts:\n{{ JSON.stringify($json[\"linkedIn posts\"])}}\n\n## THe Twitter posts:\n{{ JSON.stringify($('Exract and limit X').item.json['Twitter tweets']) }}\n",
        "messages": {
          "messageValues": [
            {
              "message": "You are a helpful Marketing assistant"
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.5
    },
    {
      "id": "6954285f-7ea5-4e3d-8be2-03051d716d03",
      "name": "Send Cover letter and CC me",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        2080,
        0
      ],
      "parameters": {
        "html": "={{ $json.output.cover_letter }}",
        "options": {},
        "subject": "={{ $json.output.subject }}",
        "toEmail": "={{ $('Google Sheets Trigger').item.json.email }}, {{ $('Set your company\\'s variables').item.json.your_email }}",
        "fromEmail": "thomas@pollup.net"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "357477a8-98c3-48a5-8c88-965f90a4beb2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        360,
        -280
      ],
      "parameters": {
        "color": 4,
        "height": 480,
        "content": "## Personalize here\n\n### Set: \n- your name\n- your company name\n- your company activity, used to find a match with your leads\n- your email, used as the sender"
      },
      "typeVersion": 1
    },
    {
      "id": "0c26383c-c8f1-44b1-995e-2c88118061bb",
      "name": "Google Sheets Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -40,
        20
      ],
      "parameters": {
        "options": {
          "dataLocationOnSheet": {
            "values": {
              "rangeDefinition": "specifyRange"
            }
          }
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IcvbbG_WScVNyutXhzqyE9NxdxNbY90Dd63R8Y1UrAw/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1IcvbbG_WScVNyutXhzqyE9NxdxNbY90Dd63R8Y1UrAw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IcvbbG_WScVNyutXhzqyE9NxdxNbY90Dd63R8Y1UrAw/edit?usp=drivesdk",
          "cachedResultName": "Analyze social media of a lead"
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "923cca3d-69a9-4d26-80a3-e9062d42d8a8",
      "name": "Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2280,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "done": "X",
            "linkedin_url": "={{ $('Google Sheets Trigger').item.json.linkedin_url }}"
          },
          "schema": [
            {
              "id": "linkedin_url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "linkedin_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "twitter_handler",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "twitter_handler",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "done",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "done",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "linkedin_url"
          ]
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IcvbbG_WScVNyutXhzqyE9NxdxNbY90Dd63R8Y1UrAw/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1IcvbbG_WScVNyutXhzqyE9NxdxNbY90Dd63R8Y1UrAw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IcvbbG_WScVNyutXhzqyE9NxdxNbY90Dd63R8Y1UrAw/edit?usp=drivesdk",
          "cachedResultName": "Analyze social media of a lead"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "6df02119-09db-4d87-b435-7753693b27aa",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        180,
        20
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3839b337-6c33-4907-ba75-8ef04cefc14c",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.done }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "executeOnce": false,
      "typeVersion": 2.2,
      "alwaysOutputData": true
    },
    {
      "id": "2edaa85e-ef69-490c-9835-cf8779cada6d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        -320
      ],
      "parameters": {
        "color": 4,
        "width": 260,
        "height": 500,
        "content": "## Create a Gooogle sheet with the following columns:\n- linkedin_url\n- name\n- twitter_handler \n- email\n- done\n\nAnd put some data in it except in \"done\" that should remain empty."
      },
      "typeVersion": 1
    },
    {
      "id": "19210bba-1db1-4568-b34e-4e9de002b0eb",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1680,
        -160
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 300,
        "content": "## Here you can modify the prompt\n- make it better by adding some examples\n- Follow a known framework\netc."
      },
      "typeVersion": 1
    },
    {
      "id": "bebab4e5-35fa-49b7-bb85-a85231c44389",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        660,
        -280
      ],
      "parameters": {
        "color": 4,
        "width": 340,
        "height": 480,
        "content": "## Call RapidAPI Twitter API Profile Data\nYou have to create an account in [RapidAPI](https://rapidapi.com/restocked-gAGxip8a_/api/twitter-api47) and subscribe to Twiiter API. With a free account you will be able to scrape 500 tweets / month.\nAfter your subscription you will have to choose as Generic Auth Type: Header Auth and then put as header name: \"x-rapidapi-key\" and the value given in the RapidAPI interface\n"
      },
      "typeVersion": 1
    },
    {
      "id": "42df4665-2d46-4020-938c-f082db6f09d0",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1220,
        -300
      ],
      "parameters": {
        "color": 4,
        "width": 280,
        "height": 480,
        "content": "## Call RapidAPI Fresh Linkedin Profile Data\nYou have to create an account in [RapidAPI](https://rapidapi.com) and subscribe to Fresh LinkedIn Profile Data. With a free account you will be able to scrape 100 profile / month.\nAfter your subscription you will have to choose as Generic Auth Type: Header Auth and then put as header name: \"x-rapidapi-key\" and the value given in the RapidAPI interface\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4a14febd-bd82-428c-8c97-15f1ba724b02",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -840,
        -620
      ],
      "parameters": {
        "width": 700,
        "height": 1180,
        "content": "## Social Media Analysis and Automated Email Generation\n\n> by Thomas Vie [Thomas@pollup.net](mailto:thomas@pollup.net)\n\n### **Who is this for?**\nThis template is ideal for marketers, lead generation specialists, and business professionals seeking to analyze social media profiles of potential leads and automate personalized email outreach efficiently.\n\n\n### **What problem is this workflow solving?**\nManually analyzing social media profiles and crafting personalized emails can be time-consuming and prone to errors. This workflow streamlines the process by integrating social media APIs with AI to generate tailored communication, saving time and increasing outreach effectiveness.\n\n### **What this workflow does:**\n1. **Google Sheets Integration:** Start with a Google Sheet containing lead information such as LinkedIn URL, Twitter handle, name, and email.\n2. **Social Media Data Extraction:** Automatically fetch profile and activity data from Twitter and LinkedIn using RapidAPI integrations.\n3. **AI-Powered Content Generation:** Use OpenAI's Chat Model to analyze the extracted data and generate personalized email subject lines and cover letters.\n4. **Automated Email Dispatch:** Send the generated email directly to the lead, with a copy sent to yourself for tracking purposes.\n5. **Progress Tracking:** Update the Google Sheet to indicate completed actions.\n\n#### **Setup:**\n1. **Google Sheets:**\n - Create a sheet with the columns: LinkedIn URL, name, Twitter handle, email, and a \"done\" column for tracking.\n - Populate the sheet with your leads.\n\n2. **RapidAPI Accounts:**\n - Sign up for RapidAPI and subscribe to the Twitter and LinkedIn API plans.\n - Configure API authentication keys in the workflow.\n\n3. **AI Configuration:**\n - Connect OpenAI Chat Model with your API key for text generation.\n\n4. **Email Integration:**\n - Add your email credentials or service (SMTP or third-party service like Gmail) for sending automated emails.\n\n#### **How to customize this workflow to your needs:**\n- **Modify the AI Prompt:** Adapt the prompt in the AI node to better align with your tone, style, or specific messaging framework.\n- **Expand Data Fields:** Add additional data fields in Google Sheets if you require further personalization.\n- **API Limits:** Adjust API configurations to fit your usage limits or upgrade to higher tiers for increased data scraping capabilities.\n- **Personalize Email Templates:** Tweak email formats to suit different audiences or use cases.\n- **Extend Functionality:** Integrate additional social media platforms or CRM tools as needed.\n\nBy implementing this workflow, you\u2019ll save time on repetitive tasks and create more effective lead generation strategies."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Set your company's variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get tweets": {
      "main": [
        [
          {
            "node": "Exract and limit X",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets": {
      "main": [
        []
      ]
    },
    "Get twitter ID": {
      "main": [
        [
          {
            "node": "Get tweets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Subject and cover letter based on match",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Exract and limit X": {
      "main": [
        [
          {
            "node": "Get linkedin Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get linkedin Posts": {
      "main": [
        [
          {
            "node": "Extract and limit Linkedin",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Subject and cover letter based on match",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extract and limit Linkedin": {
      "main": [
        [
          {
            "node": "Generate Subject and cover letter based on match",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Cover letter and CC me": {
      "main": [
        [
          {
            "node": "Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set your company's variables": {
      "main": [
        [
          {
            "node": "Get twitter ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Subject and cover letter based on match": {
      "main": [
        [
          {
            "node": "Send Cover letter and CC me",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

How this works

This workflow automates the extraction and analysis of social media content from LinkedIn and X (formerly Twitter), using AI to summarise key insights and generate structured reports, saving hours of manual data gathering for marketing teams or analysts. It fetches recent posts and tweets via HTTP requests, processes them with code nodes to extract and limit relevant items, then leverages OpenAI's chat model alongside a structured output parser to produce concise, actionable summaries. Ideal for professionals monitoring brand mentions or competitor activity, it delivers value through quick, AI-enhanced intelligence without needing advanced coding skills.

Use this workflow for periodic social media audits or real-time event-driven monitoring, such as tracking campaign performance across platforms. Avoid it for high-volume data needs exceeding API limits, or when deeper sentiment analysis beyond basic summarisation is required—opt for dedicated tools like Google Sheets integration for spreadsheet exports instead. Common variations include adding email notifications for alerts or customising the AI prompts for industry-specific insights.

About this workflow

Code Http. Uses httpRequest, lmChatOpenAi, outputParserStructured, chainLlm. Event-driven trigger; 19 nodes.

Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

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

General

Code Http. Uses httpRequest, lmChatOpenAi, outputParserStructured, chainLlm. Event-driven trigger; 19 nodes.

HTTP Request, OpenAI Chat, Output Parser Structured +4
General

YouTube Video Analyzer with AI. Uses manualTrigger, lmChatOpenAi, lmChatOpenRouter, lmChatDeepSeek. Event-driven trigger; 21 nodes.

OpenAI Chat, OpenRouter Chat, Lm Chat Deep Seek +4
General

Converttofile Http. Uses lmChatOpenAi, googleSheets, httpRequest, openAi. Event-driven trigger; 18 nodes.

OpenAI Chat, Google Sheets, HTTP Request +3
General

HR-focused automation pipeline with AI. Uses formTrigger, extractFromFile, informationExtractor, chainSummarization. Event-driven trigger; 18 nodes.

Form Trigger, Information Extractor, Chain Summarization +5
General

Automated Resume Review System Using OpenAI + Google Sheets. Uses formTrigger, outputParserStructured, googleSheets, informationExtractor. Event-driven trigger; 17 nodes.

Form Trigger, Output Parser Structured, Google Sheets +5