Building a Daily Python Lesson Telegram Bot with Supabase and React
Source: Dev.to
Introduction
Imagine a web application that sends users a short Python lesson every day through Telegram.
With modern tools like Supabase and React, we can create this seamlessly — combining frontend, backend, and a Telegram bot. In this tutorial, we’ll walk through:
- Designing the application
- Creating the bot
- Integrating it with Supabase
- Linking it to a React frontend
Step 1: Designing the Application
Features
- Daily Python lessons delivered via Telegram.
- Users track progress on lessons in the app.
- Users can configure notifications (enable/disable, delivery time, Telegram username).
Database Tables
lessons
create table public.lessons (
id uuid primary key default gen_random_uuid(),
day_index int not null unique,
title text not null,
content text,
example_code text,
challenge text,
created_at timestamptz default now()
);
user_progress
create table public.user_progress (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade,
lesson_id uuid references lessons(id) on delete cascade,
completed boolean default false,
completed_at timestamptz
);
user_notifications
create table public.user_notifications (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade,
channel text not null, -- 'telegram', 'email'
enabled boolean default true,
delivery_time time not null,
timezone text default 'UTC',
created_at timestamptz default now(),
updated_at timestamptz default now()
);
user_telegram
create table public.user_telegram (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade unique,
telegram_chat_id bigint,
activation_code int not null,
status text default 'pending', -- pending | connected
created_at timestamptz default now(),
updated_at timestamptz default now()
);
Step 2: Create a Telegram Bot
- Open Telegram and search for BotFather.
- Send
/newbotand follow the instructions. - Choose a name and username; BotFather will give you a bot token.
- Keep this token safe — it’s required to send messages via the Telegram API.
Test Your Bot
curl -X POST https://api.telegram.org/bot/sendMessage \
-d chat_id= \
-d text="Hello from PyDaily!"
Tip: Use @userinfobot to get your Telegram chat ID for testing.
Step 3: Supabase Backend Setup
Supabase will handle:
- Authentication
- Database storage
- Edge Functions (serverless backend)
1. Store Lessons
insert into public.lessons (day_index, title, content, example_code, challenge)
values
(1, 'Variables & Types', 'Introduction to Python variables',
'x = 5\ny = "Hello"', 'Write a program to swap two variables'),
(2, 'Control Flow', 'If, elif, else',
'if x > 5:\n print("x is greater")',
'Write a function to check even/odd');
2. User Notification Setup
- Users can choose the delivery channel (Telegram) and time.
- Add a row in
user_telegramfor each user with a generated activation code.
3. Edge Function for Telegram
Create a Supabase Edge Function that:
- Fetches users who have Telegram enabled.
- Determines today’s lesson.
- Checks
user_progressto avoid duplicate sends. - Sends the lesson via the Telegram Bot API.
- Updates
user_progress.
Step 4: Frontend in React
Notification Settings Component
function NotificationSettings({ user }) {
const [telegramUsername, setTelegramUsername] = useState('');
const [activationCode, setActivationCode] = useState('');
const [status, setStatus] = useState('pending');
const generateCode = async () => {
const { data } = await supabase.rpc('generate_telegram_activation_code');
setActivationCode(data);
};
return (
<div>
<input
placeholder="Telegram username"
value={telegramUsername}
onChange={e => setTelegramUsername(e.target.value)}
/>
<button onClick={generateCode}>Generate Activation Code</button>
<p>Status: {status}</p>
{status === 'pending' && (
<div>
Send this code to the bot: {activationCode}
</div>
)}
</div>
);
}
- On submit, save data to
user_notificationsanduser_telegramvia the Supabase client. - React fetches lesson history to display user progress.
Step 5: Connecting Everything
- User enters Telegram username in the frontend.
- Backend generates an activation code (via RPC).
- User sends the code to the bot → backend webhook validates it → updates
status = connected. - Daily lesson scheduler Edge Function runs:
// Pseudocode
for (const user of usersWithTelegramEnabled) {
const lesson = await getTodaysLesson();
const alreadySent = await checkUserProgress(user.id, lesson.id);
if (!alreadySent) {
await sendTelegramMessage(user.telegram_chat_id, formatLesson(lesson));
await markLessonSent(user.id, lesson.id);
}
}
son = getLessonForToday(user)
if !user_progress.completed:
sendTelegram(user.telegram_chat_id, lesson.content)
markLessonCompleted(user, lesson)
With these pieces in place, PyDaily will automatically deliver daily Python lessons to users via Telegram, while letting them track progress and control notification preferences from a React dashboard. 🚀
Scheduling
- Can schedule via Supabase cron or an external service.
- Lessons include Markdown formatting or code blocks.
Step 6: Testing & Going Live
- Test the activation code flow.
- Ensure
user_telegram.status = connected. - Run the Edge Function manually to verify messages.
- Schedule the Edge Function for daily execution.
Conclusion
With Supabase and React you can:
- Manage users, lessons, and notifications seamlessly.
- Use a Telegram bot for daily engagement without building a custom messaging service.
- Extend the architecture to email, WhatsApp, or other channels.
Next Steps
- Add lesson attachments (images, diagrams) via Telegram
sendPhoto. - Extend the React UI with a lesson timeline and progress charts.
- Add retry logic in Edge Functions for robust delivery.
This post provides a complete end‑to‑end plan to implement a daily Python‑lesson Telegram bot integrated with a React frontend using Supabase as the backend.