Skip to content

Update commands.py - #57

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

mahangames57-droid wants to merge 1 commit into
aeither:mainfrom
mahangames57-droid:patch-1

Conversation

@mahangames57-droid

@mahangames57-droid mahangames57-droid commented Jun 4, 2026 •

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features
    • Interactive setup flow for scheduling daily messages to channels/groups
    • Ability to configure message content and delivery time (with Asia/Tehran timezone support)
    • New commands: /start to begin setup, /stop to disable scheduling, and /cancel to exit configuration
    • User settings are automatically saved and restored

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR completely replaces a synchronous telebot command registration system with an async python-telegram-bot application. It implements a multi-step conversation to collect channel ID, message text, and schedule time; stores configuration in users.json; schedules daily cron jobs via AsyncIOScheduler; restores persisted jobs on startup; and provides /stop and /cancel controls for disabling and cleanup.

Changes

Async Telegram Bot Scheduler

Layer / File(s) Summary
Module setup and configuration
commands.py (lines 1–31)
Imports async/logging framework, python-telegram-bot, and AsyncIOScheduler; defines TOKEN, DATA_FILE, TIMEZONE constants and conversation state enum values.
Conversation entry and channel validation
commands.py (lines 43–98)
/start command and check_admin_callback prompt for authorization; receive_channel validates bot admin/creator status in provided chat before advancing conversation state.
Message and schedule configuration
commands.py (lines 100–173)
receive_message captures user message text; receive_hour validates HH:MM format in Asia/Tehran timezone, creates/updates daily cron job, persists config to users.json, and ends conversation.
Daily message execution
commands.py (lines 175–189)
send_daily_message reloads user config, checks active flag, sends stored message to configured channel_id, and logs results.
User control and cancellation
commands.py (lines 191–223)
/stop marks user inactive and removes scheduler job; /cancel ends conversation with acknowledgment.
Application bootstrap and job restoration
commands.py (lines 225–274)
restore_jobs recreates daily cron jobs from users.json on startup; main() builds Application, attaches AsyncIOScheduler, registers handlers, and starts polling; module guard enables direct execution.

Sequence Diagram

sequenceDiagram
  participant User
  participant Bot as python-telegram-bot
  participant Scheduler as AsyncIOScheduler
  participant Storage as users.json
  participant Channel as Telegram Channel

  User->>Bot: /start
  Bot->>Bot: check_admin_callback
  Bot->>User: Prompt channel ID
  
  User->>Bot: Send channel ID
  Bot->>Bot: receive_channel (verify bot admin status)
  Bot->>User: Prompt message text
  
  User->>Bot: Send message
  Bot->>Bot: receive_message
  Bot->>User: Prompt schedule time (HH:MM)
  
  User->>Bot: Send time (HH:MM)
  Bot->>Bot: receive_hour (validate timezone)
  Bot->>Scheduler: Create daily cron job
  Bot->>Storage: Save user config (active=true)
  Bot->>User: Conversation ended
  
  Note over Scheduler: Daily at scheduled time
  Scheduler->>Bot: Trigger send_daily_message
  Bot->>Storage: Load user config
  Bot->>Channel: Send message
  
  User->>Bot: /stop
  Bot->>Storage: Mark active=false
  Bot->>Scheduler: Remove job
  Bot->>User: Acknowledged
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A bot born anew, async and spry,
Schedules thy messages to the sky!
With conversations that flow, and jobs that persist,
Daily Tehran whispers—a feature we've missed! ✨📅

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

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.
Title check ❓ Inconclusive The title 'Update commands.py' is vague and generic, failing to convey the substantial changes from synchronous to asynchronous architecture with conversation flows and scheduling functionality. Use a more descriptive title such as 'Convert commands.py to async telegram-bot with conversation flow and message scheduling' to clearly communicate the primary changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.

@mahangames57-droid

Copy link
Copy Markdown
Author

هیچی

@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: 5

