情感分析机器人
高级
这是一个Crypto Trading, AI Summarization领域的自动化工作流,包含 18 个节点。主要使用 If, Code, HttpRequest, GoogleSheets, SplitInBatches 等节点。 使用Google Gemini和EODHD新闻API实现自动化股票情感分析
前置要求
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
- •Google Gemini API Key
使用的节点 (18)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "34d07950904120624117fd89d9d9b4f13d9fa466720a0972ac5aa843f9eb8cb8",
"templateCredsSetupCompleted": true
},
"name": "情感分析机器人",
"tags": [],
"nodes": [
{
"id": "0d063cec-e739-48b6-9698-0ac586f147ad",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1040,
1620
],
"parameters": {
"text": "=You are a stock sentiment analyzer. Your task is to evaluate news content for their potential impact on a specific stock.\n\nInput Format:\n User input is in the following format:\n Symbol: (The stock symbol also called ticker symbol)\n title: (News headline that you have to analyze for sentiment of the given stock)\ncontent:(the content of the news to analyze)\nAnalysis Guidelines:\n Evaluate how the news might affect the price of only the stock specified by the user in the input and generate a sentiment score between -1 and 1.\n A score close to -1 indicates a strong negative impact, suggesting the news could significantly drive the stock price down.\n A score near 0 represents a neutral impact, implying little to no effect on the stock price.\n Conversely, a score close to 1 reflects a strong positive impact, likely driving the stock price up.\n When generating the score, consider whether the news is surprising i.e., if it contains new information - or already priced in.\n Explain in detail the rationale behind the score, highlighting why the news is positive, negative, or neutral for the given stock's price.\nOutput Format:\n Return the result as JSON in the following format:\n\n { symbol: (The stock symbol also called ticker symbol),\"sentiment_score\": (The sentiment score - float between -1 and 1), \"rationale\": (Your explanation for the score)}\nProvide the JSON output only. Do not include any other text.\n\nReal stock Symbol:\n{{$('loop_over_tickers').all()[0].json.ticker}}\n{{ $('join_articles_into_1').all()[0].json.fullString }}\n",
"options": {},
"promptType": "define"
},
"executeOnce": false,
"typeVersion": 2
},
{
"id": "a9bec4e8-b9df-4868-b6c3-072316fe1ed9",
"name": "Google Gemini聊天模型1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1028,
1840
],
"parameters": {
"options": {
"maxOutputTokens": 2048
},
"modelName": "models/gemini-2.0-flash"
},
"credentials": {
"googlePalmApi": {
"id": "ynRNNwts1fakC7X4",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "0b197810-0002-4f2c-8122-1db9a6a81558",
"name": "从EODHD获取文章",
"type": "n8n-nodes-base.httpRequest",
"position": [
160,
1520
],
"parameters": {
"url": "https://eodhd.com/api/news",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"queryParameters": {
"parameters": [
{
"name": "s",
"value": "={{ $json.ticker }}"
},
{
"name": "offset",
"value": "0"
},
{
"name": "limit",
"value": "10"
},
{
"name": "fmt",
"value": "json"
}
]
}
},
"credentials": {
"httpQueryAuth": {
"id": "p1dJbEo98pH5SVih",
"name": "Query Auth account"
}
},
"executeOnce": false,
"typeVersion": 4.2,
"alwaysOutputData": false
},
{
"id": "392f7ccd-aba3-4911-859a-556535f45eea",
"name": "循环处理股票代码",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-200,
1640
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "6e5b9817-b6ec-4c0a-98fd-b41340ab6230",
"name": "从表格读取股票代码",
"type": "n8n-nodes-base.googleSheets",
"position": [
-420,
1640
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 470128021,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit#gid=470128021",
"cachedResultName": "stocks"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit?usp=drivesdk",
"cachedResultName": "Stock Sentiment"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Bpltco7Lqc7P73Qp",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "e68be220-53b9-4b3d-a543-98a916382d42",
"name": "如果股票代码无效",
"type": "n8n-nodes-base.if",
"position": [
380,
1520
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "770d6272-1cde-44d7-9e15-fe5d7c28ba36",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $ifEmpty($input.all().toJsonString(),'True') }}",
"rightValue": "True"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "bfc2cc77-5fc2-41ae-9e2a-22fed368c852",
"name": "在Google表格中写入无效股票代码",
"type": "n8n-nodes-base.googleSheets",
"position": [
600,
1420
],
"parameters": {
"columns": {
"value": {
"date": "={{$today}}\n",
"stock": "={{ $('loop_over_tickers').item.json.ticker }}",
"sentimentScore": "Invaild Ticker"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "stock",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "stock",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sentimentScore",
"type": "string",
"display": true,
"required": false,
"displayName": "sentimentScore",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "rational",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "rational",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit?usp=drivesdk",
"cachedResultName": "Stock Sentiment"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Bpltco7Lqc7P73Qp",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "81a16d3a-cdc4-4ad3-8769-b858a999f0ed",
"name": "将文章合并为一个",
"type": "n8n-nodes-base.code",
"position": [
600,
1620
],
"parameters": {
"jsCode": "// --- n8n Code Node (JavaScript) ---\n// This script takes an array of objects and converts it into a single JSON string.\n\n// 1. Extract the JSON data from all incoming n8n items.\nconst allArticlesArray = items.map(item => item.json);\n\n// 2. Convert the entire array into a single JSON string.\n// The 'null, 2' arguments format the string with indentation for readability.\nconst combinedString = JSON.stringify(allArticlesArray, null, 2);\n\n// 3. Return the result as a single item.\n// The output will have one property, 'fullString', containing the combined text.\nreturn [\n {\n json: {\n fullString: combinedString\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "9c05ff30-59c7-45e0-8079-e3a0f01547bd",
"name": "将输出格式化为JSON",
"type": "n8n-nodes-base.code",
"onError": "continueRegularOutput",
"position": [
1600,
1520
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n// The input is an array of items. We'll work with the first item.\n\n\n// Access the string value from the 'output' field in the input JSON.\nconst rawStringWithMarkdown = item.json.output;\nconsole.log(item.json.output)\n// The JSON we want is nested inside a markdown code block (```json ... ```).\n// We need to extract just the JSON part.\n\n// Find the first occurrence of '{' to locate the start of the JSON object.\nconst jsonStartIndex = rawStringWithMarkdown.indexOf('{');\n\n// Find the last occurrence of '}' to locate the end of the JSON object.\nconst jsonEndIndex = rawStringWithMarkdown.lastIndexOf('}');\n\n// Slice the string from the start to the end to get only the clean JSON string.\n// We add +1 to jsonEndIndex because substring's second argument is exclusive.\nconst cleanJsonString = rawStringWithMarkdown.substring(jsonStartIndex, jsonEndIndex + 1);\n\n// Parse the cleaned string into a proper, usable JSON object.\nconst parsedJson = JSON.parse(cleanJsonString);\n\n// Return the parsed JSON object. The keys (symbol, sentiment_score, etc.)\n// will become individual fields in the n8n output for the next node to use.\nreturn parsedJson;}\n\n"
},
"executeOnce": false,
"retryOnFail": false,
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "c5817f1f-8e79-4c13-9807-fd5176c2773f",
"name": "如果格式化成功",
"type": "n8n-nodes-base.if",
"position": [
1840,
1620
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "770d6272-1cde-44d7-9e15-fe5d7c28ba36",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.error }}",
"rightValue": "True"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "0dc93919-fb1a-46df-b316-1044f11cd791",
"name": "将情感分析写入表格",
"type": "n8n-nodes-base.googleSheets",
"position": [
2360,
1740
],
"parameters": {
"columns": {
"value": {
"date": "={{$today}}\n",
"stock": "={{$('loop_over_tickers').all()[0].json.ticker.replace(\".US\",\"\")}}",
"rational": "={{ $json.rationale }}",
"sentimentScore": "={{ $json.sentiment_score }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "stock",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "stock",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sentimentScore",
"type": "string",
"display": true,
"required": false,
"displayName": "sentimentScore",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "rational",
"type": "string",
"display": true,
"required": false,
"displayName": "rational",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1tQDBVDqn5v08GOsjupjV8o3Jzqd4-fKoSoGhWLEOTww/edit?usp=drivesdk",
"cachedResultName": "Stock Sentiment"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Bpltco7Lqc7P73Qp",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "3cbf7b55-50ae-4d1c-8f9e-56941441ef00",
"name": "计划触发器",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-640,
1640
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 16
}
]
}
},
"typeVersion": 1.2
},
{
"id": "ce8d9b54-2026-4faa-9ee1-c261170c8426",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-620,
660
],
"parameters": {
"width": 480,
"height": 440,
"content": "# 工作流概述"
},
"typeVersion": 1
},
{
"id": "efaee1f9-e57a-4640-a1d6-eb5bc5f341af",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-680,
1200
],
"parameters": {
"color": 4,
"width": 640,
"height": 640,
"content": "# 1. 每日触发和股票代码检索"
},
"typeVersion": 1
},
{
"id": "eaca666d-2830-4e98-bfe4-44c15d452939",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
1020
],
"parameters": {
"color": 5,
"width": 680,
"height": 940,
"content": "# 2. 新闻文章检索和验证"
},
"typeVersion": 1
},
{
"id": "92a8b9e8-cdca-4584-938f-b478b8136867",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
1180
],
"parameters": {
"color": 6,
"width": 500,
"height": 800,
"content": "# 3. 使用AI进行情感分析"
},
"typeVersion": 1
},
{
"id": "aa4c0dfb-0e02-4f74-b908-27b6b81bbef1",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1500,
980
],
"parameters": {
"color": 2,
"width": 560,
"height": 860,
"content": "# 4. 输出格式化和错误处理"
},
"typeVersion": 1
},
{
"id": "cd441252-7867-40e4-9fb9-aa1e6fd53fb9",
"name": "便签5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2160,
1300
],
"parameters": {
"color": 3,
"width": 520,
"height": 600,
"content": "# 5. 存储结果"
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"timezone": "Asia/Jerusalem",
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1"
},
"versionId": "28688d53-2f5a-4653-bd71-bca83d087647",
"connections": {
"AI Agent": {
"main": [
[
{
"node": "format_output_as_json",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Read_tickers_from_Sheet",
"type": "main",
"index": 0
}
]
]
},
"loop_over_tickers": {
"main": [
[],
[
{
"node": "Get articles from EODHD",
"type": "main",
"index": 0
}
]
]
},
"If_ticker_not_valid": {
"main": [
[
{
"node": "Write_in_google_sheets_invalid_ticker",
"type": "main",
"index": 0
}
],
[
{
"node": "join_articles_into_1",
"type": "main",
"index": 0
}
]
]
},
"if_format_succesful": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "write_sentiment_to_sheets",
"type": "main",
"index": 0
}
]
]
},
"join_articles_into_1": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"format_output_as_json": {
"main": [
[
{
"node": "if_format_succesful",
"type": "main",
"index": 0
}
]
]
},
"Get articles from EODHD": {
"main": [
[
{
"node": "If_ticker_not_valid",
"type": "main",
"index": 0
}
]
]
},
"Read_tickers_from_Sheet": {
"main": [
[
{
"node": "loop_over_tickers",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"write_sentiment_to_sheets": {
"main": [
[
{
"node": "loop_over_tickers",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 加密货币交易, AI 摘要总结
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用Apollo.io和Google表格的自动化LinkedIn潜在客户丰富管道
使用Apollo.io和Google表格的自动化LinkedIn潜在客户丰富管道
If
Code
Wait
+10
33 节点Rahi Uppal
潜在客户开发
SOL/USDT多时间框架AI市场分析器与交易系统(含Telegram审批)
使用Gemini AI、多时间框架分析和AFK Crypto自动化Solana交易
If
Code
Wait
+7
56 节点Jeff
加密货币交易
第一轮 Telegram 和 LinkedIn 快速通道 AI 招聘助手
AI候选人筛选流程:LinkedIn到Telegram,集成Gemini与Apify
If
Set
Code
+15
55 节点Dean Pike
人力资源
AI驱动的谷歌地图商家数据抓取与表格导出
基于AI的谷歌地图商家数据抓取,支持数据丰富化并导出至表格
If
Code
Wait
+13
25 节点Msaid Mohamed el hadi
潜在客户开发
每日 WhatsApp 群组智能分析:GPT-4.1 分析与语音消息转录
每日 WhatsApp 群组智能分析:GPT-4.1 分析与语音消息转录
If
Set
Code
+20
52 节点Daniel Lianes
杂项
选题捕手模板
使用Gemini分析Reddit、YouTube和X生成内容策略报告
If
Set
Code
+14
34 节点Sheryl
市场调研
工作流信息
难度等级
高级
节点数量18
分类2
节点类型9
作者
Raz Hadas
@raz-hadasCo-founder of buildmyflow, on a mission to create powerful and easy-to-use n8n automation templates. With a background in AI and a passion for social impact as the co-founder of TovTech, I'm dedicated to building a community-focused resource for free and premium workflows that save you time and unlock new possibilities. Let's automate together! https://www.linkedin.com/in/raz-hadas/
外部链接
在 n8n.io 查看 →
分享此工作流