-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Adding a new method of hosting - service/daemon #380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
HostServer001
wants to merge
8
commits into
TgCatUB:beta
Choose a base branch
from
UselessCodeOrg:beta
base: beta
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
cec3a78
install as service
HostServer001 8e30ef7
add: hosting option catuserbot as daemon
HostServer001 96417d9
GITBOOK-1: No subject
HostServer001 273dd25
fix: potential security patch concerns and small fixes
HostServer001 c54014c
Merge branch 'beta' of https://github.com/UselessCodeOrg/catuserbot i…
HostServer001 c7e2eb5
minor changes
HostServer001 c96ff0e
add: idempotency
HostServer001 95a9c14
add: force reinsatll venv
HostServer001 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,4 +113,6 @@ xtraplugins/ | |
| userbot/cache/ | ||
| temp/ | ||
| badcatext/ | ||
| catvc/ | ||
| catvc/ | ||
| temp.png | ||
| neofetch/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| #this file is run using the venv created by uv | ||
| import asyncio | ||
| import logging | ||
| import os | ||
| import subprocess | ||
| import sys | ||
| from dotenv import load_dotenv | ||
| from telethon import TelegramClient | ||
| from telethon.sessions import StringSession, MemorySession | ||
| from telethon.errors import ( | ||
| AuthKeyInvalidError, | ||
| AccessTokenInvalidError, | ||
| AccessTokenExpiredError, | ||
| ChatWriteForbiddenError, | ||
| ) | ||
|
|
||
| load_dotenv() | ||
|
|
||
| logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") | ||
| logger = logging.getLogger("Stage 2") | ||
|
|
||
| CHECK_TIMEOUT = 20 | ||
|
|
||
|
|
||
| async def telegram_user_check(string_session: str, api_id: int, api_hash: str) -> bool: | ||
| logger.info("telegram_user_check") | ||
| try: | ||
| client = TelegramClient(StringSession(string_session), api_id, api_hash) | ||
| await asyncio.wait_for(client.connect(), timeout=CHECK_TIMEOUT) | ||
| try: | ||
| if not await client.is_user_authorized(): | ||
| logger.error("User session is not authorized.") | ||
| return False | ||
| me = await asyncio.wait_for(client.get_me(), timeout=CHECK_TIMEOUT) | ||
| return me is not None | ||
| finally: | ||
| await client.disconnect() | ||
| except asyncio.TimeoutError: | ||
| logger.error("User session check timed out.") | ||
| return False | ||
| except (AuthKeyInvalidError, ValueError) as e: | ||
| logger.error("User session invalid: %s", e) | ||
| return False | ||
| except Exception as e: | ||
| logger.error("User session check: %s", e) | ||
| return False | ||
|
|
||
|
|
||
| async def telegram_bot_check(bot_token: str, api_id: int, api_hash: str) -> bool: | ||
| logger.info("telegram_bot_check") | ||
| try: | ||
| client = await TelegramClient(MemorySession(), api_id, api_hash).start(bot_token=bot_token) | ||
| async with client: | ||
| me = await asyncio.wait_for(client.get_me(), timeout=CHECK_TIMEOUT) | ||
| return me is not None | ||
| except asyncio.TimeoutError: | ||
| logger.error("Bot token check timed out.") | ||
| return False | ||
| except (AccessTokenInvalidError, AccessTokenExpiredError) as e: | ||
| logger.error("Bot token invalid or expired: %s", e) | ||
| return False | ||
| except Exception as e: | ||
| logger.error("Bot token check: %s", e) | ||
| return False | ||
|
|
||
|
|
||
| async def check_bot_group_access(bot_token: str, api_id: int, api_hash: str, group_id: int) -> bool: | ||
| logger.info("check_bot_group_access") | ||
| client = await TelegramClient(MemorySession(), api_id, api_hash).start(bot_token=bot_token) | ||
| try: | ||
| await asyncio.wait_for(client.sendmessage(group_id, "Bot access check"), timeout=CHECK_TIMEOUT) | ||
| return True | ||
| except ChatWriteForbiddenError: | ||
| logger.error("Bot doesn't have permission to send messages in the group.") | ||
| return False | ||
| except ValueError: | ||
| logger.error("Group not found or bot is not a member.") | ||
| return False | ||
| except asyncio.TimeoutError: | ||
| logger.error("Bot group send timed out.") | ||
| return False | ||
| except (AccessTokenInvalidError, AccessTokenExpiredError) as e: | ||
| logger.error("Bot token invalid or expired: %s", e) | ||
| return False | ||
| except Exception as e: | ||
| logger.error("Bot group access check: %s", e, exc_info=True) | ||
| return False | ||
| finally: | ||
| await client.disconnect() | ||
|
|
||
|
|
||
| def is_database_operational(db_name="catuserbot", user="postgres") -> bool: | ||
| logger.info("is_database_operational") | ||
| try: | ||
| subprocess.run( | ||
| ["sudo", "-u", user, "psql", "-d", db_name, "-c", "SELECT 1;"], | ||
| check=True, | ||
| capture_output=True, | ||
| text=True, | ||
| timeout=10, | ||
| ) | ||
| return True | ||
| except subprocess.TimeoutExpired: | ||
| logger.error("Database check timed out.") | ||
| return False | ||
| except Exception as e: | ||
| logger.error("Database check: %s", e) | ||
| return False | ||
|
|
||
|
|
||
| async def main(): | ||
| logger.info("main") | ||
| APP_ID = os.getenv("APP_ID") | ||
| API_HASH = os.getenv("API_HASH") | ||
| STRING_SESSION = os.getenv("STRING_SESSION") | ||
| BOT_TOKEN = os.getenv("TG_BOT_TOKEN") | ||
| # GROUP_ID = Development.PRIVATE_GROUP_BOT_API_ID | ||
|
|
||
| checks = { | ||
| "User session":await telegram_user_check(STRING_SESSION, APP_ID, API_HASH), | ||
| "Bot token":await telegram_bot_check(BOT_TOKEN, APP_ID, API_HASH), | ||
| # "Bot group access":await check_bot_group_access(BOT_TOKEN, APP_ID, API_HASH, GROUP_ID), | ||
| "Database":is_database_operational(), | ||
| } | ||
|
|
||
| failed = [name for name, ok in checks.items() if not ok] | ||
| if failed: | ||
| logger.error("Checks failed: %s", ", ".join(failed)) | ||
| sys.exit(1) | ||
|
|
||
| logger.info("All checks passed.") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| asyncio.run(main()) | ||
|
|
||
| #End of the universe :) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # 📕 Service/Daemon | ||
|
|
||
| {% hint style="info" %} | ||
| This is the newest type of hosting option | ||
| {% endhint %} | ||
|
|
||
|
|
||
|
|
||
| ## ≡ What is Service/Daemon? | ||
|
|
||
| Service also referred as daemon is a process which runs in the background. This process is managed by systemd and can automatically be started on boot. Systemd also tries to restart it if failed. Overall the restart and management of a process is handled by systemd. | ||
|
|
||
| ## ≡ Why Service/Daemon? | ||
|
|
||
| * Its lightweight than docker.  | ||
| * More native to the computer.  | ||
| * Uses less resources | ||
|
|
||
| ## ≡ Requirements | ||
|
|
||
| * PC/Laptop with Linux OS which uses systemd as its system and service manager.\ | ||
| Run the following command to check. | ||
|
|
||
| ```bash | ||
| ps -p 1 -o comm= | ||
| ``` | ||
|
|
||
| If the output is systemd then you can continue to follow the setup steps | ||
|
|
||
| ## ≡ How to Host? | ||
|
|
||
| ### 〣 Clone the repo | ||
|
|
||
| ```bash | ||
| git clone https://github.com/TgCatUB/catuserbot | ||
| ``` | ||
|
|
||
| ### 〣 _**Setup Chromium & its driver**_ | ||
|
|
||
| * First check chromium is installed or not | ||
|
|
||
| ```bash | ||
| which chromium | ||
| ``` | ||
|
|
||
| If the above command return a path like `/usr/bin/chromium` (maybe different path if you installed it else where) put that path in .env files.\ | ||
| If it dosen't return this path follow the following steps to install chromium | ||
|
|
||
| <table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><em><mark style="color:blue;"><strong>Install Chromium or Google-Chrome</strong></mark></em></td><td></td><td><a href="../../.gitbook/assets/chromium_pokemon.jpg">chromium_pokemon.jpg</a></td><td><a href="../guide/chromium-or-chrome-setup.md#chromium">#chromium</a></td></tr></tbody></table> | ||
|
|
||
| ### 〣 _**Edit the .env with your config values**_ <a href="#edit-config" id="edit-config"></a> | ||
|
|
||
| * Copy .env.smaple to .env file by `cp .env.sample .env` | ||
| * Modify the <mark style="color:green;">.env</mark> with any text editor, like `nano .env` | ||
| * Do not add data base url in .env file, the script will make a database itslef | ||
| * **Check :** [<mark style="color:blue;">**Config Values**</mark>](../variables/config-vars.md#mandatory-vars) | ||
|
|
||
| ### 〣 Creating service | ||
|
|
||
| ```bash | ||
| sudo python3 install_as_service.py | ||
| ``` | ||
|
|
||
| sudo is needed for this command to make the `.service` file and place it in `/etc/systemd/system/` directory.\ | ||
| Apart from this the script also installs things like uv, progetsql, and requirements.txt . | ||
|
|
||
| It is advised to check `install_as_service.py` and `install`_`_`_`checker.py` file before you run them. If you have cloned the repo for correct official source no need to worry. | ||
|
|
||
| ### 〣 Monitoring and basic operations | ||
|
|
||
| * To check status of service | ||
|
|
||
| ```bash | ||
| systemctl status catuserbot.service | ||
| ``` | ||
|
|
||
| * To restart the service | ||
|
|
||
| ```bash | ||
| systemctl restart catuserbot.service | ||
| ``` | ||
|
|
||
| * To stop the service | ||
|
|
||
| ```bash | ||
| systemctl stop catuserbot.service | ||
| ``` | ||
|
|
||
| * To start the service | ||
|
|
||
| ```bash | ||
| systemctl start catuserbot.service | ||
| ``` | ||
|
|
||
| * To see journal logs | ||
|
|
||
| ```bash | ||
| sudo journalctl -u catuserbot.service | ||
| ``` | ||
|
|
||
| Logs are also stored in the .log file in the root directory of the clone repo | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small
install_checker.pymarkdown fix need