🤖 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 `@commands.py`:
- Around line 32-40: Handle corrupted or partially-written users.json by
updating load_data to catch json.JSONDecodeError and return {} (and optionally
log a warning) so restore_jobs() won't crash on startup, and change save_data to
write to a temporary file and then atomically replace DATA_FILE (e.g., write to
DATA_FILE + ".tmp" and use os.replace) to avoid in-place partial writes;
reference the load_data and save_data functions and DATA_FILE constant when
making these changes.
- Around line 21-23: The module currently resolves TOKEN at import time (TOKEN =
os.environ.get(...)) which runs before load_dotenv() in main; remove the
top-level TOKEN assignment and instead read the BOT_TOKEN inside main() after
calling load_dotenv(), validate it and exit/fail fast if missing, or provide a
commands.get_token() accessor that reads env at call-time; update any code that
relied on the module-level TOKEN to accept the token as an argument or call the
new accessor so the real value from .env is used.
- Around line 243-274: The repo's old entrypoint expects register_commands
(imported by main.py) but commands.py removed it and now only exposes main();
add a compatibility shim named register_commands in commands.py that either (a)
wraps/forwards to the new main() startup flow or (b) performs the previous
minimal bootstrap (creates/returns whatever the old main.py expects, e.g., a
TeleBot-like object or a non-blocking startup handle) so imports don't
fail—implement register_commands() near the top-level of commands.py and ensure
it references the same Application.builder()/scheduler setup or simply delegates
to main(), preserving the old import contract.
- Around line 163-170: The confirmation reply inserts user-provided
context.user_data["message_text"] (message_text) into update.message.reply_text
with parse_mode="Markdown", which can break for Telegram legacy Markdown; escape
Markdown special characters in message_text before calling reply_text (or switch
to parse_mode="HTML" and escape accordingly) so the confirmation cannot fail —
locate where message_text is read/used and apply a Markdown-escaping function to
message_text prior to passing it to update.message.reply_text (or remove
parse_mode and send plain text).
- Around line 8-18: The file currently mismatches the project entrypoint and
deps: remove PTB-specific main() and export a register_commands(bot:
telebot.TeleBot) function that main.py expects (reference symbol:
register_commands) so main.py can register handlers on the telebot instance;
align the token env var by replacing TOKEN = os.environ.get("BOT_TOKEN", ...)
with reading TELEGRAM_BOT_TOKEN (or centralize env var usage to
TELEGRAM_BOT_TOKEN) so the token name matches README/main.py; eliminate imports
on unused PTB/apscheduler/pytz or move those features behind optional flags and
list required packages in pyproject.toml so clean installs succeed; in
receive_hour(message_text) stop passing raw user text into parse_mode="Markdown"
— escape or sanitize message_text before sending (reference symbol:
receive_hour); and make load_data()/save_data() robust by adding JSON parse
error handling and atomic writes (read with try/except JSONDecodeError and on
save write to temp file then os.replace) to avoid crashes or partial writes
(reference symbols: load_data, save_data).
🪄 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: 87bbdce2-954e-493b-bc9d-525e2866cb86

📥 Commits

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

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

Comment thread commands.py
Comment on lines +8 to +18
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
Application,
CommandHandler,
MessageHandler,
CallbackQueryHandler,
ConversationHandler,
ContextTypes,
filters,
)
from apscheduler.schedulers.asyncio import AsyncIOScheduler

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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python - <<'PY'
import tomllib
from pathlib import Path

deps = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))["project"]["dependencies"]
needed = ["python-telegram-bot", "apscheduler", "pytz"]

print("declared dependencies:")
for dep in deps:
    print(" -", dep)

print("\nrequired by commands.py:")
for name in needed:
    present = any(dep.lower().startswith(name) for dep in deps)
    print(f"{name}: {'present' if present else 'MISSING'}")
PY

Repository: aeither/telegram-bot-python

Length of output: 242


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Print relevant dependency block
echo "=== pyproject.toml dependencies ==="
python - <<'PY'
import tomllib
from pathlib import Path
p = Path("pyproject.toml")
data = tomllib.loads(p.read_text(encoding="utf-8"))
deps = data.get("project", {}).get("dependencies", [])
print("\n".join(deps))
PY

# Inspect commands.py sections (imports, token loading, persistence, receive_hour)
echo
echo "=== commands.py (lines 1-260) ==="
nl -ba commands.py | sed -n '1,260p'

echo
echo "=== commands.py (search tokens/persistence/receive_hour) ==="
rg -n --hidden --no-ignore-vcs "(BOT_TOKEN|load_data|save_data|receive_hour|markdown|Markdown|parse_mode|message_text)" commands.py

# Inspect main.py for register_commands / load_dotenv order
if [ -f main.py ]; then
  echo
  echo "=== main.py (lines 1-220) ==="
  nl -ba main.py | sed -n '1,220p'
else
  echo
  echo "main.py not found"
fi

echo
echo "=== main.py imports from commands.py ==="
rg -n --hidden --no-ignore-vcs "(from commands import|import commands|register_commands|load_dotenv|BOT_TOKEN)" main.py || true

