Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,6 @@ xtraplugins/
userbot/cache/
temp/
badcatext/
catvc/
catvc/
temp.png
neofetch/
137 changes: 137 additions & 0 deletions _install_checker.py
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 :)
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [📕 Self Host](installation/hosting/self-host.md)
* [📕 Heroku](installation/hosting/heroku.md)
* [📕 Railway](installation/hosting/railway.md)
* [📕 Service/Daemon](installation/hosting/service-daemon.md)
* [📚 Variables](installation/variables/README.md)
* [📕 Config Vars](installation/variables/config-vars.md)
* [📕 Database Vars](installation/variables/database-vars.md)
Expand Down
8 changes: 4 additions & 4 deletions docs/installation/hosting/self-host.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ sudo apt-get update && sudo apt-get install nodejs -y

{% code title="Change dir to catuserbot & make config.py to save config values" overflow="wrap" %}
```batch
git clone https://github.com/TgCatUB/catuserbot && cd catuserbot && mv exampleconfig.py config.py
git clone https://github.com/TgCatUB/catuserbot && cd catuserbot && mv .env.sample .env
```
{% endcode %}

### 〣 _**Setup Chromium & its driver**_ <a href="#setup-chromium" id="setup-chromium"></a>

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-type="select" data-multiple></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>
<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 config.py with your config values**_ <a href="#edit-config" id="edit-config"></a>
### 〣 _**Edit the .env with your config values**_ <a href="#edit-config" id="edit-config"></a>

* Modify the <mark style="color:green;">config.py</mark> with any text editor, like `nano config.py`
* Modify the <mark style="color:green;">.env</mark> with any text editor, like `nano config.py`
* **Check :** [<mark style="color:blue;">**Config Values**</mark>](../variables/config-vars.md#mandatory-vars)

### 〣 _**Create a Virtual**_ environment _**& install requirements**_ <a href="#create-venv" id="create-venv"></a>
Expand Down
101 changes: 101 additions & 0 deletions docs/installation/hosting/service-daemon.md
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.&#x20;
* More native to the computer.&#x20;
* 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

small install_checker.py markdown fix need


### 〣 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
Loading