Skip to content

Refactor Telegram bot to use python-telegram-bot - #59

Open
just51888 wants to merge 1 commit into
aeither:mainfrom
just51888:patch-1
Open

just51888 wants to merge 1 commit into
aeither:mainfrom
just51888:patch-1

Conversation

@just51888

@just51888 just51888 commented Jun 16, 2026 •

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features

    • Enhanced /start command with support for mapped code lookups that return Chinese names
  • Refactor

    • Modernized bot framework to use async handlers with improved initialization and polling

@coderabbitai

coderabbitai Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

main.py is rewritten from a synchronous telebot/pyTelegramBotAPI implementation to an async python-telegram-bot Application. It adds a name_map dict, an async /start command handler that looks up codes and replies with Chinese names or fallbacks, and replaces the old polling/exception loop with app.run_polling().

Changes

Bot framework rewrite (main.py)

Layer / File(s) Summary
Module-level config and name_map
main.py
Replaces dotenv/telebot imports and bot initialization with python-telegram-bot imports, TOKEN read from os.environ, and a name_map dict mapping short codes to Chinese display strings.
Async /start command handler
main.py
Adds an async start() function that reads the first command argument, checks it against name_map, logs the user and code, and replies with the mapped Chinese name, the raw code, or a generic welcome.
Application construction and polling startup
main.py
Replaces the old telebot startup, webhook deletion, and infinite-sleep exception-handling loop with main() that builds the Application, registers the /start handler, and calls app.run_polling().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hop, hop, the old bot sleeps no more,
Async wings now carry each message to shore.
A name_map blooms with characters bright,
/start replies in Chinese delight.
No more sleep loops — just polling's sweet flight! 🌸

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Refactor Telegram bot to use python-telegram-bot' directly and accurately describes the main change: migrating from telebot/pyTelegramBotAPI to python-telegram-bot with async handlers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@main.py`:
- Around line 23-33: Remove the user_id variable from the three print statements
where raw Telegram user IDs are being logged to stdout. The variable `user_id`
derived from `update.effective_user.id` should not appear in the print
statements on the lines containing "通过 {code}" and "直接开始". Either remove the
user_id entirely from these log messages or hash/redact it before logging to
avoid exposing sensitive user identifiers in host logs.
- Around line 3-4: The imports in main.py from telegram.ext (Application,
CommandHandler, ContextTypes) belong to the python-telegram-bot library, but
pyproject.toml declares pytelegrambotapi, which is a different incompatible
library. In pyproject.toml, replace the pytelegrambotapi dependency with
python-telegram-bot at version >=21.0 to match the imports and support the async
handlers used in main.py.
- Line 6: The TOKEN variable at line 6 retrieves the TELEGRAM_BOT_TOKEN from the
environment using os.environ.get(), but the .env file is never loaded despite
python-dotenv being a declared dependency and the README instructing users to
create a .env file. Add a call to load_dotenv() at the beginning of main.py
(right after the imports, before TOKEN is assigned) to ensure environment
variables from the .env file are loaded into the process. This will allow users
following the documented setup instructions to have their TELEGRAM_BOT_TOKEN
properly loaded from the .env file instead of getting None.
- Line 38: The main.py file currently only registers a CommandHandler for the
"start" command, but the README.md documents both a "/hello" command and text
message echo functionality. Add a CommandHandler registration for the "hello"
command that calls an appropriate hello function, and add a MessageHandler
registration that handles text messages to implement the echo behavior. Ensure
that corresponding handler functions (hello and echo) are defined in main.py to
support these new registrations, matching the same pattern used for the existing
start handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d8a866a-7914-401c-927b-f35d2a93ea1f

📥 Commits

Reviewing files that changed from the base of the PR and between 5cfd740 and 8420aee.

📒 Files selected for processing (1)
  • main.py

Comment thread main.py
Comment on lines +3 to +4
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Description: Inspect Python dependency manifests for Telegram bot framework packages.
fd -t f '^(pyproject\.toml|requirements.*\.txt|setup\.py|setup\.cfg|Pipfile|poetry\.lock|uv\.lock)$' \
  --exec sh -c 'printf "\n== %s ==\n" "$1"; rg -n -C2 "python-telegram-bot|pyTelegramBotAPI|telebot|telegram-bot" "$1" || true' sh {}

