AutomationFlowsSlack & Telegram › Fetch New Proposals

Fetch New Proposals

Fetch New Proposals. Uses httpRequest, mongoDb, telegram. Manual trigger; 16 nodes.

Manual trigger★★★★☆ complexity16 nodesHTTP RequestMongoDBTelegram
Slack & Telegram Trigger: Manual Nodes: 16 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Telegram 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 →

Download .json
{
  "nodes": [
    {
      "parameters": {
        "url": "https://polkadot-api.subsquare.io/gov2/referendums",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "simple",
              "value": "false"
            },
            {
              "name": "page_size",
              "value": "5"
            },
            {
              "name": "page",
              "value": "1"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            },
            {
              "name": "User-Agent",
              "value": "trustless-core-dao"
            }
          ]
        },
        "options": {}
      },
      "id": "aca8aacd-f781-4a27-9639-e521bb756e40",
      "name": "Fetch Polkadot Proposals1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -800,
        2912
      ]
    },
    {
      "parameters": {
        "url": "https://kusama-api.subsquare.io/gov2/referendums",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "simple",
              "value": "false"
            },
            {
              "name": "page_size",
              "value": "5"
            },
            {
              "name": "page",
              "value": "1"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            },
            {
              "name": "User-Agent",
              "value": "trustless-core-dao"
            }
          ]
        },
        "options": {}
      },
      "id": "b065c555-8dac-4f5e-b5d7-10b8b5e0abe3",
      "name": "Fetch Kusama Proposals1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -800,
        3104
      ]
    },
    {
      "parameters": {},
      "id": "e354e085-2592-49d6-84df-25459559923d",
      "name": "Wait for Both APIs1",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.1,
      "position": [
        -576,
        3008
      ]
    },
    {
      "parameters": {
        "jsCode": "// Get responses from both APIs via the merge node\nconst items = $input.all();\nlet allItems = [];\n\n// Process each input item\nitems.forEach((item, index) => {\n  const response = item.json;\n  let apiItems = [];\n  \n  // Handle both array and object responses\n  if (Array.isArray(response)) {\n    apiItems = response[0]?.items || [];\n  } else {\n    apiItems = response.items || [];\n  }\n  \n  // Determine source chain based on input index (0 = Polkadot, 1 = Kusama)\n  const sourceChain = index === 0 ? 'polkadot' : 'kusama';\n  const subdomain = index === 0 ? 'polkadot' : 'kusama';\n  \n  // Process items for this chain\n  apiItems.forEach(apiItem => {\n    allItems.push({\n      json: {\n        subsquare_id: `${sourceChain}_${apiItem._id}`, // Prefix to avoid conflicts\n        referendumIndex: apiItem.referendumIndex,\n        title: apiItem.title,\n        proposer: apiItem.proposer,\n        content: apiItem.content,\n        summary: apiItem.contentSummary?.summary || '',\n        track: apiItem.track,\n        state: apiItem.state?.name || '',\n        createdAt: apiItem.createdAt,\n        source_chain: sourceChain,\n        proposalLink: `https://${subdomain}.subsquare.io/referenda/${apiItem.referendumIndex}`\n      }\n    });\n  });\n});\n\nreturn allItems;"
      },
      "id": "4522a15d-ac08-4a2d-8b38-a88e2f7579da",
      "name": "Extract & Merge Items1",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -352,
        3008
      ]
    },
    {
      "parameters": {
        "interval": 10,
        "unit": "minutes"
      },
      "id": "01622d77-247b-429f-be0e-fcfe7222ea2b",
      "name": "Interval Trigger2",
      "type": "n8n-nodes-base.interval",
      "typeVersion": 1,
      "position": [
        -1024,
        3008
      ]
    },
    {
      "parameters": {
        "collection": "proposals",
        "options": {
          "limit": 1
        },
        "query": "={ \"subsquare_id\": \"{{ $json.subsquare_id }}\" }"
      },
      "id": "1a46d8f3-3801-4097-8f81-eece49c13f8b",
      "name": "Check if Exists2",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.2,
      "position": [
        96,
        2944
      ],
      "alwaysOutputData": true,
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "condition1",
              "leftValue": "={{ $json }}",
              "rightValue": 0,
              "operator": {
                "type": "object",
                "operation": "empty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "4d5a8268-561b-4913-8344-9f3c16673e0a",
      "name": "If New Proposal2",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        320,
        2944
      ]
    },
    {
      "parameters": {
        "jsCode": "// Get the original proposal data from Split In Batches\nconst proposalData = $('Split In Batches2').item.json;\n\n// Pass through the proposal data for storage\nreturn {\n  json: proposalData\n};"
      },
      "id": "2a6afd93-4899-4b2d-8424-d3667f82208e",
      "name": "Restore Proposal Data2",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        560,
        2784
      ]
    },
    {
      "parameters": {
        "operation": "insert",
        "collection": "proposals",
        "fields": "subsquare_id,referendumIndex,title,proposer,summary,track,state,createdAt,source_chain,proposalLink",
        "options": {}
      },
      "id": "09de7f27-f2cb-43bb-8265-70d043b01023",
      "name": "Store in MongoDB2",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.2,
      "position": [
        752,
        2864
      ],
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "text": "={{ $json.message }}",
        "additionalFields": {
          "appendAttribution": false,
          "disable_web_page_preview": false,
          "parse_mode": "Markdown"
        }
      },
      "id": "41a61e09-f163-42a0-9160-1b48c71ff573",
      "name": "Send Telegram Message2",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1456,
        2688
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "b7025ecb-6e76-413f-9bfa-32e9b8ce410c",
      "name": "Split In Batches2",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -128,
        3008
      ]
    },
    {
      "parameters": {},
      "id": "6bc53625-5b5a-4d72-88d1-23a97aad2808",
      "name": "Loop Over Items2",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1664,
        2960
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "condition1",
              "leftValue": "={{ $json.source_chain }}",
              "rightValue": "kusama",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "0f299c62-ee7f-40fc-bfc7-ef6de66483ac",
      "name": "Check Chain Type",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        784,
        2688
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://kusama.api.subscan.io/api/scan/search",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "YOUR_SUBSCAN_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "key",
              "value": "={{ $json.proposer }}"
            },
            {
              "name": "row",
              "value": "10"
            },
            {
              "name": "page",
              "value": "0"
            }
          ]
        },
        "options": {
          "redirect": {
            "redirect": {}
          }
        }
      },
      "id": "00fca329-0c1b-47f5-add7-c635dce56ee2",
      "name": "Get Kusama Proposer Info",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1008,
        2576
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://polkadot.api.subscan.io/api/scan/search",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "YOUR_SUBSCAN_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "key",
              "value": "={{ $json.proposer }}"
            },
            {
              "name": "row",
              "value": "10"
            },
            {
              "name": "page",
              "value": "0"
            }
          ]
        },
        "options": {
          "redirect": {
            "redirect": {}
          }
        }
      },
      "id": "17ab109c-4deb-4640-ad66-99e4e5131add",
      "name": "Get Polkadot Proposer Info",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1008,
        2800
      ]
    },
    {
      "parameters": {
        "jsCode": "// Get the proposal data from Split In Batches node\nconst proposalData = $('Restore Proposal Data2').item.json;\n\n// Get the proposer info from the API response\nconst proposerResponse = $input.first().json;\nlet proposerName = proposalData.proposer; // fallback to address\n\n// Try to extract display name from the API response\ntry {\n  if (proposerResponse?.data?.account) {\n    const accountData = proposerResponse.data.account;\n    if (accountData?.account_display?.people?.display) {\n      proposerName = accountData.account_display.people.display;\n    } else if (accountData?.display) {\n      proposerName = accountData.display;\n    }\n  }\n} catch (error) {\n  // If parsing fails, keep the original proposer address\n  console.log('Failed to parse proposer info:', error);\n}\n\n// Capitalize the chain name for the message title\nconst chainName = proposalData.source_chain.charAt(0).toUpperCase() + proposalData.source_chain.slice(1);\n\n// Format the Telegram message with chain-specific title\nconst message = `\ud83d\udd14 *New ${chainName} Proposal on Opensquare #${proposalData.referendumIndex}*\n\n*Proposal Title:* ${proposalData.title}\n\n*Proposer:* ${proposerName}\n\n*Summary:* ${proposalData.summary}\n\n*Proposal link:* ${proposalData.proposalLink}`;\n\nreturn {\n  json: {\n    message: message,\n    referendumIndex: proposalData.referendumIndex,\n    title: proposalData.title,\n    proposer: proposerName,\n    summary: proposalData.summary,\n    source_chain: proposalData.source_chain,\n    proposalLink: proposalData.proposalLink\n  }\n};"
      },
      "id": "d12825c0-28da-4bbc-8199-8b05582f62fa",
      "name": "Format Message3",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1232,
        2688
      ]
    }
  ],
  "connections": {
    "Fetch Polkadot Proposals1": {
      "main": [
        [
          {
            "node": "Wait for Both APIs1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Kusama Proposals1": {
      "main": [
        [
          {
            "node": "Wait for Both APIs1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Wait for Both APIs1": {
      "main": [
        [
          {
            "node": "Extract & Merge Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract & Merge Items1": {
      "main": [
        [
          {
            "node": "Split In Batches2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Interval Trigger2": {
      "main": [
        [
          {
            "node": "Fetch Polkadot Proposals1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Kusama Proposals1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if Exists2": {
      "main": [
        [
          {
            "node": "If New Proposal2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If New Proposal2": {
      "main": [
        [
          {
            "node": "Restore Proposal Data2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Restore Proposal Data2": {
      "main": [
        [
          {
            "node": "Store in MongoDB2",
            "type": "main",
            "index": 0
          },
          {
            "node": "Check Chain Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Telegram Message2": {
      "main": [
        [
          {
            "node": "Loop Over Items2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split In Batches2": {
      "main": [
        [],
        [
          {
            "node": "Check if Exists2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items2": {
      "main": [
        [
          {
            "node": "Split In Batches2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Chain Type": {
      "main": [
        [
          {
            "node": "Get Kusama Proposer Info",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Polkadot Proposer Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Kusama Proposer Info": {
      "main": [
        [
          {
            "node": "Format Message3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Polkadot Proposer Info": {
      "main": [
        [
          {
            "node": "Format Message3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Message3": {
      "main": [
        [
          {
            "node": "Send Telegram Message2",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Fetch New Proposals. Uses httpRequest, mongoDb, telegram. Manual trigger; 16 nodes.

Source: https://gist.github.com/nomadbitcoin/25fbe529f2412dec565f2c172ebe9c45 — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

This workflow automates quiz delivery from a Google Sheet directly into a Telegram group. It ensures that quizzes are posted one by one as polls, and once a quiz is sent, its status in the sheet is au

Google Sheets, HTTP Request, Telegram
Slack & Telegram

Telegram Wait. Uses emailReadImap, telegram, httpRequest, stickyNote. Manual trigger; 7 nodes.

Email Read Imap, Telegram, HTTP Request
Slack & Telegram

N8N Complete Final. Uses telegramTrigger, dataTable, telegram, mqtt. Event-driven trigger; 58 nodes.

Telegram Trigger, Data Table, Telegram +3
Slack & Telegram

TextMain. Uses telegramTrigger, stopAndError, telegram, httpRequest. Event-driven trigger; 56 nodes.

Telegram Trigger, Stop And Error, Telegram +2
Slack & Telegram

Pede Ai. Uses httpRequest, telegram, postgres, telegramTrigger. Event-driven trigger; 53 nodes.

HTTP Request, Telegram, Postgres +1