echo
echo "=== repo-wide references to register_commands / load_data / receive_hour ==="
rg -n --hidden --no-ignore-vcs "(register_commands|load_data\\(|save_data\\(|receive_hour|BOT_TOKEN|BOT_TOKEN|BOT_TOKEN|BOT_TOKEN)" .

Repository: aeither/telegram-bot-python

Length of output: 256


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== pyproject.toml dependencies ==="
python - <<'PY'
import tomllib
from pathlib import Path
data = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
deps = data.get("project", {}).get("dependencies", [])
print("\n".join(deps))
PY

echo
echo "=== commands.py (lines 1-260) ==="
if [ -f commands.py ]; then
  cat -n commands.py | sed -n '1,260p'
else
  echo "commands.py not found"
fi

echo
echo "=== commands.py (search tokens/persistence/receive_hour) ==="
rg -n --hidden --no-ignore-vcs "(BOT_TOKEN|load_data|save_data|receive_hour|markdown|Markdown|parse_mode|message_text)" commands.py || true

echo
echo "=== main.py (lines 1-220) ==="
if [ -f main.py ]; then
  cat -n main.py | sed -n '1,220p'
else
  echo "main.py not found"
fi

echo
echo "=== main.py imports from commands.py ==="
rg -n --hidden --no-ignore-vcs "(from commands import|import commands|register_commands|load_dotenv|BOT_TOKEN)" main.py || true

echo
echo "=== repo-wide references to register_commands / load_data / receive_hour ==="
rg -n --hidden --no-ignore-vcs "(register_commands|load_data\\(|save_data\\(|receive_hour|BOT_TOKEN)" . || true

Repository: aeither/telegram-bot-python

Length of output: 15078


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== commands.py: search for register_commands ==="
rg -n --hidden --no-ignore-vcs "def register_commands|register_commands\s*\(" commands.py || true

echo
echo "=== commands.py: tail (rest of file) ==="
tail -n 80 commands.py

echo
echo "=== commands.py: show full file length ==="
python - <<'PY'
from pathlib import Path
p=Path("commands.py")
print("commands.py lines:", sum(1 for _ in p.open("r", encoding="utf-8")))
PY

echo
echo "=== repo-wide references to python-telegram-bot/AsyncIOScheduler/restore_jobs ==="
rg -n --hidden --no-ignore-vcs "(python-telegram-bot|AsyncIOScheduler|restore_jobs|send_daily_message|ConversationHandler\\()" . || true

Repository: aeither/telegram-bot-python

Length of output: 3386


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== .env.example ==="
cat .env.example

echo
echo "=== README.md (token-related lines) ==="
rg -n --hidden --no-ignore-vcs "TELEGRAM_BOT_TOKEN|BOT_TOKEN" README.md || true

echo
echo "=== pyproject.toml (project.dependencies block) ==="
python - <<'PY'
import tomllib
from pathlib import Path
p=Path("pyproject.toml")
data=tomllib.loads(p.read_text(encoding="utf-8"))
print(data.get("project", {}).get("dependencies", []))
PY

echo
echo "=== commands.py token env var ==="
rg -n --hidden --no-ignore-vcs "TOKEN = os\.environ\.get\\(|BOT_TOKEN" commands.py

Repository: aeither/telegram-bot-python

Length of output: 658


Fix critical startup breaks: missing deps, entrypoint mismatch, and token env var divergence

  • commands.py imports python-telegram-bot, apscheduler, and pytz, but pyproject.toml only declares pytelegrambotapi and python-dotenv; clean installs will fail before the bot can run.

  • main.py imports register_commands from commands.py and builds a telebot.TeleBot, but commands.py has no register_commands export (it defines its own PTB main()), so initialization will break.

  • Token env var mismatch: commands.py uses BOT_TOKEN (TOKEN = os.environ.get("BOT_TOKEN", ...)), while main.py/README/.env.example use TELEGRAM_BOT_TOKEN.

  • Additionally: receive_hour() injects user message_text into parse_mode="Markdown" without escaping, and load_data()/save_data() do raw JSON reads/writes without recovery/atomicity—corrupted users.json can crash handlers or leave partial writes.

🤖 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 `@commands.py` around lines 8 - 18, The file currently mismatches the project
entrypoint and deps: remove PTB-specific main() and export a
register_commands(bot: telebot.TeleBot) function that main.py expects (reference
symbol: register_commands) so main.py can register handlers on the telebot
instance; align the token env var by replacing TOKEN =
os.environ.get("BOT_TOKEN", ...) with reading TELEGRAM_BOT_TOKEN (or centralize
env var usage to TELEGRAM_BOT_TOKEN) so the token name matches README/main.py;
eliminate imports on unused PTB/apscheduler/pytz or move those features behind
optional flags and list required packages in pyproject.toml so clean installs
succeed; in receive_hour(message_text) stop passing raw user text into
parse_mode="Markdown" — escape or sanitize message_text before sending
(reference symbol: receive_hour); and make load_data()/save_data() robust by
adding JSON parse error handling and atomic writes (read with try/except
JSONDecodeError and on save write to temp file then os.replace) to avoid crashes
or partial writes (reference symbols: load_data, save_data).

Comment thread commands.py
Comment on lines +21 to +23
TOKEN = os.environ.get("BOT_TOKEN", "YOUR_BOT_TOKEN_HERE")
DATA_FILE = "users.json"
TIMEZONE = "Asia/Tehran"

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

Avoid resolving the bot token at import time.

main.py:1-39 calls load_dotenv() after importing commands, so this module reads the token before the .env file is loaded. Combined with the new BOT_TOKEN name, TOKEN can be frozen to the placeholder for the whole process. Resolve it inside main() and fail fast if it is missing.

🤖 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 `@commands.py` around lines 21 - 23, The module currently resolves TOKEN at
import time (TOKEN = os.environ.get(...)) which runs before load_dotenv() in
main; remove the top-level TOKEN assignment and instead read the BOT_TOKEN
inside main() after calling load_dotenv(), validate it and exit/fail fast if
missing, or provide a commands.get_token() accessor that reads env at call-time;
update any code that relied on the module-level TOKEN to accept the token as an
argument or call the new accessor so the real value from .env is used.

Comment thread commands.py
Comment on lines +32 to +40
def load_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r", encoding="utf-8") as f:
return json.load(f)
return {}

def save_data(data):
with open(DATA_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)

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

Harden users.json reads and writes against corruption.

restore_jobs() loads this file during startup, so a truncated or manually edited users.json will raise JSONDecodeError and brick the bot until someone repairs the file. save_data() also writes in place, which makes partial-file corruption possible on crash. Handle decode failures and write via a temp file + replace.

🤖 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 `@commands.py` around lines 32 - 40, Handle corrupted or partially-written
users.json by updating load_data to catch json.JSONDecodeError and return {}
(and optionally log a warning) so restore_jobs() won't crash on startup, and
change save_data to write to a temporary file and then atomically replace
DATA_FILE (e.g., write to DATA_FILE + ".tmp" and use os.replace) to avoid
in-place partial writes; reference the load_data and save_data functions and
DATA_FILE constant when making these changes.

