australian_capital_dao/n8n.json

570 lines
22 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"name": "DAOHaus Alerts",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "530c914a-c732-4cb6-aaf1-2b722f9e7398",
"options": {}
},
"id": "def14e6f-a3fc-4844-8a94-b2d3a0a9bdb5",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1.1,
"position": [
660,
540
],
"webhookId": "530c914a-c732-4cb6-aaf1-2b722f9e7398"
},
{
"parameters": {
"method": "POST",
"url": "https://opt-mainnet.g.alchemy.com/v2/{alchemy_api_key}",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"id\": 1,\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getTransactionReceipt\",\n \"params\": [\n\"{{ $json[\"body\"][\"event\"][\"activity\"][0][\"hash\"] }}\"\n ]\n}",
"options": {}
},
"id": "b97eaff4-26f2-4230-b3e2-3eb14b5cbbba",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1160,
540
]
},
{
"parameters": {
"authentication": "webhook",
"options": {},
"embeds": {
"values": [
{
"description": "={{ $json[\"message\"] }}\n\n{{ $json[\"proposalURL\"] }}",
"author": "Australian Capital DAO",
"color": "#FF00D9",
"timestamp": "={{ ($now.minus({hours:10})).toFormat('yyyy-LL-dd HH:mm:ss') }}\n",
"title": "New DAO TX",
"url": "={{ $json[\"explorer\"] }}"
}
]
}
},
"id": "8e49fb62-06a1-4e51-898c-c17e1eb5dae0",
"name": "Discord2",
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
1960,
420
],
"credentials": {
"discordWebhookApi": {
"id": "XzOnTbxymIRJMNFK",
"name": "N8N Channel"
}
}
},
{
"parameters": {
"chatId": "-4260162868",
"text": "={{ $json[\"message\"] }}",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "View tx on Etherscan",
"additionalFields": {
"url": "={{ $json[\"explorer\"] }}"
}
},
{
"text": "View Proposal",
"additionalFields": {
"url": "={{ $json[\"proposalURL\"] }}"
}
}
]
}
}
]
},
"additionalFields": {
"appendAttribution": false
}
},
"id": "2577c299-f86e-46d2-8799-e4e10875e3c7",
"name": "Telegram",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.1,
"position": [
1960,
640
],
"credentials": {
"telegramApi": {
"id": "VWQskb1y7DoFEnMh",
"name": "Telegram account"
}
}
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"id": "245d297b-8838-441e-b206-1f9cfdff8591",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.1,
"position": [
480,
940
],
"webhookId": "47a00ca7-1eb5-408d-8846-4af7f8b1e36b",
"credentials": {
"telegramApi": {
"id": "VWQskb1y7DoFEnMh",
"name": "Telegram account"
}
}
},
{
"parameters": {
"authentication": "webhook",
"content": "=New message from: {{ $json[\"message\"][\"from\"][\"first_name\"] }} (username: {{ $json[\"message\"][\"from\"][\"username\"] }}) (ID: {{ $json[\"message\"][\"from\"][\"id\"] }})\nChat Title: {{ $json[\"message\"][\"chat\"][\"title\"] }}\nChat ID: {{ $json[\"message\"][\"chat\"][\"id\"] }}\nChat Type: {{ $json[\"message\"][\"chat\"][\"type\"] }}\nMessage text: {{ $json[\"message\"][\"text\"] }}",
"options": {}
},
"id": "ce165915-be3e-49f2-b9e8-308f98e37ffd",
"name": "Discord3",
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
1560,
900
],
"credentials": {
"discordWebhookApi": {
"id": "XzOnTbxymIRJMNFK",
"name": "N8N Channel"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "ca511fdf-180b-4236-b474-3bfe439ded0c",
"leftValue": "={{ $json[\"body\"][\"event\"][\"activity\"].length }}",
"rightValue": 1,
"operator": {
"type": "number",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "9536c45d-ae2a-472d-87f5-2b4535150128",
"name": "If1",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
880,
540
]
},
{
"parameters": {
"jsCode": "function hexToDecimal(hex) {\n return parseInt(hex, 16);\n}\nfunction stripExtraZeros(hexString) {\n // Remove leading zeros while keeping at least \"0x\" if present\n hexString = hexString.replace(/^0x0+/, '');\n return \"0x\"+hexString;\n}\n\n\n\nconst topics = {\n \"0xb9956173924f9c1204bae41dd3737d7ed1161846d13183879cdc03c4b9f8d019\":\"Submit Proposal\",\n \"0x786755545a7e27c12c90cc7f0934514d03fdacfe3684a340b8c4100531e7ecd5\":\"Submit Vote\",\n \"0xb4571f7e4e2c2b6e6185e47ab5caa5fe34087299bd49fbae945a4583101ee3f0\":\"Process Proposal\",\n \"0xd45ad122361f16d6f50d7c4a73638f20ee48eff6186af15224e2a4a1f6d50171\":\"Sponsor Proposal\"\n};\n\nvar Logs = $('HTTP Request').first().json.result.logs;\nvar topicsFromLogs = [];\n\nfor (var i = 0; i < Logs.length; i++) {\n var log = Logs[i];\n topicsFromLogs.push(...log.topics); // Using spread operator to append topics array\n}\n\nvar data = {\n \"method\":\"Unknown method\"\n};\n\nconst opts = {\n \"Submit Vote\":{\n 1:\"member\",\n 2:\"proposal\",\n 3:\"vote\"\n },\n \"Submit Proposal\":{\n 1:\"proposal\",\n 2:\"dataHash\"\n },\n \"Process Proposal\":{\n 1:\"member\",\n 2:\"proposal\",\n 3:\"vote\"\n },\n \"Sponsor Proposal\":{\n 1:\"member\",\n 2:\"proposal\",\n 3:\"votingStarts\"\n }\n}\n\n\n// Check each topic in the logs against the topics object\nfor (let i = 0; i < topicsFromLogs.length; i++) {\n const topic = topicsFromLogs[i];\n if (topics.hasOwnProperty(topic)) {\n data[\"method\"] = topics[topic];\n console.log('Matched Option:', data[\"method\"]);\n } else {\n if (opts.hasOwnProperty(data[\"method\"])){\n var keys = opts[data[\"method\"]];\n if (keys[i] != \"member\"){\n data[keys[i]] = hexToDecimal(topic); \n } else {\n data[keys[i]] = stripExtraZeros(topic);\n }\n }\n }\n}\nfunction hexToUtf8(hexStr) {\n return Buffer.from(hexStr, 'hex').toString('utf8');\n}\n\nif (data[\"method\"]== \"Submit Proposal\"){\n const hexData = $('HTTP Request').first().json.result.logs[0].data;\n // Extracting segments from hexData (assuming it's already defined)\n const votingPeriodHex = hexData.slice(2, 66); // 64 characters (32 bytes) for votingPeriod\n const proposalDataHex = hexData.slice(66, 130); // 64 characters (32 bytes) for proposalData\n const expirationHex = hexData.slice(130, 194); // 64 characters (32 bytes) for expiration\n const baalGasHex = hexData.slice(194, 258); // 64 characters (32 bytes) for baalGas\n const selfSponsorHex = hexData.slice(258, 322); // 64 characters (32 bytes) for selfSponsor\n const timestampHex = hexData.slice(322, 386); // 64 characters (32 bytes) for timestamp\n const detailsHex = hexData.slice(386); // Remaining part for details\n \n // Decode hex segments into decimal or string format\n const votingPeriod = hexToDecimal(votingPeriodHex);\n const proposalData = proposalDataHex;\n const expiration = hexToDecimal(expirationHex);\n const baalGas = hexToDecimal(baalGasHex);\n const selfSponsor = hexToDecimal(selfSponsorHex);\n const timestamp = hexToDecimal(timestampHex);\n \n let detailsObj;\n detailsObj = hexToUtf8(detailsHex);\n const jsonStringStart = detailsObj.indexOf('{\"');\n if (jsonStringStart !== -1) {\n detailsObj = detailsObj.slice(jsonStringStart);\n }\n\n \n // Construct the JSON object\n const jsonObject = {\n votingPeriod: votingPeriod,\n proposalData: proposalData,\n expiration: expiration,\n baalGas: baalGas,\n selfSponsor: selfSponsor,\n timestamp: timestamp,\n details: detailsObj\n };\n\n data['data'] = jsonObject;\n} else if (data[\"method\"]== \"Submit Vote\"){\n const hexData = $('HTTP Request').first().json.result.logs[0].data;\n data[\"votes\"]= hexToDecimal(hexData)/1000000000000000000;\n} else if (data[\"method\"]== \"Process Proposal\"){\n var logData = []\n for (var i = 0; i < Logs.length; i++) {\n if (Logs[i].topics[0]==\"0xb4571f7e4e2c2b6e6185e47ab5caa5fe34087299bd49fbae945a4583101ee3f0\"){\n data[\"proposal\"] = hexToDecimal(Logs[i].topics[1]);\n }\n}\n\n\n}\n\nconsole.log(data);\nreturn data;\n"
},
"id": "eb7edb1c-a29d-4a55-9e69-3526edb2194a",
"name": "Parser",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1360,
540
]
},
{
"parameters": {
"jsCode": "function cleanJsonString(jsonString) {\n // Remove invisible and non-printable characters (excluding newlines, carriage returns, and tabs)\n const cleanedString = jsonString.replace(/[^\\x20-\\x7E\\r\\n\\t]+/g, '');\n \n // Remove leading or trailing whitespace\n const trimmedString = cleanedString.trim();\n \n // Ensure the string is enclosed within curly braces if its a JSON object\n if (!trimmedString.startsWith('{') || !trimmedString.endsWith('}')) {\n throw new Error('Invalid JSON format: Missing opening or closing brace.');\n }\n\n return trimmedString;\n}\n\nconst addressNames = {\n \"0x6cb4b39bec23a921c9a20d061bf17d4640b0d39e\":\"woodburn.au\" \n};\nfunction addressName(address) {\n if (addressNames.hasOwnProperty(address)){\n return addressNames[address];\n }\n return address;\n}\n\n\n\nvar message = \"New DAO transaction: \";\nconst parsed = $('Parser').first().json;\nmessage += parsed.method;\n\nif (parsed.method == \"Submit Vote\"){\n message += \"\\n\"+ addressName(parsed.member) + \" voted \";\n if (parsed.vote == 1){\n message += \"for\";\n } else {\n message += \"against\";\n }\n message += \" proposal #\"+parsed.proposal;\n message += \" using \" + parsed.votes + \" votes\";\n}\nelse if (parsed.method == \"Sponsor Proposal\"){\n message += \"\\n\"+ addressName(parsed.member) + \" sponsored \";\n message += \"proposal #\"+parsed.proposal;\n}\nelse if (parsed.method == \"Submit Proposal\"){\n message += \"\\n\"+ addressName($('HTTP Request').first().json.result.from);\n message += \" created proposal #\" + parsed.proposal;\n try {\n const cleanedJsonString = cleanJsonString(parsed.data.details);\n const details = JSON.parse(cleanedJsonString);\n message += \"\\nProposal: \" + details.title;\n message += \"\\nDescription: \" + details.description;\n\n if (details.contentURI != \"\"){\n message += \"\\nURL: \" + details.contentURI;\n }\n }\n catch (error){\n message += \"\\nProposal details failed to parse\";\n message += error;\n }\n}\nelse if (parsed.method == \"Process Proposal\"){\n message += \"\\n\"+ addressName($('HTTP Request').first().json.result.from);\n message += \" executed proposal #\" + parsed.proposal;\n}\n\n\n// message += \"\\n\\nhttps://optimistic.etherscan.io/tx/\";\n// message += $('HTTP Request').first().json.result.transactionHash;\n// message += \"\\nhttps://admin.daohaus.club/#/molochV3/0xa/0xf4604948ad5365840803297bf81cd9a46c36fce7/proposal/\"\n// message += parsed.proposal;\n\nreturn {\n \"message\":message,\n \"explorer\":\"https://optimistic.etherscan.io/tx/\"+$('HTTP Request').first().json.result.transactionHash,\n\"proposalURL\":\"https://admin.daohaus.club/#/molochV3/0xa/0xf4604948ad5365840803297bf81cd9a46c36fce7/proposal/\"+parsed.proposal\n};\n\n"
},
"id": "22c0ce02-9388-4dca-ac32-3fda22a4f280",
"name": "Create message",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1580,
500
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "21456147-b1d5-4cb6-877d-ffe7c567eec6",
"leftValue": "={{ $json[\"message\"][\"entities\"].length }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "notEquals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "cc10be80-8d35-43d0-84a7-78440d3b7801",
"name": "If",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
660,
1100
]
},
{
"parameters": {
"chatId": "={{ $json[\"message\"][\"chat\"][\"id\"] }}",
"text": "Pong",
"additionalFields": {
"appendAttribution": false,
"reply_to_message_id": "={{ $json[\"message\"][\"message_id\"] }}"
}
},
"id": "d6d67b9f-279f-4618-a2d4-14737449131f",
"name": "Ping Pong",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.1,
"position": [
1280,
1000
],
"credentials": {
"telegramApi": {
"id": "VWQskb1y7DoFEnMh",
"name": "Telegram account"
}
}
},
{
"parameters": {
"chatId": "={{ $json[\"message\"][\"chat\"][\"id\"] }}",
"text": "Sure here is the link to the Australian Capital DAO",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "Go to DAO Page",
"additionalFields": {
"url": "https://admin.daohaus.club/#/molochv3/0xa/0xf4604948ad5365840803297bf81cd9a46c36fce7"
}
}
]
}
}
]
},
"additionalFields": {
"appendAttribution": false,
"reply_to_message_id": "={{ $json[\"message\"][\"message_id\"] }}"
}
},
"id": "402477d9-701c-4d08-80d9-608c4b702881",
"name": "Dao Link",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.1,
"position": [
1280,
1160
],
"credentials": {
"telegramApi": {
"id": "VWQskb1y7DoFEnMh",
"name": "Telegram account"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"leftValue": "={{ $json[\"message\"][\"text\"] }}",
"rightValue": "/ping",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "4c2f8464-cf52-467d-a219-e75793559353",
"leftValue": "={{ $json[\"message\"][\"text\"] }}",
"rightValue": "/dao",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"id": "eb1090bf-5f39-4c8e-ac85-ed2e7b59e76e",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
960,
1080
]
}
],
"pinData": {
"Webhook": [
{
"json": {
"headers": {
"host": "n8n.woodburn.au",
"x-forwarded-scheme": "https",
"x-forwarded-proto": "https",
"x-forwarded-for": "118.208.168.176",
"x-real-ip": "118.208.168.176",
"content-length": "845",
"content-type": "application/json",
"user-agent": "insomnia/9.3.1",
"accept": "*/*"
},
"params": {},
"query": {},
"body": {
"webhookId": "wh_mvrhnhyqysvf70qj",
"id": "whevt_rc0mq97pww9a7leo",
"createdAt": "2024-07-18T05:46:57.824Z",
"type": "ADDRESS_ACTIVITY",
"event": {
"network": "OPT_MAINNET",
"activity": [
{
"fromAddress": "0xf4604948ad5365840803297bf81cd9a46c36fce7",
"toAddress": "0x35d3efffa0e6c63ee5c7e8c7dd7e7d6e961a6689",
"blockNum": "0x752694c",
"hash": "0x02d3f83b6663df1edc04db532190a17ef7a3267ca3104d7c36435eb2aad12b3f",
"value": 0,
"typeTraceAddress": "STATICCALL_0_0",
"asset": "ETH",
"category": "internal",
"rawContract": {
"rawValue": "0x0",
"decimals": 18
}
}
]
}
}
}
}
],
"Telegram Trigger": [
{
"json": {
"update_id": 328606253,
"message": {
"message_id": 34,
"from": {
"id": 5166524939,
"is_bot": false,
"first_name": "Nathan.Woodburn/",
"username": "nathanwoodburn",
"language_code": "en"
},
"chat": {
"id": -4260162868,
"title": "Test Bot Group",
"type": "group",
"all_members_are_administrators": true
},
"date": 1721355038,
"text": "/dao@australian_capital_dao_bot",
"entities": [
{
"offset": 0,
"length": 31,
"type": "bot_command"
}
]
}
}
}
]
},
"connections": {
"Webhook": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Parser",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Discord3",
"type": "main",
"index": 0
},
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"If1": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Parser": {
"main": [
[
{
"node": "Create message",
"type": "main",
"index": 0
}
]
]
},
"Create message": {
"main": [
[
{
"node": "Discord2",
"type": "main",
"index": 0
},
{
"node": "Telegram",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Ping Pong",
"type": "main",
"index": 0
}
],
[
{
"node": "Dao Link",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "4d31c171-d9e4-47a8-8a76-4a56b6fd3101",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "716fbd4310435337bb8df7c59b7984bfb867d59d9129682cbc4d8523a713d40e"
},
"id": "POAYZQJI8PYGlKWt",
"tags": []
}