Skip to content

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ€– student_bot

A dead-simple Telegram bot that lets schoolchildren message the school administration with a single button

Python python-telegram-bot SQLite Async


πŸ“– About

A contact bot connecting young students with their school administration or teachers.

The guiding rule: a child should not have to learn anything to use it. No tickets, no message-type pickers, no nested menus, no technical vocabulary. One button, then they write or send whatever they want, and it reaches the administration instantly.

The bot's user interface is in Arabic, because its users are Arabic-speaking children. The code, comments and documentation are in English.

/start  β†’  πŸ‘‹ Welcome  β†’  [ πŸ’¬ Contact us ]  β†’  😊 Write or send anything
        β†’  πŸ“© Delivered to the admins  β†’  πŸ’¬ Admin replies  β†’  😊 Conversation continues

✨ Features

🎯 A single button The child's keyboard holds exactly one button: πŸ’¬ ΨͺΩˆΨ§Ψ΅Ω„ Ω…ΨΉΩ†Ψ§ (Contact us)
πŸͺ„ Automatic content detection Text, photo, document, video, voice note, audio, video note, animation, sticker β€” never a question asked
πŸ’¬ Continuous conversation The child stays in contact mode and keeps sending, exactly like a normal chat
πŸ‘¨β€πŸ« Direct admin replies A Reply button under every message; the admin answers with any content type
πŸ‘₯ Multiple admins Messages reach every admin, and whoever replies first gets through to the child
⚑ Fully asynchronous asyncio + aiosqlite β€” dozens of children at once, nobody blocks anybody
πŸ”’ Locked down Children never see the admin panel, and no child can see another child's data
πŸ’Ύ Durable state Contact mode lives in the database, so it survives a restart

πŸ“ Project layout

student_bot/
β”‚
β”œβ”€β”€ main.py                      # Startup, handler registration, global error handler
β”œβ”€β”€ config.py                    # Reads and validates .env
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ .env.example
β”‚
β”œβ”€β”€ database/                    # Data layer, fully isolated from the handlers
β”‚   β”œβ”€β”€ connection.py            #   aiosqlite connection + schema creation
β”‚   β”œβ”€β”€ users.py                 #   users table
β”‚   β”œβ”€β”€ conversations.py         #   conversations table
β”‚   └── messages.py              #   messages table
β”‚
β”œβ”€β”€ handlers/                    # Telegram-facing layer
β”‚   β”œβ”€β”€ start.py                 #   /start, /help, /id
β”‚   β”œβ”€β”€ student.py               #   Child UI + the catch-all message receiver
β”‚   β”œβ”€β”€ admin.py                 #   Admin panel, replies, announcements
β”‚   └── media.py                 #   Automatic content-type detection
β”‚
β”œβ”€β”€ keyboards/                   # Buttons, kept apart from the logic
β”‚   β”œβ”€β”€ reply.py                 #   The "Contact us" reply keyboard
β”‚   └── inline.py                #   Inline buttons for child and admin
β”‚
β”œβ”€β”€ services/                    # Business logic
β”‚   β”œβ”€β”€ message_service.py       #   Sends any content type to any chat
β”‚   └── conversation_service.py  #   Bridges child and admins
β”‚
└── utils/
    β”œβ”€β”€ decorators.py            # @admin_only
    └── logger.py                # Logging setup

How a message flows

Child's message
     β”‚
     β–Ό
handlers/student.py  ──►  handlers/media.py       (what type is this?)
     β”‚
     β–Ό
services/conversation_service.py  ──►  database/  (persist it)
     β”‚
     β–Ό
services/message_service.py  ──►  every admin + [πŸ’¬ Reply] [πŸ”’ Close] buttons

πŸš€ Running locally

Requirements

  • Python 3.11 or newer

Steps

1. Clone

git clone https://github.com/ixl55/telegram-bot-.git && cd telegram-bot-

2. Virtual environment and dependencies

Windows
python -m venv .venv && .venv\Scripts\activate && pip install -r requirements.txt
Linux / macOS
python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt

3. Create the bot

Open @BotFather β†’ /newbot β†’ copy the token.

4. Configuration

cp .env.example .env

Then fill it in:

BOT_TOKEN=your_token_from_botfather
ADMIN_IDS=123456789          # your numeric id; for several: 111111,222222
DB_PATH=student_bot.db
LOG_LEVEL=INFO

πŸ†” Don't know your id? Start the bot with any placeholder value, send it /id, then put the number it returns into ADMIN_IDS and restart.

5. Run

python main.py

A healthy start looks like this:

Connected to database: .../student_bot.db
Bot ready, 1 admin(s) configured
Starting the bot...

πŸ‘¦ The child's experience

Step What happens
/start Welcome message plus the πŸ’¬ ΨͺΩˆΨ§Ψ΅Ω„ Ω…ΨΉΩ†Ψ§ button
Presses the button "Go ahead! Write your message or send a photo or a file" with ❌ Cancel and 🏠 Home
Sends anything "Your message arrived!" then short per-type confirmations afterwards
❌ Cancel Contact mode ends and the home screen returns

