n8n Workflow
Advanced

Twitter Sentiment Analysis ETL with Slack Notifications

Automate a daily ETL process: extract tweets, analyze sentiment with Google Cloud Natural Language, store results in MongoDB and Postgres, and send Slack notifications.

Overview

Build a daily automated ETL pipeline to extract tweets, perform sentiment analysis with Google NLP, load the data into PostgreSQL and MongoDB, and alert your team on Slack for positive-sentiment tweets.

🧠 Description & Use Case

This workflow demonstrates a complete ETL (Extract, Transform, Load) pipeline that automates social media sentiment analysis. It fetches tweets based on a specific hashtag, analyzes their sentiment using AI, stores the data in two different types of databases (MongoDB and PostgreSQL), and sends conditional notifications to a Slack channel.

This is a powerful tool for brand monitoring, campaign tracking, and market research, allowing you to automatically gauge public opinion and act on it.

🔄 How It Works:

  1. Trigger

    • The Cron node initiates the workflow every day at 6 AM.
  2. Extract: Fetch Tweets

    • The Twitter node searches for recent tweets containing the hashtag #OnThisDay.
  3. Load (Stage 1): Store Raw Data

    • The MongoDB node immediately saves the raw text of each tweet into a tweets collection. This creates a simple, unstructured data archive.
  4. Transform: Analyze Sentiment

    • The Google Cloud Natural Language node processes the tweet text to determine its emotional tone, generating a sentiment score and magnitude.
  5. Transform: Structure Data

    • The Set node combines the original tweet text with its new sentiment score and magnitude into a clean, structured format.
  6. Load (Stage 2): Store Enriched Data

    • The Postgres node inserts the structured, enriched data (tweet text, score, and magnitude) into a relational database table named tweets for easy querying and reporting.
  7. Filter & Notify

    • The IF node checks if the sentiment score is positive (greater than 0).
    • If true, the Slack node sends a formatted message to a designated channel, highlighting the positive tweet.
    • If false, the NoOp node ends the process for that tweet, taking no further action.

✅ Real-World Use Cases:

  • Brand Monitoring: Track public perception of your brand by analyzing tweets mentioning your company name or products.
  • Campaign Analysis: Measure the real-time sentiment of a marketing campaign by tracking its official hashtag.
  • Proactive Customer Support: Modify the workflow to flag negative tweets for immediate follow-up by your support team.
  • Market Research: Gather public opinion on a specific topic, event, or competitor to inform business strategy.
  • Data Warehousing: Build a robust data pipeline that collects data from an unstructured source (Twitter), enriches it with AI, and stores it in both a NoSQL (MongoDB) and a relational (PostgreSQL) database for different analytical needs.

Instructions

Basic steps

  1. Download workflow JSON
  2. Import into n8n
  3. Configure node parameters as needed
  4. Test and enable the workflow

💡 Tips

After importing, verify all connectors and credentials match your environment.

Preview

Workflow Visualization

9 nodes
100%
TwittertwitterPostgrespostgresMongoDBmongoDbSlackslackIFifNoOpnoOpGoogle Cloud Natural LanguagegoogleCloudNaturalLanguageSetsetCroncron

Nodes

1

Twitter

twitter

v1
2

Postgres

postgres

v1
3

MongoDB

mongoDb

v1
4

Slack

slack

v1
5

IF

if

v1
6

NoOp

noOp

v1
7

Google Cloud Natural Language

googleCloudNaturalLanguage

v1
8

Set

set

v1
9

Cron

cron

v1

Statistics

Total nodes:9
Disabled nodes:0
Node types:9
Connections:7
View full JSON structure
{
  "nodes": [
    {
      "name": "Twitter",
      "type": "n8n-nodes-base.twitter",
      "position": [
        300,
        300
      ],
      "parameters": {
        "limit": 3,
        "operation": "search",
        "searchText": "=#OnThisDay",
        "additionalFields": {}
      },
      "credentials": {
        "twitterOAuth1Api": "twitter_api"
      },
      "typeVersion": 1
    },
    {
      "name": "Postgres",
      "type": "n8n-nodes-base.postgres",
      "position": [
        1100,
        300
      ],
      "parameters": {
        "table": "tweets",
        "columns": "text, score, magnitude",
        "returnFields": "=*"
      },
      "credentials": {
        "postgres": "postgres"
      },
      "typeVersion": 1
    },
    {
      "name": "MongoDB",
      "type": "n8n-nodes-base.mongoDb",
      "position": [
        500,
        300
      ],
      "parameters": {
        "fields": "text",
        "options": {},
        "operation": "insert",
        "collection": "tweets"
      },
      "credentials": {
        "mongoDb": "mongodb"
      },
      "typeVersion": 1
    },
    {
      "name": "Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1500,
        200
      ],
      "parameters": {
        "text": "=🐦 NEW TWEET with sentiment score {{$json[\"score\"]}} and magnitude {{$json[\"magnitude\"]}} ⬇️\n{{$json[\"text\"]}}",
        "channel": "tweets",
        "attachments": [],
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": "slack"
      },
      "typeVersion": 1
    },
    {
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "position": [
        1300,
        300
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json[\"score\"]}}",
              "operation": "larger"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "name": "NoOp",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1500,
        400
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "name": "Google Cloud Natural Language",
      "type": "n8n-nodes-base.googleCloudNaturalLanguage",
      "position": [
        700,
        300
      ],
      "parameters": {
        "content": "={{$node[\"MongoDB\"].json[\"text\"]}}",
        "options": {}
      },
      "credentials": {
        "googleCloudNaturalLanguageOAuth2Api": "google_nlp"
      },
      "typeVersion": 1
    },
    {
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "position": [
        900,
        300
      ],
      "parameters": {
        "values": {
          "number": [
            {
              "name": "score",
              "value": "={{$json[\"documentSentiment\"][\"score\"]}}"
            },
            {
              "name": "magnitude",
              "value": "={{$json[\"documentSentiment\"][\"magnitude\"]}}"
            }
          ],
          "string": [
            {
              "name": "text",
              "value": "={{$node[\"Twitter\"].json[\"text\"]}}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "name": "Cron",
      "type": "n8n-nodes-base.cron",
      "position": [
        100,
        300
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "hour": 6
            }
          ]
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "IF": {
      "main": [
        [
          {
            "node": "Slack",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "NoOp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set": {
      "main": [
        [
          {
            "node": "Postgres",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cron": {
      "main": [
        [
          {
            "node": "Twitter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB": {
      "main": [
        [
          {
            "node": "Google Cloud Natural Language",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Twitter": {
      "main": [
        [
          {
            "node": "MongoDB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Cloud Natural Language": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Actions

Share
Categories:
Tags:
cronifnoopsetslacktwitterpostgresmongodbgooglecloudnaturallanguage

Technical Specs

Complexity:
Advanced
Node Count:
9 nodes
Published:11 months ago
Updated:9 days ago

Compatibility

Platform:
N8N Cloud & Self-hosted
Min Version:
N8N v1.0.0+
Supports cloud and self-hosted deployment

License

This workflow template follows MIT license, you can freely use, modify and distribute.

Please comply with relevant third-party service terms when using.

Related Workflows