This Telegram bot automatically fetches new subscription links from specified Telegram channels, categorizes them, and pushes them to a GitHub repository. It's designed to be run by individual users via GitHub Actions.
telegram-sub-bot/
├── bot.py # Main bot entrypoint (handles polling and can trigger updates)
├── run_scheduled_updates.py # Script for non-interactive subscription updates (used by GitHub Actions)
├── requirements.txt # Python dependencies
├── .env.example # Template for environment variables for local development
├── README.md # This file
├── .gitignore # Specifies intentionally untracked files that Git should ignore
├── data/
│ └── users.json # Stores user configurations (Telegram ID, channels, optional repo/token)
├── core/
│ ├── handlers/ # Telegram command handlers
│ │ ├── start.py # Handles /start command
│ │ ├── channels.py # Handles /tch command (add, remove, list channels)
│ │ ├── github.py # Handles /status command (placeholder for GitHub Action status)
│ │ └── notify.py # Module for sending notifications to users
│ ├── services/ # Core business logic
│ │ ├── extractor.py # (To be implemented) Fetches posts and extracts links from channels
│ │ ├── builder.py # (To be implemented) Builds subscription files from links
│ │ └── uploader.py # Clones, updates, and pushes to the user's GitHub subscription repository
│ └── utils/ # Utility modules
│ ├── userdb.py # Manages persistence and retrieval of user data from users.json
│ └── config.py # Loads configuration from environment variables and .env file
└── .github/
└── workflows/
└── update.yml # GitHub Actions workflow for scheduled and manual subscription updates
For local development or running the bot outside of GitHub Actions:
- Clone your forked repository.
- Create a virtual environment:
python -m venv venvand activate it (source venv/bin/activateorvenv\Scripts\activateon Windows). - Install dependencies:
pip install -r requirements.txt. - Create a
.envfile in the project root by copying.env.example. - Fill in your
BOT_TOKEN,GITHUB_TOKEN, andDEFAULT_REPOin the.envfile. - To run the bot in polling mode (listening for Telegram commands):
python bot.py - To test the update script locally (simulating an Action run):
python bot.py run_updates
To run this bot for yourself, follow these steps:
Click the "Fork" button at the top right of this page to create your own copy of this repository. This will be your bot repository.
You'll need a Telegram bot token.
- Talk to BotFather on Telegram.
- Use the
/newbotcommand. - Follow the instructions to choose a name and username for your bot.
- BotFather will give you a token. Keep this safe.
The bot needs a GitHub token to push updates to your subscription repository.
- Go to your GitHub Developer settings.
- Click on "Personal access tokens" -> "Tokens (classic)".
- Click "Generate new token" -> "Generate new token (classic)".
- Give your token a descriptive name (e.g.,
TELEGRAM_SUB_BOT_ACTION). - Select the
reposcope. This will allow the token to access and write to your repositories. - Click "Generate token" and copy the token. You won't be able to see it again.
In your forked bot repository (the one you created in Step 1), you need to set up secrets for the GitHub Action to use.
-
Go to your forked bot repository's Settings tab.
-
In the left sidebar, navigate to Secrets and variables -> Actions.
-
Click the New repository secret button for each of the following secrets:
BOT_TOKEN: The Telegram bot token you got from BotFather (Step 2).GITHUB_TOKEN: The GitHub Personal Access Token you created (Step 3). This token will be used by the bot to commit to your subscriptions repository.DEFAULT_REPO(Optional but Recommended): The GitHub repository where the subscription files should be pushed (e.g.,yourusername/my-subscription-links).- This should be the full repository name including username, like
yourusername/my-subs-repo. - Ensure this repository exists before running the bot or Action. The
uploader.pyscript will try to clone it; if the clone fails (e.g., because the repo doesn't exist), the script will error out. - The subscription files will be placed in a
data/subs/directory within this target repository. - If you don't set this, the bot will expect you to configure the repository name through a bot command (which needs to be fully implemented for setting the repository).
- This should be the full repository name including username, like
- Go to the Actions tab in your forked bot repository.
- If you see a banner saying "Workflows aren't running in this repository" or an "I understand my workflows, go ahead and enable them" button, click it to enable Actions.
- The
Update Subscriptionsworkflow is defined in.github/workflows/update.yml. It's scheduled to run every 6 hours by default. You can also trigger it manually from the Actions tab:- Click on "Update Subscriptions" in the workflows list on the left.
- Click the "Run workflow" dropdown button on the right, then "Run workflow".
Create the repository on GitHub that you specified as DEFAULT_REPO (e.g., yourusername/my-subscription-links). This can be a private or public repository. The bot will clone this repository, add files to a data/subs/ directory, and push changes. It's crucial this repository exists.
- Find your bot on Telegram (the one you created with BotFather).
- Send the
/startcommand. - Use the bot commands to configure it:
/start: Displays a welcome message and lists available commands./tch @ChannelNameOrLink: Adds or removes a Telegram channel to fetch subscription links from.- Examples:
/tch @myawesomesubsor/tch https://t.me/publicchannelname - Examples:
/tch @myawesomesubsor/tch https://t.me/publicchannelname - You can also use
/tch listto see your current channels and/tch remove @channelto remove one.
- Examples:
/status: Shows a placeholder message for the status of the last GitHub Action run.- Note: A full implementation for
/statusto show real-time GitHub Actions status would require GitHub API integration and is not yet implemented.
- Note: A full implementation for
- Configuration Commands (Reliance on GitHub Secrets):
- User-specific GitHub repository names or tokens are not currently configurable via bot commands.
- All GitHub-related configurations (target repository, access token) must be set via GitHub Secrets (
DEFAULT_REPO,GITHUB_TOKEN) in your forked bot repository.
- User Interaction (Telegram): You interact with your bot on Telegram using commands like
/startand/tch. Your Telegram user ID and chosen channels are stored indata/users.jsonwithin the bot's repository. - Scheduled/Manual Updates (GitHub Actions):
- The GitHub Action defined in
.github/workflows/update.ymlruns on a schedule (default: every 12 hours) or can be manually dispatched from the Actions tab of your bot repository. - Checkout & Setup: The workflow checks out the bot's code and sets up the Python environment, installing dependencies from
requirements.txt. - Run Update Script: It executes
python bot.py run_updates. This command tellsbot.pyto invoke themain()function fromrun_scheduled_updates.py.
- The GitHub Action defined in
run_scheduled_updates.pyLogic:- This script is the core of the automated update process. It does not start the Telegram poller.
- It loads all user configurations from
data/users.json. - For each user and their specified channels:
- It initializes an
aiogram.Botinstance using theBOT_TOKENsecret. - Fetch & Extract: It calls
core.services.extractor.py(to be implemented) to fetch recent posts from channels and extract subscription links. - Build Subscriptions: It calls
core.services.builder.py(to be implemented) to categorize the extracted links and generate subscription files in various formats (e.g., plain text lists for different protocols). - Upload to GitHub: It calls
core.services.uploader.py(update_subscriptionsfunction) which:- Clones the user's target subscription repository (defined by
DEFAULT_REPOor user-specific settings if ever implemented, usingGITHUB_TOKEN). - Places the newly generated subscription files into a
data/subs/directory within the cloned repository. - Commits and pushes any changes.
- Clones the user's target subscription repository (defined by
- Notify User: After a successful update (or if no new links were found), it uses
core.handlers.notify.pyto send a status message to the user on Telegram.
- It initializes an
- The script exits after processing all users.
core/services/uploader.pyin Detail:- Uses
asyncio.to_threadto rungitcommands non-blockingly. - Manages cloning, committing, and pushing to the target repository specified by
DEFAULT_REPO(or user-specific settings if available) using theGITHUB_TOKEN. - Subscription files are placed in a
data/subs/directory in the target repository.
- Uses
- Core Logic Implementation Status:
core/services/extractor.py: Logic for fetching posts and extracting links is to be implemented.core/services/builder.py: Logic for building various subscription file formats is to be implemented.- The overall workflow for scheduled updates depends on the completion of these modules.
- GitHub Action Execution: The setup with
bot.py run_updatescallingrun_scheduled_updates.pyis designed for efficient execution in GitHub Actions, avoiding the start of the Telegram poller. - Error Handling: Basic error handling is in place in
uploader.pyandrun_scheduled_updates.py. This can be further improved with more specific error reporting and user notifications for critical failures. /statusCommand: Currently provides a static message. Real-time status requires GitHub API integration.- User-Specific GitHub Configuration: The bot currently relies on
DEFAULT_REPOandGITHUB_TOKENsecrets for all users. Storing and using per-user GitHub tokens or repository names via bot commands is not implemented and would require careful security considerations for token storage. - Security of
data/users.json: This file contains Telegram user IDs and their channel lists. If your bot repository is public, this data will also be public. It does not (and should not) store GitHub tokens. - Idempotency: The update process should ideally be idempotent, meaning running it multiple times with the same input should produce the same result in the target repository without causing errors or duplicate entries (e.g.,
uploader.pychecks for actual changes before committing).
By forking this repository and following these setup instructions, you can automate the process of collecting and organizing your Telegram subscription links. Development is ongoing, particularly for the link extraction and subscription building services.