Children never see an admin command or panel of any kind.


πŸ‘¨β€πŸ« The admin's experience

Every admin receives:

πŸ“© New message

πŸ‘€ Name: Ahmed
πŸ†” User: 123456789

followed by the content itself and two buttons:

Button Effect
πŸ’¬ Ψ§Ω„Ψ±Ψ― (Reply) Enters reply mode; anything sent next (text/photo/file/video/audio) goes straight to the child
πŸ”’ Ψ₯Ω†Ω‡Ψ§Ψ‘ Ψ§Ω„Ω…Ψ­Ψ§Ψ―Ψ«Ψ© (Close) Closes the conversation and tells the child politely

Leave reply mode with the βœ‹ Stop button or the /admin command.

Admin panel β€” /admin

Button Shows
πŸ“© Ψ§Ω„Ψ±Ψ³Ψ§Ψ¦Ω„ Open conversations, each with a quick reply button
πŸ‘₯ Ψ§Ω„Ψ·Ω„Ψ§Ψ¨ The most recently registered students
πŸ“Š Ψ§Ω„Ψ₯حءائياΨͺ Students, conversations, total messages, messages today
πŸ“’ Ψ₯ΨΉΩ„Ψ§Ω† Broadcast one message to every student, batched to respect rate limits

Commands

Command Who Purpose
/start Everyone Start and register
/help Everyone Short explanation
/id Everyone Show your Telegram id
/admin Admins only Open the admin panel

πŸ—„οΈ Database

SQLite through aiosqlite. Every operation is async/await with no blocking call anywhere, using WAL journaling and foreign_keys=ON.

users
Column Type Notes
id INTEGER Primary key
telegram_id INTEGER Unique
username TEXT May be empty
full_name TEXT
created_at TEXT Automatic
conversations
Column Type Notes
id INTEGER Primary key
user_id INTEGER β†’ users.id
status TEXT open / closed
created_at TEXT
updated_at TEXT Last activity

Contact mode is simply an open conversation. That is why no global variable holds per-user state and why every child is fully independent of the others.

messages
Column Type Notes
id INTEGER Primary key
conversation_id INTEGER β†’ conversations.id
sender_id INTEGER Sender's telegram_id (child or admin)
message_type TEXT text, photo, document, video, voice, audio, video_note, animation, sticker
text_content TEXT For text messages
file_id TEXT For everything else
caption TEXT Attachment caption
created_at TEXT

πŸ–₯️ Deploying with systemd

1. Upload

tar -czf - --exclude='__pycache__' --exclude='*.db' --exclude='.venv' student_bot | ssh USER@SERVER 'tar -xzf - -C /opt'

2. Environment and dependencies

ssh USER@SERVER "cd /opt/student_bot && python3 -m venv .venv && .venv/bin/pip install -r requirements.txt"

3. Unit file at /etc/systemd/system/student-bot.service

[Unit]
Description=Student Contact Telegram Bot
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/student_bot
Environment=PYTHONUNBUFFERED=1
Environment=PYTHONIOENCODING=utf-8
ExecStart=/opt/student_bot/.venv/bin/python main.py
Restart=always
RestartSec=5
SyslogIdentifier=student-bot

[Install]
WantedBy=multi-user.target

4. Enable and watch

systemctl daemon-reload && systemctl enable --now student-bot && systemctl status student-bot
journalctl -u student-bot -f

⚠️ Never run two instances on the same token. Telegram allows a single poller; a second one causes Conflict errors and lost messages.


πŸ”’ Security and privacy

  • .env is never committed β€” it is in .gitignore, and on the server it should be chmod 600.
  • Every admin entry point is guarded by @admin_only, which checks telegram_id for commands and callback buttons alike.
  • Children are isolated: no command or button exposes another user's data, and every conversation belongs to exactly one child.
  • HTML is escaped for every name and body shown to an admin, so no tag can be injected through a display name.
  • No global mutable state: the child's mode lives in the database, and each admin's mode lives in their own context.user_data.

πŸ”‘ If your token ever leaks: /revoke in @BotFather, then put the new one in .env.


πŸ“ Logging

Logs go to the console and to logs/bot.log (rotating, 2 MB Γ— 3 files). Set LOG_LEVEL=DEBUG for more detail.

On Windows the logger forces UTF-8 output, otherwise cp1252 mangles the Arabic interface strings.


❓ Troubleshooting

Problem Fix
BOT_TOKEN is missing Create .env next to main.py and put the token in it
ADMIN_IDS is missing Add your numeric id (find it with /id)
Messages never reach the admin Each admin must send /start to the bot once first
Conflict: terminated by other getUpdates Another instance is running on the same token β€” stop it
Messages lost after a restart drop_pending_updates=True in main.py discards whatever arrived while the bot was down; set it to False
Dependencies will not install Check for Python 3.11+ and an activated virtual environment

πŸ› οΈ Built with

Python 3.11+ Β· python-telegram-bot 21.6 Β· asyncio Β· aiosqlite Β· python-dotenv Β· logging Β· type hints throughout

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages