Telegram + Postgres quizzes with scoring and rankings
Running a quiz in chat sounds simple until you’re copying answers into spreadsheets, chasing missing replies, and arguing with yourself about what “counts” as correct. Then someone asks for rankings. Or a clean report. And the whole thing turns into admin work.
HR managers feel it when training compliance is due. An educator running weekly tests runs into the same wall. So does a team lead onboarding new hires. This Telegram quiz scoring automation keeps the quiz in Telegram and puts the data where it belongs, in a database, scored and ready.
Below you’ll see how the workflow runs, what it automates end-to-end, and what you can tweak to match your scoring style and tone.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Telegram + Postgres quizzes with scoring and rankings
flowchart LR
subgraph sg0["Telegram Flow"]
direction LR
n0@{ icon: "mdi:swap-horizontal", form: "rounded", label: "For Tests", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Test"]
n2@{ icon: "mdi:cog", form: "rounded", label: "Randomize questions", pos: "b", h: 48 }
n3@{ icon: "mdi:cog", form: "rounded", label: "Wait", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-vertical", form: "rounded", label: "Variables", pos: "b", h: 48 }
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Question"]
n7@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Commands", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Buttons", pos: "b", h: 48 }
n9@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>List tests"]
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Main Menu"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update Bot Status on start"]
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Telegram Trigger"]
n14@{ icon: "mdi:swap-vertical", form: "rounded", label: "Initialization", pos: "b", h: 48 }
n15@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Any questions?", pos: "b", h: 48 }
n16["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Delete message"]
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Code"]
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Questions AND Answers"]
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Update Answer"]
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Non-Answered Questions"]
n21["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Tests"]
n22@{ icon: "mdi:swap-vertical", form: "rounded", label: "Union Number with Question", pos: "b", h: 48 }
n23@{ icon: "mdi:cog", form: "rounded", label: "Union list", pos: "b", h: 48 }
n24["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Get Test"]
n25["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Result Test"]
n26["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Calculate answers"]
n27["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/postgres.svg' width='40' height='40' /></div><br/>Upsert pred Answer"]
n28@{ icon: "mdi:swap-vertical", form: "rounded", label: "Variables TG", pos: "b", h: 48 }
n29@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Is Start?", pos: "b", h: 48 }
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Welcome Message"]
n31["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/telegram.svg' width='40' height='40' /></div><br/>Error"]
n17 --> n5
n1 --> n18
n3 --> n16
n5 --> n27
n9 --> n8
n9 --> n7
n8 --> n11
n8 --> n0
n7 --> n21
n7 --> n31
n24 --> n1
n6 --> n3
n0 --> n21
n0 --> n24
n0 --> n19
n21 --> n22
n29 --> n30
n29 --> n9
n11 --> n12
n4 --> n5
n23 --> n10
n28 --> n14
n19 --> n20
n15 --> n2
n15 --> n26
n14 --> n29
n13 --> n28
n26 --> n25
n27 --> n6
n2 --> n17
n2 --> n4
n18 --> n2
n20 --> n15
n22 --> n23
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n13 trigger
class n0,n7,n8,n9,n15,n29 decision
class n12,n18,n19,n20,n21,n24,n26,n27 database
class n17 code
classDef customIcon fill:none,stroke:none
class n1,n5,n6,n10,n11,n12,n13,n16,n17,n18,n19,n20,n21,n24,n25,n26,n27,n30,n31 customIcon
The Problem: Quizzes in chat get messy fast
Collecting answers in Telegram (or any chat) is easy. Managing them is the painful part. You end up scrolling through threads to find who answered what, then retyping it somewhere “official” so you can score it. Miss one message and the results are wrong. Add a second quiz, a second cohort, or a second reviewer, and you’re suddenly dealing with inconsistent scoring, duplicated attempts, and reports that don’t match what participants saw in the chat.
The friction compounds. It’s not one big failure, it’s dozens of small ones that steal your attention.
- Answers live in Telegram history, which means reporting starts with searching and guessing.
- Manual scoring invites inconsistency, especially when multiple people run the same test.
- Participants ask “how did I do?” and you spend another hour compiling rankings.
- When you want trends over time, the data is too messy to trust.
The Solution: Telegram quizzes logged, scored, and ranked in Postgres
This n8n workflow turns Telegram into the front door for quizzes, then uses Postgres as the system of record. A participant starts in the Telegram bot, the workflow checks where they are in the process, and it routes them to the right place (menu, test list, or the next unanswered question). Questions and answers are pulled from Postgres, the workflow shuffles the order, and then delivers each question in chat. Each response gets recorded back into Postgres immediately, so you’re not depending on someone to “save it later.” At the end, results are computed in the database and the participant gets their outcome plus a ranking view, right inside Telegram.
The workflow starts with a Telegram message to your bot. It then fetches the test content from Postgres, sends questions one-by-one, and logs every answer as it comes in. Finally, it calculates the score and shares the participant’s ranking so there’s no extra follow-up.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you run a 10-question onboarding quiz for 20 new hires each month. Manually, you might spend about 5 minutes per person just to find answers in chat and enter them somewhere useful, which is roughly 2 hours before you even start scoring and ranking. With this workflow, the “admin” part is basically zero: the participant starts the bot, answers in Telegram, and Postgres stores every response automatically. You’ll still spend time reviewing outcomes, but the copy-paste and cleanup disappear.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Telegram for the quiz bot and participant chat.
- Postgres to store tests, answers, and scores.
- Postgres schema/tables (create them using the provided SQL script).
Skill level: Intermediate. You’ll connect Telegram and Postgres, then run a SQL script and map a few fields in n8n.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A participant messages your Telegram bot. The Telegram trigger starts the workflow and sets variables for the session, like which menu state the user is in and which test they’re taking.
The workflow routes them to the right place. Using simple checks and switches, n8n decides if it should show a greeting, display the test list, start a new attempt, or continue unanswered questions.
Questions are pulled from Postgres and delivered in chat. The workflow fetches the Q&A items, shuffles them, assigns the current index, and sends the next question. There’s also a short wait and message cleanup so the chat stays readable.
Responses get recorded, then results are computed. Each answer is written to Postgres, the workflow checks what’s left, and when the quiz is complete it calculates the score and sends results plus ranking back to Telegram.
You can easily modify the scoring logic to accept partial credit or different answer formats based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Telegram Trigger
This workflow starts when a Telegram message arrives, then initializes variables and bootstraps the session before routing the user.
- Add and open Telegram Intake Trigger and connect it to Telegram Variable Setup.
- Open Telegram Variable Setup and define the user/session fields you need for downstream routing.
- Open Bootstrap Setup and set any default variables required for the quiz state.
- Verify the execution path Telegram Intake Trigger → Telegram Variable Setup → Bootstrap Setup → Start Checkpoint.
Credential Required: Connect your Telegram credentials (required for Telegram Intake Trigger and all Telegram nodes).
Step 2: Configure Initial Routing and Greeting
After the bootstrap, the workflow determines whether to greet the user and how to route commands versus button actions.
- Open Start Checkpoint and configure the IF conditions that control whether users receive the greeting and route selector.
- Configure Greeting Notice with your welcome message to the user.
- Open Route Selector and define switch rules to pass Telegram input to either Button Branching or Command Routing.
- In Button Branching, add routes for interactive button actions to Primary Menu and Test Mode Router.
- In Command Routing, define command-based paths to Retrieve Test List and the fallback to Error Notification.
Credential Required: Connect your Telegram credentials (required for Greeting Notice, Primary Menu, and Error Notification).
Step 3: Connect Database Operations (Postgres)
The workflow relies on Postgres for quiz lists, individual tests, answer recording, and results computation. Configure credentials for all database nodes.
- Open Set Bot Status and configure the SQL needed to record or update the bot’s session state.
- Open Retrieve Test List and set your query to return available quizzes for the user.
- Configure Fetch Single Test and Fetch Q&A Items queries to fetch the chosen quiz and its questions.
- Open Upsert Predicted Answer and Record Answer to store predicted/actual answers as needed.
- Configure Load Unanswered Items and Compute Results to load remaining questions and calculate the final score.
Credential Required: Connect your Postgres credentials (required for all Postgres nodes such as Retrieve Test List, Fetch Q&A Items, Compute Results, and others).
Step 4: Build the Test List and Entry Flow
Once a list is retrieved, the workflow formats and displays it, then allows users to enter a selected test.
- Open Attach Question Index to map indices for the list of tests returned by Retrieve Test List.
- Configure Summarize List to build a condensed output list from the indexed data.
- Open Display Test List and format the output message sent to Telegram.
- Ensure the path Fetch Single Test → Run Test Entry → Fetch Q&A Items is connected for starting a chosen test.
Credential Required: Connect your Telegram credentials for Display Test List and Run Test Entry.
Step 5: Configure Question Processing and Parallel Branching
Questions are randomized, processed, and merged before storing predicted answers. This step uses a parallel branch after shuffling.
- Open Shuffle Questions and configure the sort/shuffle logic for question order.
- Shuffle Questions outputs to both Custom Script and Assign Variables in parallel.
- In Custom Script, add any custom logic for question metadata or filtering.
- In Assign Variables, map question data into consistent fields for downstream nodes.
- Confirm both branches merge in Combine Streams before storing with Upsert Predicted Answer.
Step 6: Deliver Questions, Wait, and Clean Up Messages
This section sends each question to Telegram, waits, and removes prior messages to keep the chat clean.
- Open Send Question and format the question payload sent to the user.
- Configure Delay Step to define the wait time before cleanup.
- Open Remove Message to delete or hide previous messages after the delay.
Credential Required: Connect your Telegram credentials for Send Question and Remove Message.
Step 7: Record Answers and Decide Whether to Continue
Answers are stored and the workflow checks for remaining questions, either looping back or computing results.
- Open Record Answer to store the user’s response in your database.
- Configure Load Unanswered Items to retrieve the next unanswered question set.
- In Remaining Questions?, set the IF logic to route to Shuffle Questions when questions remain or to Compute Results when finished.
Credential Required: Connect your Postgres credentials for Record Answer and Load Unanswered Items.
Step 8: Send Results to the User
When the quiz ends, results are calculated and sent via Telegram.
- Open Compute Results and ensure the SQL returns the score and summary fields you want to display.
- Configure Send Results to format the final response message for the user.
Credential Required: Connect your Telegram credentials for Send Results.
Step 9: Test & Activate Your Workflow
Run a full test to validate Telegram input, quiz flow, database writes, and final result output.
- Click Execute Workflow and send a message to your Telegram bot to trigger Telegram Intake Trigger.
- Verify the greeting and routing behavior flows through Greeting Notice, Route Selector, and Primary Menu.
- Select a test and confirm questions are sent through Send Question with the delay and cleanup running.
- Complete the quiz and confirm Send Results posts the final score.
- When everything works, toggle the workflow to Active for production use.
Common Gotchas
- Telegram bot credentials can expire or be tied to the wrong bot. If messages stop sending, check your Telegram node credentials in n8n first, then confirm the bot token is still valid in BotFather.
- If you’re using Wait nodes or relying on chat timing, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses or the user replies slower than expected.
- Postgres permissions matter more than people expect. If upserts or inserts fail, check the database user rights on your quiz tables and confirm you replaced the default “n8n” schema name in the SQL script.
Frequently Asked Questions
About 45 minutes if your Postgres and Telegram bot are ready.
No. You’ll mostly connect accounts and paste the provided SQL to create tables.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in your database hosting costs (Postgres is often included with your existing stack).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and you’ll probably want to. Most people customize it by editing test content directly in Postgres, then tweaking the messaging in the Telegram “Send Question” and “Send Results” steps so it matches their tone. If you need different evaluation methods (partial credit, negative marking, or multiple correct answers), update the Postgres-side scoring query used in “Compute Results,” and adjust the values the workflow stores in “Record Answer.” You can also change the shuffling behavior by editing the “Shuffle Questions” logic so certain questions always appear first.
Usually it’s an invalid or rotated bot token, so Telegram nodes can’t send messages anymore. Update the Telegram credentials in n8n, then run a test message from “Greeting Notice” or “Send Question.” If it still fails, check that the bot is allowed to message users (they must start the bot first), and confirm you’re not mixing up environments if you have a test bot and a production bot.
On n8n Cloud Starter, you can run a few thousand workflow executions per month, which is enough for many small teams running quizzes weekly. If you self-host, there’s no execution cap, so the limit is mostly your server and Postgres performance. Practically, this workflow is comfortable handling many concurrent users because each answer is just a small database write and a Telegram message. If you expect big spikes, start by increasing wait times and making sure your Postgres has indexes on attempt and user fields.
Often, yes, because this workflow isn’t a simple two-step “send then log” automation. You need branching, state tracking, and repeated question loops, which n8n handles cleanly without forcing you into expensive task counts. Self-hosting is also a big deal if you run quizzes frequently. Zapier or Make can be easier for very small flows, but they get awkward when you’re managing menus, retries, and ranking logic. If you want help choosing, Talk to an automation expert and we’ll map the simplest option for your setup.
Once this is running, quizzes stop being a cleanup project. The workflow handles the repetitive parts so you can focus on what the results actually mean.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.