每日汇率邮件报告
中级
这是一个Crypto Trading领域的自动化工作流,包含 11 个节点。主要使用 Code, Merge, EmailSend, HttpRequest, ScheduleTrigger 等节点。 包含美元→欧元/尼日利亚奈拉及BTC/ETH价格追踪的每日汇率邮件报告
前置要求
- •可能需要目标 API 的认证凭证
分类
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "2000c64071c20843606b95c63795bb0797c41036047055a6586498e855b96efc",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "1ba443db-fe26-4caf-a247-e3f5bf4157d7",
"name": "每日早上 8 点触发器",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-256,
224
],
"parameters": {
"rule": {
"interval": [
{
"field": "seconds"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "493a3fe9-2c87-494a-8baa-70ff0de03530",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-480,
16
],
"parameters": {
"width": 350,
"height": 380,
"content": "💰 货币追踪工作流:"
},
"typeVersion": 1
},
{
"id": "c70f0f99-2259-405a-a305-bdd3062c52aa",
"name": "获取法定货币汇率",
"type": "n8n-nodes-base.httpRequest",
"position": [
-32,
144
],
"parameters": {
"url": "https://api.exchangerate-api.com/v4/latest/USD",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "5ba231d1-5077-4f06-a4e6-28090ce56a4e",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-144
],
"parameters": {
"color": 6,
"width": 350,
"height": 280,
"content": "🌍 法定货币汇率:"
},
"typeVersion": 1
},
{
"id": "f252dd92-67e3-4b8b-9deb-b1ed3b601f8f",
"name": "获取加密货币价格",
"type": "n8n-nodes-base.httpRequest",
"position": [
-32,
304
],
"parameters": {
"url": "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum&vs_currencies=usd&include_24hr_change=true",
"options": {}
},
"typeVersion": 4.1
},
{
"id": "48a20f94-5687-42da-8b76-80c000fc282d",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
624,
304
],
"parameters": {
"width": 350,
"height": 280,
"content": "₿ 加密货币价格:"
},
"typeVersion": 1
},
{
"id": "dc21acae-14ff-483d-a912-e7368bf3451e",
"name": "格式化邮件内容",
"type": "n8n-nodes-base.code",
"position": [
352,
208
],
"parameters": {
"jsCode": "// n8n Code (v2): Better \"Format Email Content\"\n// - Auto-detects fiat vs crypto inputs (works regardless of Merge order)\n// - Defensive parsing + nice HTML + text fallback\n// - Uses Africa/Lagos by default for display time (change tz if needed)\n\nconst TZ = 'Africa/Lagos';\nconst NOW = new Date();\n\nconst items = $input.all(); // merged inputs\nif (!items || items.length < 2) {\n throw new Error('Expected 2 inputs (fiat + crypto), but received ' + (items ? items.length : 0));\n}\n\n// Identify which payload is which regardless of order\nlet fiatData, cryptoData;\nfor (const it of items) {\n const j = it.json || {};\n if (j.rates && j.base && j.date) fiatData = j;\n if (j.bitcoin || j.ethereum) cryptoData = j;\n}\n\nif (!fiatData) {\n throw new Error('Fiat data not found. Ensure the ExchangeRate-API node is connected to the Merge before this Code node.');\n}\nif (!cryptoData) {\n throw new Error('Crypto data not found. Ensure the CoinGecko node is connected to the Merge before this Code node.');\n}\n\n// Extract fiat\nconst eurRate = Number(fiatData?.rates?.EUR);\nconst ngnRate = Number(fiatData?.rates?.NGN);\nconst lastUpdated = String(fiatData?.date || 'N/A');\n\n// Extract crypto\nconst btcPrice = Number(cryptoData?.bitcoin?.usd);\nconst btcChange = Number(cryptoData?.bitcoin?.usd_24h_change);\nconst ethPrice = Number(cryptoData?.ethereum?.usd);\nconst ethChange = Number(cryptoData?.ethereum?.usd_24h_change);\n\n// Helpers\nconst fmtNum = (num, decimals = 2) =>\n isFinite(num) ? new Intl.NumberFormat('en-US', {\n minimumFractionDigits: decimals, maximumFractionDigits: decimals\n }).format(num) : '—';\n\nconst arrow = (n) => (isFinite(n) ? (n >= 0 ? '▲' : '▼') : '');\nconst color = (n) => (isFinite(n) ? (n >= 0 ? '#0FA958' : '#E03E2F') : '#6B7280');\nconst sign = (n) => (isFinite(n) && n > 0 ? '+' : '');\n\nconst fmtPct = (n) =>\n isFinite(n)\n ? `<span style=\"color:${color(n)};font-weight:600\">${sign(n)}${fmtNum(n, 2)}%</span> ${arrow(n)}`\n : '<span style=\"color:#6B7280\">—</span>';\n\nconst fmtDate = (d=NOW, tz=TZ) =>\n d.toLocaleString('en-US', { timeZone: tz, weekday:'long', year:'numeric', month:'long', day:'numeric', hour:'2-digit', minute:'2-digit' });\n\n// Build HTML\nconst html = `\n<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width\">\n<title>Daily Currency Report</title>\n</head>\n<body style=\"margin:0;padding:24px;background:#F5F7FB;font-family:Inter,system-ui,Segoe UI,Roboto,Arial,sans-serif;\">\n <div style=\"max-width:640px;margin:0 auto;background:#ffffff;border-radius:12px;box-shadow:0 8px 24px rgba(16,24,40,0.08);overflow:hidden;\">\n <div style=\"background:linear-gradient(135deg,#667EEA 0%,#764BA2 100%);padding:28px 24px;text-align:center;\">\n <div style=\"font-size:28px;color:#fff;letter-spacing:0.2px\">💰 Daily Currency Report</div>\n <div style=\"margin-top:6px;color:rgba(255,255,255,0.9);font-size:14px\">${fmtDate()}</div>\n </div>\n\n <div style=\"padding:24px\">\n <h2 style=\"margin:0 0 12px 0;font-size:18px;color:#111827\">🌍 Fiat Exchange Rates (USD base)</h2>\n <div style=\"display:grid;gap:12px\">\n <div style=\"background:#F8FAFC;border-left:4px solid #3B82F6;padding:16px;border-radius:8px\">\n <div style=\"display:flex;justify-content:space-between;align-items:center\">\n <div>\n <div style=\"font-weight:600;color:#111827\">🇺🇸 USD → 🇪🇺 EUR</div>\n <div style=\"color:#6B7280;font-size:12px\">US Dollar to Euro</div>\n </div>\n <div style=\"font-weight:700;color:#1D4ED8;font-size:20px\">${fmtNum(eurRate, 4)}</div>\n </div>\n </div>\n\n <div style=\"background:#F8FAFC;border-left:4px solid #10B981;padding:16px;border-radius:8px\">\n <div style=\"display:flex;justify-content:space-between;align-items:center\">\n <div>\n <div style=\"font-weight:600;color:#111827\">🇺🇸 USD → 🇳🇬 NGN</div>\n <div style=\"color:#6B7280;font-size:12px\">US Dollar to Nigerian Naira</div>\n </div>\n <div style=\"font-weight:700;color:#065F46;font-size:20px\">₦${fmtNum(ngnRate, 2)}</div>\n </div>\n </div>\n </div>\n\n <h2 style=\"margin:24px 0 12px 0;font-size:18px;color:#111827\">₿ Cryptocurrency Prices</h2>\n <div style=\"display:grid;gap:12px\">\n <div style=\"background:#FFFBEB;border-left:4px solid #F59E0B;padding:16px;border-radius:8px\">\n <div style=\"display:flex;justify-content:space-between;align-items:center\">\n <div>\n <div style=\"font-weight:600;color:#111827\">₿ Bitcoin (BTC)</div>\n <div style=\"color:#6B7280;font-size:12px\">24h change: ${fmtPct(btcChange)}</div>\n </div>\n <div style=\"font-weight:700;color:#B45309;font-size:20px\">$${fmtNum(btcPrice, 0)}</div>\n </div>\n </div>\n\n <div style=\"background:#EEF2FF;border-left:4px solid #6366F1;padding:16px;border-radius:8px\">\n <div style=\"display:flex;justify-content:space-between;align-items:center\">\n <div>\n <div style=\"font-weight:600;color:#111827\">⟠ Ethereum (ETH)</div>\n <div style=\"color:#6B7280;font-size:12px\">24h change: ${fmtPct(ethChange)}</div>\n </div>\n <div style=\"font-weight:700;color:#3730A3;font-size:20px\">$${fmtNum(ethPrice, 0)}</div>\n </div>\n </div>\n </div>\n\n <div style=\"margin-top:20px;color:#6B7280;font-size:12px;border-top:1px solid #E5E7EB;padding-top:12px\">\n 📊 Fiat updated: ${lastUpdated} | ⏱️ Generated: ${fmtDate()} (${TZ})\n </div>\n </div>\n\n <div style=\"background:#F9FAFB;padding:14px;text-align:center;color:#6B7280;font-size:12px;border-top:1px solid #E5E7EB\">\n This email was generated automatically by your n8n currency tracker.\n </div>\n </div>\n</body>\n</html>\n`;\n\n// Plain text\nconst text = [\n `Daily Currency Report — ${NOW.toLocaleDateString('en-US', { timeZone: TZ })}`,\n ``,\n `Fiat (USD base)`,\n `• USD → EUR: ${fmtNum(eurRate, 4)}`,\n `• USD → NGN: ₦${fmtNum(ngnRate, 2)}`,\n ``,\n `Crypto`,\n `• BTC: $${fmtNum(btcPrice, 0)} (24h: ${sign(btcChange)}${fmtNum(btcChange, 2)}%)`,\n `• ETH: $${fmtNum(ethPrice, 0)} (24h: ${sign(ethChange)}${fmtNum(ethChange, 2)}%)`,\n ``,\n `Fiat updated: ${lastUpdated} | Generated: ${fmtDate()} (${TZ})`\n].join('\\n');\n\nreturn [\n {\n json: {\n subject: `💰 Daily Currency Report — ${NOW.toLocaleDateString('en-US', { timeZone: TZ })}`,\n html,\n text,\n summary: {\n usd_eur: eurRate,\n usd_ngn: ngnRate,\n btc_usd: btcPrice,\n btc_change_24h: btcChange,\n eth_usd: ethPrice,\n eth_change_24h: ethChange,\n fiat_date: lastUpdated,\n generated_at: fmtDate()\n }\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "1fb2c7a0-f562-4a0d-95cb-250c06ac7c22",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
-224
],
"parameters": {
"color": 7,
"width": 380,
"height": 300,
"content": "🎨 邮件格式化:"
},
"typeVersion": 1
},
{
"id": "96c07871-73a2-4507-bb48-4e4d3acd0213",
"name": "发送每日货币邮件",
"type": "n8n-nodes-base.emailSend",
"position": [
576,
224
],
"webhookId": "ee553940-a01e-4b5c-a0b4-492c0dac7f72",
"parameters": {
"html": "={{ $json.html }}",
"options": {
"appendAttribution": false
},
"subject": "={{ $json.subject }}",
"toEmail": "recipient@email.com",
"fromEmail": "your-email@gmail.com",
"emailFormat": "html"
},
"credentials": {
"smtp": {
"id": "0xVva6dyyi5SuxBe",
"name": "SMTP account"
}
},
"typeVersion": 2
},
{
"id": "4c14b55a-2fa2-4597-9fc8-4fd59ed0931c",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
-96
],
"parameters": {
"color": 3,
"width": 350,
"height": 320,
"content": "📨 邮件投递:"
},
"typeVersion": 1
},
{
"id": "88b956bc-370f-492b-a87b-04aefedcd2f6",
"name": "合并",
"type": "n8n-nodes-base.merge",
"position": [
112,
208
],
"parameters": {},
"typeVersion": 3.2
}
],
"pinData": {
"Get Crypto Prices": [
{
"bitcoin": {
"usd": 112417,
"usd_24h_change": 1.2206074861031901
},
"ethereum": {
"usd": 4334.57,
"usd_24h_change": 1.332324938717491
}
}
],
"Get Fiat Exchange Rates": [
{
"base": "USD",
"date": "2025-09-08",
"rates": {
"AED": 3.67,
"AFN": 68.37,
"ALL": 83.02,
"AMD": 382.63,
"ANG": 1.79,
"AOA": 916.83,
"ARS": 1365.42,
"AUD": 1.53,
"AWG": 1.79,
"AZN": 1.7,
"BAM": 1.67,
"BBD": 2,
"BDT": 121.69,
"BGN": 1.67,
"BHD": 0.376,
"BIF": 2984.39,
"BMD": 1,
"BND": 1.29,
"BOB": 6.91,
"BRL": 5.42,
"BSD": 1,
"BTN": 88.25,
"BWP": 13.71,
"BYN": 3.34,
"BZD": 2,
"CAD": 1.38,
"CDF": 2896.98,
"CHF": 0.799,
"CLP": 969.79,
"CNY": 7.13,
"COP": 3975.45,
"CRC": 505.79,
"CUP": 24,
"CVE": 94.15,
"CZK": 20.83,
"DJF": 177.72,
"DKK": 6.37,
"DOP": 63.29,
"DZD": 129.79,
"EGP": 48.52,
"ERN": 15,
"ETB": 142.03,
"EUR": 0.854,
"FJD": 2.25,
"FKP": 0.741,
"FOK": 6.37,
"GBP": 0.741,
"GEL": 2.69,
"GGP": 0.741,
"GHS": 12.03,
"GIP": 0.741,
"GMD": 72.94,
"GNF": 8704.53,
"GTQ": 7.66,
"GYD": 209.17,
"HKD": 7.8,
"HNL": 26.19,
"HRK": 6.43,
"HTG": 130.87,
"HUF": 335.43,
"IDR": 16405.58,
"ILS": 3.34,
"IMP": 0.741,
"INR": 88.25,
"IQD": 1308.99,
"IRR": 43088.53,
"ISK": 122.22,
"JEP": 0.741,
"JMD": 160.13,
"JOD": 0.709,
"JPY": 148.21,
"KES": 129.11,
"KGS": 87.38,
"KHR": 4012.54,
"KID": 1.53,
"KMF": 420.06,
"KRW": 1387.66,
"KWD": 0.305,
"KYD": 0.833,
"KZT": 536.85,
"LAK": 21714.01,
"LBP": 89500,
"LKR": 301.75,
"LRD": 200.48,
"LSL": 17.61,
"LYD": 5.43,
"MAD": 9.08,
"MDL": 16.67,
"MGA": 4474.6,
"MKD": 52.61,
"MMK": 2099.18,
"MNT": 3568.11,
"MOP": 8.03,
"MRU": 39.95,
"MUR": 46.15,
"MVR": 15.43,
"MWK": 1735.52,
"MXN": 18.71,
"MYR": 4.22,
"MZN": 63.57,
"NAD": 17.61,
"NGN": 1524.54,
"NIO": 36.76,
"NOK": 10.02,
"NPR": 141.2,
"NZD": 1.7,
"OMR": 0.384,
"PAB": 1,
"PEN": 3.52,
"PGK": 4.17,
"PHP": 56.74,
"PKR": 283.58,
"PLN": 3.63,
"PYG": 7224.64,
"QAR": 3.64,
"RON": 4.34,
"RSD": 100.12,
"RUB": 81.28,
"RWF": 1452.2,
"SAR": 3.75,
"SBD": 8.3,
"SCR": 14.79,
"SDG": 458.72,
"SEK": 9.39,
"SGD": 1.29,
"SHP": 0.741,
"SLE": 23.29,
"SLL": 23290.25,
"SOS": 571.13,
"SRD": 38.91,
"SSP": 4544.95,
"STN": 20.92,
"SYP": 12893.45,
"SZL": 17.61,
"THB": 32.11,
"TJS": 9.49,
"TMT": 3.5,
"TND": 2.9,
"TOP": 2.36,
"TRY": 41.27,
"TTD": 6.78,
"TVD": 1.53,
"TWD": 30.43,
"TZS": 2491.13,
"UAH": 41.21,
"UGX": 3504.97,
"USD": 1,
"UYU": 40.07,
"UZS": 12641.56,
"VES": 154.01,
"VND": 26257.92,
"VUV": 119.28,
"WST": 2.75,
"XAF": 560.08,
"XCD": 2.7,
"XCG": 1.79,
"XDR": 0.73,
"XOF": 560.08,
"XPF": 101.89,
"YER": 239.83,
"ZAR": 17.61,
"ZMW": 23.93,
"ZWL": 26.71
},
"terms": "https://www.exchangerate-api.com/terms",
"provider": "https://www.exchangerate-api.com",
"time_last_updated": 1757289601,
"WARNING_UPGRADE_TO_V6": "https://www.exchangerate-api.com/docs/free"
}
]
},
"connections": {
"Merge": {
"main": [
[
{
"node": "Format Email Content",
"type": "main",
"index": 0
}
]
]
},
"Daily 8AM Trigger": {
"main": [
[
{
"node": "Get Fiat Exchange Rates",
"type": "main",
"index": 0
},
{
"node": "Get Crypto Prices",
"type": "main",
"index": 0
}
]
]
},
"Get Crypto Prices": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Format Email Content": {
"main": [
[
{
"node": "Send Daily Currency Email",
"type": "main",
"index": 0
}
]
]
},
"Get Fiat Exchange Rates": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
中级 - 加密货币交易
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用CoinGecko和ExchangeRate-API创建BTC-ETH价格和美元汇率API
使用CoinGecko和ExchangeRate-API创建BTC/ETH价格和美元汇率API
Code
Merge
Webhook
+3
7 节点David Olusola
加密货币交易
比特币和以太坊加密货币下跌警报(Telegram、Slack 和 SMS)
通过 Telegram、Slack 和 SMS 发送比特币和以太坊加密货币下跌警报
If
Code
Slack
+5
8 节点David Olusola
加密货币交易
使用 CoinGecko 通过邮件/SMS 监控比特币和以太坊价格告警
使用 CoinGecko 通过邮件/SMS 监控比特币和以太坊价格告警
If
Code
Gmail
+4
8 节点David Olusola
加密货币交易
使用Gemini AI将GitHub热门仓库自动生成周教程并发布到WordPress
使用Gemini AI将GitHub热门仓库自动生成周教程并发布到WordPress
Code
Split Out
Email Send
+6
9 节点David Olusola
内容创作
使用 CoinGecko 和 ExchangeRate-API 跟踪加密货币价格和汇率至 Notion
使用 CoinGecko 和 ExchangeRate-API 跟踪加密货币价格和汇率至 Notion
Code
Merge
Notion
+3
7 节点David Olusola
杂项
多模型共识与 Telegram 提醒的 AI 股票分析
基于多模型共识和 Telegram 提醒的 AI 股票分析系统
Set
Code
Merge
+8
27 节点DevCode Journey
加密货币交易
工作流信息
难度等级
中级
节点数量11
分类1
节点类型6
作者
David Olusola
@dae221I help ambitious businesses eliminate operational bottlenecks and scale faster with AI automation. My clients typically see 40-60% efficiency gains within 90 days. Currently accepting 3 new projects this quarter - david@daexai.com
外部链接
在 n8n.io 查看 →
分享此工作流