This workflow corresponds to n8n.io template #8992 — we link there as the canonical source.
This workflow follows the Discord → HTTP Request 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "220614c6-c32f-41ba-9669-2532c13a21f6",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "45 7,17 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "2fbe1f25-d09c-43da-933e-6903c6b2155b",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
208,
0
],
"parameters": {
"url": "=https://api.etherscan.io/v2/api?chainid=1&module=account&action=tokentx&address=YOUR_WALLET_HERE&sort=asc&apikey=YOUR_KEY_HERE",
"method": "=GET",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "755d4d95-2ff5-4023-8c37-005dc7f3ea69",
"name": "Code in JavaScript",
"type": "n8n-nodes-base.code",
"position": [
416,
0
],
"parameters": {
"jsCode": "// Input: JSON response from Etherscan tokentx endpoint\nconst wallet = \"YOUR_WALLET_ADDRESS\".toLowerCase();\nconst txs = items[0].json.result; // Assuming the HTTP node passed the Etherscan JSON\n\n// Reduce transactions into balances\nconst balances = {};\n\nfor (const tx of txs) {\n const symbol = tx.tokenSymbol;\n const decimals = parseInt(tx.tokenDecimal);\n const value = BigInt(tx.value);\n\n // Initialize token entry if missing\n if (!balances[symbol]) {\n balances[symbol] = {\n contract: tx.contractAddress,\n tokenName: tx.tokenName,\n tokenSymbol: tx.tokenSymbol,\n decimals: decimals,\n raw: BigInt(0)\n };\n }\n\n // If wallet is the recipient => add\n if (tx.to.toLowerCase() === wallet) {\n balances[symbol].raw += value;\n }\n\n // If wallet is the sender => subtract\n if (tx.from.toLowerCase() === wallet) {\n balances[symbol].raw -= value;\n }\n}\n\n// Convert raw balances to human-readable\nconst results = Object.values(balances).map(t => {\n return {\n token: t.tokenSymbol,\n contract: t.contract,\n amount: Number(t.raw) / (10 ** t.decimals),\n decimals: t.decimals\n };\n});\n\n// Return in N8N format\nreturn results.map(r => ({ json: r }));\n"
},
"typeVersion": 2
},
{
"id": "4abe9847-da8e-47a2-ae69-5918545e0cc1",
"name": "Code in JavaScript1",
"type": "n8n-nodes-base.code",
"position": [
624,
0
],
"parameters": {
"jsCode": "const balances = items.map(i => i.json);\n\n// Join all contract addresses into a comma-separated string\nconst contracts = balances.map(b => b.contract).join(',');\n\n// Pass both balances and contracts downstream\nreturn [\n {\n json: {\n balances,\n contracts\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "dd3ca09d-2eb4-45e0-ad0d-dc9c7f093404",
"name": "HTTP Request1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1456,
0
],
"parameters": {
"url": "=https://api.coingecko.com/api/v3/simple/token_price/ethereum?contract_addresses={{ $('Code in JavaScript1').item.json.contracts }}&vs_currencies=usd",
"options": {},
"jsonHeaders": "{\n \"accept\": \"application/json\",\n \"x-cg-demo-api-key\": \"COIN_GECKO_KEY_HERE\"\n}\n",
"sendHeaders": true,
"specifyHeaders": "json"
},
"typeVersion": 4.2
},
{
"id": "21538827-f180-4012-ac7d-7567da5f251c",
"name": "Code in JavaScript2",
"type": "n8n-nodes-base.code",
"position": [
1664,
0
],
"parameters": {
"jsCode": "// ---- Pull inputs safely ----\nconst erc20 = $node[\"Code in JavaScript1\"].json?.balances ?? [];\nconst eth = $node[\"Code ETH Balance\"].json ?? null;\n\nconst cgTokenPrices = $node[\"HTTP Request1\"].json ?? {}; // { [contract]: { usd } }\nconst ethUsd = $node[\"HTTP Request ETH Price\"].json?.ethereum?.usd ?? 0;\n\n// ---- Combine balances (ETH + ERC-20) ----\nconst balances = eth ? [eth, ...erc20] : [...erc20];\n\n// ---- Build a single price map (token prices + ETH) ----\nconst priceMap = { ...cgTokenPrices };\n// Give ETH a fake \"contract\" key so it matches by contract like the tokens\nconst ETH_KEY = \"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\";\npriceMap[ETH_KEY] = { usd: ethUsd };\n\n// ---- Enrich balances with prices ----\nconst enriched = balances.map(b => {\n const key = (b.contract || \"\").toLowerCase();\n const usdPrice = priceMap[key]?.usd ?? 0;\n const amount = Number(b.amount || 0); // already human-readable amounts\n const usdValue = amount * usdPrice;\n\n return {\n token: b.token,\n contract: b.contract,\n amount,\n usdPrice,\n usdValue,\n };\n}).sort((a, b) => b.usdValue - a.usdValue);\n\n// ---- Totals & quick diagnostics ----\nconst totalUsd = enriched.reduce((s, t) => s + (t.usdValue || 0), 0);\nconst ethLine = enriched.find(t => t.token === \"ETH\");\nconst ethUsdValue = ethLine ? ethLine.usdValue : 0;\nconst restUsd = totalUsd - ethUsdValue;\n\n// ---- Discord message ----\nlet message = `**ETH Wallet Update \ud83d\udcb0**\\n\\n`;\nmessage += `**Total Value:** $${totalUsd.toFixed(2)} USD\\n`;\nif (ethLine) {\n message += `\u2022 ETH: ${ethLine.amount.toFixed(6)} @ $${(ethLine.usdPrice||0).toFixed(2)} = $${ethUsdValue.toFixed(2)}\\n`;\n message += `\u2022 Other tokens (priced): $${restUsd.toFixed(2)}\\n\\n`;\n} else {\n message += `\u2022 No ETH price/balance found\\n\\n`;\n}\n\nmessage += enriched\n .filter(t => t.usdValue > 0.01)\n .map(t => `${t.token}: $${t.usdValue.toFixed(2)} (px $${t.usdPrice.toFixed(6)})`)\n .join(\"\\n\");\n\nreturn [{\n json: {\n totalUsd,\n tokens: enriched,\n discordMessage: message\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "a6dffe53-b602-40dc-bd08-87175da21bab",
"name": "Discord",
"type": "n8n-nodes-base.discord",
"position": [
1872,
0
],
"parameters": {
"content": "={{ $json.discordMessage }}",
"options": {},
"authentication": "webhook"
},
"credentials": {
"discordWebhookApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "f01b5fec-fdb8-42a5-9abf-6676a47ca321",
"name": "HTTP Request ETH",
"type": "n8n-nodes-base.httpRequest",
"position": [
832,
0
],
"parameters": {
"url": "https://api.etherscan.io/v2/api?chainid=1&module=account&action=balance&address=YOUR_WALLET_HERE&apikey=YOUR_TOKEN_HERE",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "8c0c8162-c9c4-442e-be11-1a8820ce43e4",
"name": "Code ETH Balance",
"type": "n8n-nodes-base.code",
"position": [
1040,
0
],
"parameters": {
"jsCode": "const wei = BigInt($node[\"HTTP Request ETH\"].json.result);\nconst eth = Number(wei) / 1e18;\n\nreturn [{\n json: {\n token: \"ETH\",\n contract: \"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\", // dummy\n amount: eth,\n decimals: 18\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "b7de03cb-f775-4aea-8445-d401ecca2f31",
"name": "HTTP Request ETH Price",
"type": "n8n-nodes-base.httpRequest",
"position": [
1248,
0
],
"parameters": {
"url": "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd",
"options": {},
"jsonHeaders": "{\n \"accept\": \"application/json\",\n \"x-cg-demo-api-key\": \"COIN_GEKCO_KEY_HERE\"\n}\n",
"sendHeaders": true,
"specifyHeaders": "json"
},
"typeVersion": 4.2
},
{
"id": "85e8bac4-d42a-4d36-8496-2d1e6d19ea04",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1264,
-160
],
"parameters": {
"height": 96,
"content": "## Set Coin Gecko Keys Here"
},
"typeVersion": 1
},
{
"id": "39647a8d-f10f-4cc2-aefe-1f53d304e59c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
-240
],
"parameters": {
"height": 192,
"content": "## Add Etherscan API Key to first 2 HTTP nodes. Add Wallet Address to Code Block as well."
},
"typeVersion": 1
},
{
"id": "1b94d811-6947-46a1-b6b7-e928d74b7c73",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-176,
-288
],
"parameters": {
"height": 256,
"content": "## Daily ETH Wallet Balance sent to Discord. Currently you get two updates. One in the Morning and Evening."
},
"typeVersion": 1
}
],
"connections": {
"HTTP Request": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "Code in JavaScript2",
"type": "main",
"index": 0
}
]
]
},
"Code ETH Balance": {
"main": [
[
{
"node": "HTTP Request ETH Price",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request ETH": {
"main": [
[
{
"node": "Code ETH Balance",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Code in JavaScript1",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript1": {
"main": [
[
{
"node": "HTTP Request ETH",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript2": {
"main": [
[
{
"node": "Discord",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request ETH Price": {
"main": [
[
{
"node": "HTTP Request1",
"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.
discordWebhookApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Never miss a snapshot of your (or others) ETH wallet, this workflow polls your wallet on a schedule, fetches balances and current ETH prices, formats a concise summary, and posts it to Discord (or email/Slack/Telegram). Easy to customize to track multiple wallets, tokens, or…
Source: https://n8n.io/workflows/8992/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
I wanted a journal but never had the discipline to write one. Most of my day happens in Discord anyway, so I built this to do it for me.
This workflow monitors product prices from BooksToScrape and sends alerts to a Discord channel via webhook when competitor's prices are lower than our prices. Schedule (for daily or required schedule)
This workflow provides an automated, intelligent solution for global weather monitoring. It goes beyond simple data fetching by calculating a custom "Comfort Index" and using AI to provide human-like
AmazonLuna-Games-Fetch. Uses httpRequest, scheduleTrigger, googleSheets, stickyNote. Scheduled trigger; 16 nodes.
This n8n workflow monitors Donald Trump’s Truth Social posts and sends alerts to Telegram & Discord on auto-pilot. Stay instantly updated with every new post, repost, or reply without delays.