Repository: aeither/telegram-bot-python

Length of output: 301


🏁 Script executed:

cat -n pyproject.toml

Repository: aeither/telegram-bot-python

Length of output: 624


Update dependency manifest to use python-telegram-bot instead of pytelegrambotapi.

main.py imports from telegram.ext import Application, CommandHandler, ContextTypes, which is the API of the python-telegram-bot package. However, pyproject.toml declares pytelegrambotapi>=4.30.0,<5, which is a different library with an incompatible API. The code will fail at import time with ModuleNotFoundError.

Replace the pytelegrambotapi dependency with python-telegram-bot at a version that supports telegram.ext.Application and async handlers (e.g., >=21.0).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` around lines 3 - 4, The imports in main.py from telegram.ext
(Application, CommandHandler, ContextTypes) belong to the python-telegram-bot
library, but pyproject.toml declares pytelegrambotapi, which is a different
incompatible library. In pyproject.toml, replace the pytelegrambotapi dependency
with python-telegram-bot at version >=21.0 to match the imports and support the
async handlers used in main.py.

Comment thread main.py
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes

TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Description: Confirm token-loading contract across code, docs, and Python manifests.
fd -t f '^(README\.md|main\.py|pyproject\.toml|requirements.*\.txt|setup\.py|setup\.cfg|uv\.lock|poetry\.lock)$' \
  --exec sh -c 'printf "\n== %s ==\n" "$1"; rg -n -C2 "TELEGRAM_BOT_TOKEN|load_dotenv|python-dotenv|dotenv|env-file" "$1" || true' sh {}

Repository: aeither/telegram-bot-python

Length of output: 1612


🏁 Script executed:

#!/bin/bash
# Search for load_dotenv calls in all Python files
rg -t py "load_dotenv" . || echo "No load_dotenv calls found"

Repository: aeither/telegram-bot-python

Length of output: 98


🏁 Script executed:

#!/bin/bash
# Read full README.md to understand setup instructions
cat -n README.md

Repository: aeither/telegram-bot-python

Length of output: 2252


🏁 Script executed:

#!/bin/bash
# Read main.py to understand line 37 context and full code
cat -n main.py

Repository: aeither/telegram-bot-python

Length of output: 1595


Load the .env file or update documentation to clarify token setup.

README.md (line 33) instructs users to create a .env file with TELEGRAM_BOT_TOKEN, and python-dotenv is a declared dependency. However, load_dotenv() is never called in the codebase, so .env files are not loaded. This breaks the documented local startup path: users following the setup instructions will find TOKEN=None at line 6, causing Application.builder().token(TOKEN) at line 37 to fail.

Suggested fix
 import os
+from dotenv import load_dotenv
 from telegram import Update
 from telegram.ext import Application, CommandHandler, ContextTypes

+load_dotenv()
 TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")

 name_map = {
...

Either restore .env loading via load_dotenv() at module initialization, or update README to clarify that TELEGRAM_BOT_TOKEN must be set as an exported shell environment variable before running uv run python -B main.py.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
import os
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
load_dotenv()
TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN")
name_map = {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` at line 6, The TOKEN variable at line 6 retrieves the
TELEGRAM_BOT_TOKEN from the environment using os.environ.get(), but the .env
file is never loaded despite python-dotenv being a declared dependency and the
README instructing users to create a .env file. Add a call to load_dotenv() at
the beginning of main.py (right after the imports, before TOKEN is assigned) to
ensure environment variables from the .env file are loaded into the process.
This will allow users following the documented setup instructions to have their
TELEGRAM_BOT_TOKEN properly loaded from the .env file instead of getting None.

Comment thread main.py
Comment on lines +23 to +33
user_id = update.effective_user.id

if code and code in name_map:
chinese = name_map[code]
print(f"用户 {user_id} 通过 {code}({chinese})进入")
await update.message.reply_text(f"兄弟 已经转接:{chinese}")
elif code:
print(f"用户 {user_id} 通过 {code} 进入")
await update.message.reply_text(f"兄弟 已经转接:{code}")
else:
print(f"用户 {user_id} 直接开始")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop writing raw Telegram user IDs to stdout.

