8
n8n 中文网amn8n.com

房地产市场情绪分析

中级

这是一个Market Research, AI Summarization领域的自动化工作流,包含 15 个节点。主要使用 Code, Telegram, ScheduleTrigger, ScrapegraphAi 等节点。 使用ScrapeGraphAI和Telegram分析房地产市场情绪

前置要求
  • Telegram Bot Token
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "VhEwspDqzu7ssFVE",
  "meta": {
    "instanceId": "f4b0efaa33080e7774e0d9285c40c7abcd2c6f7cf1a8b901fa7106170dd4cda3",
    "templateCredsSetupCompleted": true
  },
  "name": "我的工作流 2",
  "tags": [
    {
      "id": "DxXGubfBzRKh6L8T",
      "name": "Revenue Optimization",
      "createdAt": "2025-07-25T16:24:30.370Z",
      "updatedAt": "2025-07-25T16:24:30.370Z"
    },
    {
      "id": "IxkcJ2IpYIxivoHV",
      "name": "Content Strategy",
      "createdAt": "2025-07-25T12:57:37.677Z",
      "updatedAt": "2025-07-25T12:57:37.677Z"
    },
    {
      "id": "PAKIJ2Mm9EvRcR3u",
      "name": "Trend Monitoring",
      "createdAt": "2025-07-25T12:57:37.670Z",
      "updatedAt": "2025-07-25T12:57:37.670Z"
    },
    {
      "id": "YtfXmaZk44MYedPO",
      "name": "Dynamic Pricing",
      "createdAt": "2025-07-25T16:24:30.369Z",
      "updatedAt": "2025-07-25T16:24:30.369Z"
    },
    {
      "id": "wJ30mjhtrposO8Qt",
      "name": "Simple RAG",
      "createdAt": "2025-07-28T12:55:14.424Z",
      "updatedAt": "2025-07-28T12:55:14.424Z"
    }
  ],
  "nodes": [
    {
      "id": "ca1ec51f-e86e-44f4-b00f-6588ec3bf456",
      "name": "计划触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1056,
        272
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f7d52e3a-2ede-4754-ab26-20e4d96f86c3",
      "name": "ScrapeGraphAI - 房地产论坛",
      "type": "n8n-nodes-scrapegraphai.scrapegraphAi",
      "position": [
        1392,
        400
      ],
      "parameters": {
        "userPrompt": "Extract recent forum discussions about real estate market conditions, investment opportunities, and market sentiment. Focus on posts from the last 24 hours. Return data in this format: { \"discussions\": [{ \"title\": \"discussion title\", \"author\": \"username\", \"date\": \"date posted\", \"content\": \"main discussion content\", \"replies_count\": \"number of replies\", \"sentiment_indicators\": [\"bullish\", \"bearish\", \"neutral indicators\"], \"url\": \"discussion url\" }] }",
        "websiteUrl": "https://www.biggerpockets.com/forums/real-estate-investing"
      },
      "typeVersion": 1
    },
    {
      "id": "728be835-5b88-4132-9289-fcf12f31d554",
      "name": "ScrapeGraphAI - 房地产新闻",
      "type": "n8n-nodes-scrapegraphai.scrapegraphAi",
      "position": [
        1392,
        640
      ],
      "parameters": {
        "userPrompt": "Extract the latest real estate investment news and market analysis from the past 24 hours. Focus on market trends, economic indicators, and expert opinions. Return data as: { \"news_articles\": [{ \"headline\": \"article title\", \"author\": \"author name\", \"date\": \"publication date\", \"summary\": \"article summary\", \"key_points\": [\"important points\"], \"market_impact\": \"positive/negative/neutral\", \"url\": \"article url\" }] }",
        "websiteUrl": "https://www.realestateinvestingtrust.com/news"
      },
      "typeVersion": 1
    },
    {
      "id": "6b2e44ec-8c2c-419a-a145-e367bacab041",
      "name": "情感分析器",
      "type": "n8n-nodes-base.code",
      "position": [
        1664,
        432
      ],
      "parameters": {
        "jsCode": "// Combine forum and news data for sentiment analysis\nconst forumData = $input.all()[0]?.json?.result?.discussions || [];\nconst newsData = $input.all()[1]?.json?.result?.news_articles || [];\n\nfunction analyzeSentiment(text) {\n  const bullishKeywords = ['buy', 'opportunity', 'growth', 'investment', 'profit', 'rising', 'bullish', 'positive', 'gain', 'uptrend'];\n  const bearishKeywords = ['sell', 'crash', 'decline', 'loss', 'falling', 'bearish', 'negative', 'risk', 'downturn', 'bubble'];\n  \n  const textLower = text.toLowerCase();\n  const bullishCount = bullishKeywords.filter(word => textLower.includes(word)).length;\n  const bearishCount = bearishKeywords.filter(word => textLower.includes(word)).length;\n  \n  if (bullishCount > bearishCount) return 'bullish';\n  if (bearishCount > bullishCount) return 'bearish';\n  return 'neutral';\n}\n\nfunction calculateSentimentScore(sentiment) {\n  switch(sentiment) {\n    case 'bullish': return 1;\n    case 'bearish': return -1;\n    default: return 0;\n  }\n}\n\nconst forumSentiments = forumData.map(discussion => {\n  const sentiment = analyzeSentiment(discussion.title + ' ' + discussion.content);\n  return {\n    source: 'forum',\n    title: discussion.title,\n    sentiment: sentiment,\n    score: calculateSentimentScore(sentiment),\n    url: discussion.url,\n    date: discussion.date\n  };\n});\n\nconst newsSentiments = newsData.map(article => {\n  const sentiment = analyzeSentiment(article.headline + ' ' + article.summary);\n  return {\n    source: 'news',\n    title: article.headline,\n    sentiment: sentiment,\n    score: calculateSentimentScore(sentiment),\n    url: article.url,\n    date: article.date,\n    market_impact: article.market_impact\n  };\n});\n\nconst allSentiments = [...forumSentiments, ...newsSentiments];\nconst totalScore = allSentiments.reduce((sum, item) => sum + item.score, 0);\nconst averageScore = totalScore / allSentiments.length || 0;\n\nlet overallSentiment = 'neutral';\nif (averageScore > 0.3) overallSentiment = 'bullish';\nelse if (averageScore < -0.3) overallSentiment = 'bearish';\n\nreturn [{\n  json: {\n    overall_sentiment: overallSentiment,\n    sentiment_score: averageScore,\n    total_sources: allSentiments.length,\n    bullish_count: allSentiments.filter(s => s.sentiment === 'bullish').length,\n    bearish_count: allSentiments.filter(s => s.sentiment === 'bearish').length,\n    neutral_count: allSentiments.filter(s => s.sentiment === 'neutral').length,\n    detailed_analysis: allSentiments,\n    analysis_timestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "ed209cd0-b393-4bb8-9e59-5fc605ab1f77",
      "name": "市场预测器",
      "type": "n8n-nodes-base.code",
      "position": [
        1968,
        416
      ],
      "parameters": {
        "jsCode": "// Market prediction based on sentiment analysis\nconst sentimentData = $input.all()[0].json;\n\nfunction predictMarketDirection(sentimentScore, bullishCount, bearishCount, totalSources) {\n  let prediction = 'hold';\n  let confidence = 0;\n  let reasoning = [];\n  \n  // Strong bullish sentiment\n  if (sentimentScore > 0.5 && bullishCount > bearishCount * 2) {\n    prediction = 'strong_buy';\n    confidence = Math.min(90, 60 + (sentimentScore * 30));\n    reasoning.push('Strong bullish sentiment detected across multiple sources');\n  }\n  // Moderate bullish sentiment\n  else if (sentimentScore > 0.2) {\n    prediction = 'buy';\n    confidence = Math.min(75, 50 + (sentimentScore * 25));\n    reasoning.push('Moderate positive sentiment in the market');\n  }\n  // Strong bearish sentiment\n  else if (sentimentScore < -0.5 && bearishCount > bullishCount * 2) {\n    prediction = 'strong_sell';\n    confidence = Math.min(90, 60 + (Math.abs(sentimentScore) * 30));\n    reasoning.push('Strong bearish sentiment detected - consider exiting positions');\n  }\n  // Moderate bearish sentiment\n  else if (sentimentScore < -0.2) {\n    prediction = 'sell';\n    confidence = Math.min(75, 50 + (Math.abs(sentimentScore) * 25));\n    reasoning.push('Negative sentiment trend - caution advised');\n  }\n  // Neutral/mixed signals\n  else {\n    prediction = 'hold';\n    confidence = 40;\n    reasoning.push('Mixed signals in market sentiment - maintain current positions');\n  }\n  \n  // Adjust confidence based on data volume\n  if (totalSources < 10) {\n    confidence *= 0.8;\n    reasoning.push('Limited data sources - lower confidence');\n  }\n  \n  return {\n    prediction,\n    confidence: Math.round(confidence),\n    reasoning\n  };\n}\n\nconst marketPrediction = predictMarketDirection(\n  sentimentData.sentiment_score,\n  sentimentData.bullish_count,\n  sentimentData.bearish_count,\n  sentimentData.total_sources\n);\n\n// Generate investment recommendations\nlet recommendations = [];\nswitch(marketPrediction.prediction) {\n  case 'strong_buy':\n    recommendations = [\n      'Consider increasing real estate investment allocation',\n      'Look for value opportunities in growth markets',\n      'Accelerate planned property acquisitions'\n    ];\n    break;\n  case 'buy':\n    recommendations = [\n      'Moderate increase in real estate exposure',\n      'Focus on cash-flowing properties',\n      'Monitor market closely for entry points'\n    ];\n    break;\n  case 'strong_sell':\n    recommendations = [\n      'Consider reducing real estate exposure',\n      'Postpone new acquisitions',\n      'Review portfolio for underperforming assets'\n    ];\n    break;\n  case 'sell':\n    recommendations = [\n      'Exercise caution with new investments',\n      'Consider taking profits on recent gains',\n      'Increase cash reserves'\n    ];\n    break;\n  default:\n    recommendations = [\n      'Maintain current investment strategy',\n      'Continue regular market monitoring',\n      'Stay prepared for market shifts'\n    ];\n}\n\nreturn [{\n  json: {\n    ...sentimentData,\n    market_prediction: marketPrediction.prediction,\n    confidence_level: marketPrediction.confidence,\n    reasoning: marketPrediction.reasoning,\n    investment_recommendations: recommendations,\n    risk_level: marketPrediction.confidence > 70 ? 'low' : marketPrediction.confidence > 50 ? 'medium' : 'high',\n    prediction_timestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "11367ba0-9a2c-4352-85c5-945596f2aab0",
      "name": "时机优化器",
      "type": "n8n-nodes-base.code",
      "position": [
        2272,
        416
      ],
      "parameters": {
        "jsCode": "// Timing optimization based on market prediction and historical patterns\nconst predictionData = $input.all()[0].json;\n\nfunction optimizeTiming(prediction, confidence, sentimentScore) {\n  let timing_recommendation = 'monitor';\n  let urgency = 'low';\n  let optimal_timeframe = '1-3 months';\n  let timing_factors = [];\n  \n  // Determine optimal timing based on prediction strength\n  if (prediction === 'strong_buy' && confidence > 75) {\n    timing_recommendation = 'act_immediately';\n    urgency = 'high';\n    optimal_timeframe = '1-2 weeks';\n    timing_factors.push('Strong market signals indicate immediate action needed');\n  }\n  else if (prediction === 'buy' && confidence > 60) {\n    timing_recommendation = 'act_soon';\n    urgency = 'medium';\n    optimal_timeframe = '2-4 weeks';\n    timing_factors.push('Positive sentiment building - act within optimal window');\n  }\n  else if (prediction === 'strong_sell') {\n    timing_recommendation = 'exit_positions';\n    urgency = 'high';\n    optimal_timeframe = '1-2 weeks';\n    timing_factors.push('Strong negative signals - consider immediate exit strategy');\n  }\n  else if (prediction === 'sell') {\n    timing_recommendation = 'reduce_exposure';\n    urgency = 'medium';\n    optimal_timeframe = '2-6 weeks';\n    timing_factors.push('Negative trend developing - gradual position reduction advised');\n  }\n  \n  // Add seasonal considerations (simplified)\n  const currentMonth = new Date().getMonth();\n  const seasonalFactors = {\n    spring: [2, 3, 4], // March, April, May\n    summer: [5, 6, 7], // June, July, August\n    fall: [8, 9, 10],  // September, October, November\n    winter: [11, 0, 1] // December, January, February\n  };\n  \n  let currentSeason = 'winter';\n  for (const [season, months] of Object.entries(seasonalFactors)) {\n    if (months.includes(currentMonth)) {\n      currentSeason = season;\n      break;\n    }\n  }\n  \n  if (currentSeason === 'spring' || currentSeason === 'summer') {\n    timing_factors.push('Peak real estate season - higher activity expected');\n  } else {\n    timing_factors.push('Off-season period - potentially better deals available');\n  }\n  \n  return {\n    timing_recommendation,\n    urgency,\n    optimal_timeframe,\n    timing_factors,\n    current_season: currentSeason\n  };\n}\n\nconst timingAnalysis = optimizeTiming(\n  predictionData.market_prediction,\n  predictionData.confidence_level,\n  predictionData.sentiment_score\n);\n\nreturn [{\n  json: {\n    ...predictionData,\n    timing_recommendation: timingAnalysis.timing_recommendation,\n    urgency_level: timingAnalysis.urgency,\n    optimal_timeframe: timingAnalysis.optimal_timeframe,\n    timing_factors: timingAnalysis.timing_factors,\n    current_season: timingAnalysis.current_season,\n    timing_analysis_timestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "a430a788-98ec-469e-9724-dca80245a1e9",
      "name": "投资顾问提醒",
      "type": "n8n-nodes-base.code",
      "position": [
        2592,
        416
      ],
      "parameters": {
        "jsCode": "// Generate comprehensive investment advisor alert\nconst analysisData = $input.all()[0].json;\n\nfunction generateAlert(data) {\n  const {\n    overall_sentiment,\n    sentiment_score,\n    market_prediction,\n    confidence_level,\n    timing_recommendation,\n    urgency_level,\n    optimal_timeframe,\n    investment_recommendations,\n    risk_level\n  } = data;\n  \n  // Determine alert priority\n  let alertPriority = 'normal';\n  if (urgency_level === 'high' && confidence_level > 70) {\n    alertPriority = 'critical';\n  } else if (urgency_level === 'medium' || confidence_level > 60) {\n    alertPriority = 'high';\n  }\n  \n  // Generate alert title\n  const alertTitle = `🏠 RE Market Alert: ${market_prediction.toUpperCase().replace('_', ' ')} Signal (${confidence_level}% confidence)`;\n  \n  // Generate detailed message\n  let message = `📊 **REAL ESTATE MARKET ANALYSIS REPORT**\\n\\n`;\n  message += `🎯 **Overall Sentiment:** ${overall_sentiment.toUpperCase()}\\n`;\n  message += `📈 **Market Prediction:** ${market_prediction.replace('_', ' ').toUpperCase()}\\n`;\n  message += `🎲 **Confidence Level:** ${confidence_level}%\\n`;\n  message += `⏰ **Timing:** ${timing_recommendation.replace('_', ' ').toUpperCase()}\\n`;\n  message += `🚨 **Urgency:** ${urgency_level.toUpperCase()}\\n`;\n  message += `📅 **Optimal Timeframe:** ${optimal_timeframe}\\n`;\n  message += `⚠️ **Risk Level:** ${risk_level.toUpperCase()}\\n\\n`;\n  \n  message += `💡 **KEY RECOMMENDATIONS:**\\n`;\n  investment_recommendations.forEach((rec, index) => {\n    message += `${index + 1}. ${rec}\\n`;\n  });\n  \n  message += `\\n🔍 **ANALYSIS SUMMARY:**\\n`;\n  message += `• Total sources analyzed: ${data.total_sources}\\n`;\n  message += `• Bullish signals: ${data.bullish_count}\\n`;\n  message += `• Bearish signals: ${data.bearish_count}\\n`;\n  message += `• Neutral signals: ${data.neutral_count}\\n`;\n  \n  message += `\\n📋 **TIMING FACTORS:**\\n`;\n  data.timing_factors.forEach((factor, index) => {\n    message += `• ${factor}\\n`;\n  });\n  \n  message += `\\n🕐 **Report Generated:** ${new Date().toLocaleString()}\\n`;\n  message += `\\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;\n  \n  return {\n    alert_title: alertTitle,\n    alert_message: message,\n    alert_priority: alertPriority,\n    raw_data: data\n  };\n}\n\nconst alert = generateAlert(analysisData);\n\nreturn [{\n  json: {\n    ...alert,\n    notification_timestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d2bd5cbb-7de7-45f3-b106-2200aba40fa4",
      "name": "Telegram 提醒",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2896,
        400
      ],
      "webhookId": "e0f221b9-7ee1-4113-850e-1fc0202811f1",
      "parameters": {
        "text": "={{ $json.alert_message }}",
        "chatId": "@real_estate_alerts",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "15984e52-8b3a-4739-956c-e3d24197ff3f",
      "name": "便签 - 触发器",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        976,
        -352
      ],
      "parameters": {
        "color": 2,
        "width": 300,
        "height": 1136,
        "content": "# 步骤1:定时触发器 ⏱️"
      },
      "typeVersion": 1
    },
    {
      "id": "de278e05-8034-4c28-a838-79933be72677",
      "name": "便签 - 数据收集",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        -352
      ],
      "parameters": {
        "color": 3,
        "width": 300,
        "height": 1136,
        "content": "# 步骤2:数据收集 🔍"
      },
      "typeVersion": 1
    },
    {
      "id": "e14ea293-64f2-4751-a573-5b9f2bed9a8a",
      "name": "便签 - 情感分析",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        -352
      ],
      "parameters": {
        "color": 4,
        "width": 300,
        "height": 1136,
        "content": "# 步骤3:情感分析 🧠"
      },
      "typeVersion": 1
    },
    {
      "id": "a1d2afa7-e8dc-4e19-8fb3-ac199f9726a9",
      "name": "便签 - 市场预测",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1888,
        -352
      ],
      "parameters": {
        "color": 5,
        "width": 300,
        "height": 1136,
        "content": "# 步骤4:市场预测 🔮"
      },
      "typeVersion": 1
    },
    {
      "id": "ce6eb84f-96ca-47a6-9b9a-8e16c1b77b13",
      "name": "便签 - 时机优化",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2192,
        -352
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 1136,
        "content": "# 步骤5:时机优化 ⏰"
      },
      "typeVersion": 1
    },
    {
      "id": "77039ec5-4612-49fb-a4b4-1f4e5c21ec56",
      "name": "便签 - 投资提醒",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2496,
        -352
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 1136,
        "content": "# 步骤6:投资提醒 🚨"
      },
      "typeVersion": 1
    },
    {
      "id": "05197e73-8d6b-45e2-8202-6c828a45a9c7",
      "name": "便签 - Telegram 投递",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2800,
        -352
      ],
      "parameters": {
        "width": 300,
        "height": 1136,
        "content": "# 步骤7:Telegram 投递 📱"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "df60cb6d-f920-46a7-843a-9d4c9bdd76d9",
  "connections": {
    "Market Predictor": {
      "main": [
        [
          {
            "node": "Timing Optimizer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "ScrapeGraphAI - RE Forums",
            "type": "main",
            "index": 0
          },
          {
            "node": "ScrapeGraphAI - RE News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Timing Optimizer": {
      "main": [
        [
          {
            "node": "Investment Advisor Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sentiment Analyzer": {
      "main": [
        [
          {
            "node": "Market Predictor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ScrapeGraphAI - RE News": {
      "main": [
        [
          {
            "node": "Sentiment Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Investment Advisor Alert": {
      "main": [
        [
          {
            "node": "Telegram Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ScrapeGraphAI - RE Forums": {
      "main": [
        [
          {
            "node": "Sentiment Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 市场调研, AI 摘要总结

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量15
分类2
节点类型5
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

外部链接
在 n8n.io 查看

分享此工作流