Comment thread commands.py
Comment on lines +163 to +170
await update.message.reply_text(
f"🎉 همه چیز تنظیم شد!\n\n"
f"📢 کانال/گروه: `{channel_id}`\n"
f"⏰ ساعت ارسال: `{hour:02d}:{minute:02d}` (تهران)\n"
f"📝 پیام: {message_text}\n\n"
f"هر روز ساعت {hour:02d}:{minute:02d} پیام ارسال میشه.\n"
f"برای توقف بنویس: /stop",
parse_mode="Markdown"

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

🧩 Analysis chain

🌐 Web query:

Does Telegram Bot API parse_mode="Markdown"require escaping user-provided text containing_, [, ], or backticks before sending?

💡 Result:

Yes, if you use parse_mode="Markdown" (the legacy mode), you must escape specific characters to prevent them from being interpreted as formatting markers [1]. Specifically, in the legacy Markdown mode, the characters _, *, , and [ must be escaped with a backslash if they are intended to be displayed as literal text [1]. If you are using the modern, more robust MarkdownV2 mode (parse_mode="MarkdownV2"), the requirements are much stricter. MarkdownV2 requires escaping a larger set of 18 special characters (including _, *, [, ], , etc.) whenever they appear outside of code blocks or specific formatting contexts [2][3]. Because manual escaping is error-prone, it is highly recommended to either: 1. Use HTML mode (parse_mode="HTML") instead, which only requires escaping <, >, and & [2]. 2. Send the message without a parse_mode and provide an entities array instead, which allows for precise, programmatic formatting without the need for escaping special characters at all [4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and display the relevant section of commands.py
if [ -f commands.py ]; then
  echo "== commands.py =="
  nl -ba commands.py | sed -n '130,200p'
else
  echo "commands.py not found at repo root"
  fd -a -t f 'commands.py' . | head -n 20
fi

Repository: aeither/telegram-bot-python

Length of output: 150


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find commands.py (exactly) and print the relevant section with line numbers
paths="$(fd -a -t f '^commands\.py$' . || true)"
if [ -z "$paths" ]; then
  echo "Could not find commands.py"
  exit 0
fi

echo "Found commands.py at:"
echo "$paths"

# For each match, print 130-200 with line numbers
while IFS= read -r p; do
  echo "== $p =="
  cat -n "$p" | sed -n '130,200p'
done <<< "$paths"

Repository: aeither/telegram-bot-python

Length of output: 2865


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -a -t f 'commands.py$' . | xargs -I{} rg -n 'user_data\["message_text"\]' {}

Repository: aeither/telegram-bot-python

Length of output: 239


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -a -t f 'commands.py$' . | xargs -I{} rg -n 'message_text' {}

Repository: aeither/telegram-bot-python

Length of output: 362


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -a -t f 'commands.py$' . | xargs -I{} rg -n 'user_data\["channel_id"\]' {}

Repository: aeither/telegram-bot-python

Length of output: 225


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -a -t f 'commands.py$' . | xargs -I{} rg -n 'channel_id' {}

Repository: aeither/telegram-bot-python

Length of output: 500


Escape user-provided message_text when using parse_mode="Markdown"
In commands.py (context.user_data["message_text"] = update.message.text and later reply_text(..., parse_mode="Markdown")), message_text is inserted into a legacy Markdown-formatted message without escaping. Telegram legacy Markdown requires escaping special characters (e.g., _, *, `, [), otherwise the confirmation can fail—despite the schedule/job already being saved. Escape message_text (or send the confirmation without Markdown / using entities or HTML).

🤖 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 `@commands.py` around lines 163 - 170, The confirmation reply inserts
user-provided context.user_data["message_text"] (message_text) into
update.message.reply_text with parse_mode="Markdown", which can break for
Telegram legacy Markdown; escape Markdown special characters in message_text
before calling reply_text (or switch to parse_mode="HTML" and escape
accordingly) so the confirmation cannot fail — locate where message_text is
read/used and apply a Markdown-escaping function to message_text prior to
passing it to update.message.reply_text (or remove parse_mode and send plain
text).

Comment thread commands.py
Comment on lines +243 to +274
# ─── اجرای اصلی ────────────────────────────────────────────
def main():
app = Application.builder().token(TOKEN).build()

# Scheduler
scheduler = AsyncIOScheduler()
app.bot_data["scheduler"] = scheduler

# ConversationHandler
conv_handler = ConversationHandler(
entry_points=[CallbackQueryHandler(check_admin_callback, pattern="^check_admin$")],
states={
WAITING_CHANNEL: [MessageHandler(filters.TEXT & ~filters.COMMAND, receive_channel)],
WAITING_MESSAGE: [MessageHandler(filters.TEXT & ~filters.COMMAND, receive_message)],
WAITING_HOUR: [MessageHandler(filters.TEXT & ~filters.COMMAND, receive_hour)],
},
fallbacks=[CommandHandler("cancel", cancel)],
)

app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("stop", stop))
app.add_handler(conv_handler)

# بازیابی jobها و شروع scheduler
scheduler.start()
restore_jobs(scheduler, app)

logger.info("ربات شروع به کار کرد...")
app.run_polling()

if __name__ == "__main__":
main()

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 | ⚡ Quick win

Update the existing entrypoint in the same PR or keep a compatibility shim.

main.py:1-39 still does from commands import register_commands and boots telebot.TeleBot. Since this rewrite removes register_commands and moves startup into commands.main(), the current app either fails on import or never reaches this async flow.

🧰 Tools
🪛 Ruff (0.15.15)

[warning] 266-266: Comment contains ambiguous ه (ARABIC LETTER HEH). Did you mean o (LATIN SMALL LETTER O)?

(RUF003)


[warning] 266-266: Comment contains ambiguous ا (ARABIC LETTER ALEF). Did you mean l (LATIN SMALL LETTER L)?

(RUF003)

🤖 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 `@commands.py` around lines 243 - 274, The repo's old entrypoint expects
register_commands (imported by main.py) but commands.py removed it and now only
exposes main(); add a compatibility shim named register_commands in commands.py
that either (a) wraps/forwards to the new main() startup flow or (b) performs
the previous minimal bootstrap (creates/returns whatever the old main.py
expects, e.g., a TeleBot-like object or a non-blocking startup handle) so
imports don't fail—implement register_commands() near the top-level of
commands.py and ensure it references the same Application.builder()/scheduler
setup or simply delegates to main(), preserving the old import contract.

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