Lines 27, 30, and 33 log update.effective_user.id; Telegram IDs are user identifiers and can be retained in host logs. Remove, redact, or hash them before logging.

🛡️ Proposed fix
-    user_id = update.effective_user.id
-
     if code and code in name_map:
         chinese = name_map[code]
-        print(f"用户 {user_id} 通过 {code}({chinese})进入")
+        print(f"用户通过 {code}({chinese})进入")
         await update.message.reply_text(f"兄弟 已经转接:{chinese}")
     elif code:
-        print(f"用户 {user_id} 通过 {code} 进入")
+        print("用户通过未识别代码进入")
         await update.message.reply_text(f"兄弟 已经转接:{code}")
     else:
-        print(f"用户 {user_id} 直接开始")
+        print("用户直接开始")
         await update.message.reply_text("欢迎!")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
user_id = update.effective_user.id
if code and code in name_map:
chinese = name_map[code]
print(f"用户 {user_id} 通过 {code}({chinese})进入")
await update.message.reply_text(f"兄弟 已经转接:{chinese}")
elif code:
print(f"用户 {user_id} 通过 {code} 进入")
await update.message.reply_text(f"兄弟 已经转接:{code}")
else:
print(f"用户 {user_id} 直接开始")
if code and code in name_map:
chinese = name_map[code]
print(f"用户通过 {code}({chinese})进入")
await update.message.reply_text(f"兄弟 已经转接:{chinese}")
elif code:
print("用户通过未识别代码进入")
await update.message.reply_text(f"兄弟 已经转接:{code}")
else:
print("用户直接开始")
await update.message.reply_text("欢迎!")
🧰 Tools
🪛 Ruff (0.15.17)

[warning] 27-27: String contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?

(RUF001)


[warning] 27-27: String contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?

(RUF001)


[warning] 28-28: String contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF001)


[warning] 31-31: String contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` around lines 23 - 33, Remove the user_id variable from the three
print statements where raw Telegram user IDs are being logged to stdout. The
variable `user_id` derived from `update.effective_user.id` should not appear in
the print statements on the lines containing "通过 {code}" and "直接开始". Either
remove the user_id entirely from these log messages or hash/redact it before
logging to avoid exposing sensitive user identifiers in host logs.

Comment thread main.py

def main():
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Description: Compare documented bot commands/features against registered handlers.
rg -n -C2 '(/hello|Echoes all other messages|CommandHandler\("hello"|MessageHandler|filters\.TEXT|CommandHandler\("start")' README.md main.py

Repository: aeither/telegram-bot-python

Length of output: 790


Align registered handlers with README documentation.

README.md advertises /hello command and echo behavior (lines 12-13, 57), but main.py only registers the /start handler. This creates a user-visible regression. Add handlers for /hello command and text message echo to match documented functionality.

Proposed addition
-from telegram.ext import Application, CommandHandler, ContextTypes
+from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
@@
 async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
@@
         await update.message.reply_text("欢迎!")
 
+async def hello(update: Update, _context: ContextTypes.DEFAULT_TYPE):
+    message = update.effective_message
+    if message:
+        await message.reply_text("Hello!")
+
+async def echo(update: Update, _context: ContextTypes.DEFAULT_TYPE):
+    message = update.effective_message
+    if message and message.text:
+        await message.reply_text(message.text)
+
 def main():
     app = Application.builder().token(TOKEN).build()
     app.add_handler(CommandHandler("start", start))
+    app.add_handler(CommandHandler("hello", hello))
+    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` at line 38, The main.py file currently only registers a
CommandHandler for the "start" command, but the README.md documents both a
"/hello" command and text message echo functionality. Add a CommandHandler
registration for the "hello" command that calls an appropriate hello function,
and add a MessageHandler registration that handles text messages to implement
the echo behavior. Ensure that corresponding handler functions (hello and echo)
are defined in main.py to support these new registrations, matching the same
pattern used for the existing start handler.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant