From e166126c5e344597453ebe35af3d35115f62bb58 Mon Sep 17 00:00:00 2001 From: bisug Date: Mon, 8 Jun 2026 14:20:19 +0545 Subject: [PATCH 1/3] docs: update README and render.yaml for clarity on Render service configuration --- README.md | 7 ++++--- render.yaml | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dda08cf..188b373 100644 --- a/README.md +++ b/README.md @@ -134,17 +134,18 @@ Render provides the most stable environment for Ether with native Docker support 2. Click the **Deploy to Render** button above. 3. Connect your GitHub account and select the forked repository. 4. Configure the **Environment Variables** (see [Configuration](#configuration)). - * **Crucial:** Ensure `WEB_SERVICE` is set to `true` to prevent the service from sleeping. + * **Crucial:** Ensure `WEB_SERVICE` is set to `true` so Render can reach the health-check web endpoint. + * **Free plan note:** Render free web services still sleep after idle periods. Use an external HTTP monitor or a paid always-on service if you need 24/7 uptime. 5. Render will automatically build and deploy the container. --- ### Keep-Alive & Automation (Cloud) -Cloud providers like Render often put free-tier apps to "sleep" after inactivity. Use these tools to ensure Ether stays online 24/7. +Cloud providers like Render often put free-tier apps to "sleep" after inactivity. External monitors can reduce idle sleep, but a paid always-on service or VPS is the more reliable option for a 24/7 userbot. #### UptimeRobot (Keep-Alive) -To prevent Render from sleeping, set up a monitor to ping your bot's URL: +To keep a Render web service receiving inbound HTTP traffic, set up a monitor to ping your bot's URL: 1. Go to [UptimeRobot](https://uptimerobot.com/) and create a free account. 2. Click **Add New Monitor**. 3. **Monitor Type**: `HTTP(s)` diff --git a/render.yaml b/render.yaml index 1fd3bbf..145e9d4 100644 --- a/render.yaml +++ b/render.yaml @@ -7,10 +7,10 @@ services: plan: free region: oregon - autoDeploy: false + autoDeployTrigger: off - # Use root endpoint for health checks (always available) - healthCheckPath: / + # Use the lightweight health endpoint for Render health checks. + healthCheckPath: /health envVars: # Telegram API Credentials (Required - Get from my.telegram.org) From 27d9b833bc991c7e90a86ba578494babff516f85 Mon Sep 17 00:00:00 2001 From: bisug Date: Mon, 8 Jun 2026 14:29:59 +0545 Subject: [PATCH 2/3] fix: update datetime handling in logger and upgrade package versions in requirements --- plugins/logger.py | 7 ++++--- requirements.txt | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/logger.py b/plugins/logger.py index f0ad82b..887d8d1 100644 --- a/plugins/logger.py +++ b/plugins/logger.py @@ -20,7 +20,7 @@ # ============================================================================= import time -from datetime import datetime, timedelta +from datetime import UTC, datetime, timedelta from telethon import events from utils.logger import get_logger from utils.task_helper import safe_run @@ -179,14 +179,15 @@ async def cache_messages(event): ): return - expire_at = datetime.utcnow() + timedelta(hours=48) + now = datetime.now(UTC) + expire_at = now + timedelta(hours=48) await msg_col.insert_one({ "msg_id": event.id, "chat_id": event.chat_id, "sender_id": event.sender_id, "text": event.text, - "date": datetime.utcnow(), + "date": now, "expire_at": expire_at }) diff --git a/requirements.txt b/requirements.txt index 8183364..38ed314 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ -aiohttp==3.13.5 -fastapi==0.136.1 +aiohttp==3.14.1 +fastapi==0.136.3 psutil==7.2.2 -pymongo[srv]==4.13.0 -python-dotenv==1.2.0 -telethon==1.43.0 -uvicorn[standard]==0.47.0 \ No newline at end of file +pymongo==4.17.0 +python-dotenv==1.2.2 +telethon==1.43.2 +uvicorn[standard]==0.49.0 From 0a606dd5324d6e2a28e3790bfa1d17e652babefd Mon Sep 17 00:00:00 2001 From: bisug Date: Mon, 8 Jun 2026 14:49:16 +0545 Subject: [PATCH 3/3] feat: enhance configuration and deployment settings for Ether Userbot --- .env.example | 7 ++- Procfile | 2 +- README.md | 140 +++++++++++++++++++++++++++++++++------------ app.json | 4 +- docker-compose.yml | 21 +++---- heroku.yml | 2 + render.yaml | 2 +- 7 files changed, 125 insertions(+), 53 deletions(-) diff --git a/.env.example b/.env.example index 28e1c00..498ee75 100644 --- a/.env.example +++ b/.env.example @@ -25,8 +25,13 @@ API_HASH= OWNER_ID= BOT_TOKEN= -BOT_USERNAME= # without @ +# Optional: bot username without @. Usually auto-fetched from BOT_TOKEN. +BOT_USERNAME= MONGO_URI= +DB_NAME=Ether +SESSION_NAME=etheruserbot DEBUG=False +WEB_SERVICE=False +PORT=8080 diff --git a/Procfile b/Procfile index eb131d6..25fcdc8 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -worker: python3 main.py +worker: python main.py diff --git a/README.md b/README.md index 188b373..4207d92 100644 --- a/README.md +++ b/README.md @@ -103,20 +103,21 @@ Ether uses environment variables for configuration. These can be set in a `.env` | :--- | :--- | :--- | | `API_ID` | Required | Your Telegram API ID from [my.telegram.org](https://my.telegram.org) | | `API_HASH` | Required | Your Telegram API Hash from [my.telegram.org](https://my.telegram.org) | -| `BOT_TOKEN` | Required | Your Bot Token from [@BotFather](https://t.me/BotFather) | | `OWNER_ID` | Required | Your numeric Telegram User ID | +| `BOT_TOKEN` | Required | Your Bot Token from [@BotFather](https://t.me/BotFather) | | `MONGO_URI` | Required | MongoDB Atlas connection string | -| `BOT_USERNAME` | Required | Your Bot's username (without @) | +| `BOT_USERNAME` | Optional | Auto-fetched from `BOT_TOKEN`; set manually only if needed | +| `SESSION_NAME` | Optional | MongoDB session document name (Default: `etheruserbot`) | | `DB_NAME` | Optional | Database name (Default: `Ether`) | | `DEBUG` | Optional | Set to `true` for verbose logging (Default: `false`) | -| `WEB_SERVICE` | Optional | Set to `true` for cloud keep-alive services | -| `PORT` | Optional | Port for the web service (Default: `8080`) | +| `WEB_SERVICE` | Optional | Set to `true` when the host requires an HTTP health endpoint | +| `PORT` | Optional | Port for the web service (Default: `8080`; Render uses `10000`) | --- ## Deployment Options -Ether is designed to be deployed anywhere. Choose the platform that fits your needs. +Ether is a long-running Telegram client. For reliable operation, use a host that allows long-lived processes and provide a persistent MongoDB database for sessions and settings.
@@ -126,31 +127,57 @@ Ether is designed to be deployed anywhere. Choose the platform that fits your ne
+### Deployment Matrix + +| Target | Files Used | Runtime Type | How to Verify | +| :--- | :--- | :--- | :--- | +| Render | `render.yaml`, `Dockerfile` | Docker web service | HTTP health check at `/health` | +| Heroku | `app.json`, `heroku.yml`, `Dockerfile` | Container worker dyno | Worker logs and Telegram `/login` | +| Docker Compose / VPS | `docker-compose.yml`, `Dockerfile` | Local Docker service | `docker compose config` and `/health` | +| Manual Python | `requirements.txt`, `main.py` | Local Python process | Import and compile checks | +| JustRunMyApp / Generic Docker Host | `Dockerfile` | Long-running Docker container | Same env vars and health endpoint rules as Docker | + ### Quick Start Guides #### 1. Cloud Hosting (Render - Recommended) -Render provides the most stable environment for Ether with native Docker support. +Render should be deployed as a Docker **Web Service** because Render requires web services to bind an HTTP port. + 1. **Fork** this repository to your own GitHub account. 2. Click the **Deploy to Render** button above. 3. Connect your GitHub account and select the forked repository. -4. Configure the **Environment Variables** (see [Configuration](#configuration)). - * **Crucial:** Ensure `WEB_SERVICE` is set to `true` so Render can reach the health-check web endpoint. - * **Free plan note:** Render free web services still sleep after idle periods. Use an external HTTP monitor or a paid always-on service if you need 24/7 uptime. -5. Render will automatically build and deploy the container. +4. Use the checked-in `render.yaml` blueprint: + * Runtime: `docker` + * Dockerfile: `./Dockerfile` + * Health check path: `/health` + * `PORT=10000` + * `WEB_SERVICE=true` +5. Set the required environment variables from [Configuration](#configuration). +6. Deploy, then open: + ```text + https://your-app.onrender.com/health + ``` + Expected response: + ```json + {"status":"healthy"} + ``` +7. Open your Telegram bot and run `/login`. + +> [!IMPORTANT] +> Render Free web services sleep after idle periods and can restart at any time. The HTTP endpoint keeps the deploy valid, but it does not make the free plan always-on. Use a paid Render instance, VPS, or another always-on host for a 24/7 userbot. --- ### Keep-Alive & Automation (Cloud) -Cloud providers like Render often put free-tier apps to "sleep" after inactivity. External monitors can reduce idle sleep, but a paid always-on service or VPS is the more reliable option for a 24/7 userbot. +Cloud providers often put free-tier apps to sleep after inactivity. External monitors can reduce idle sleep, but a paid always-on service or VPS is the more reliable option for a 24/7 userbot. #### UptimeRobot (Keep-Alive) -To keep a Render web service receiving inbound HTTP traffic, set up a monitor to ping your bot's URL: +To keep a Render web service receiving inbound HTTP traffic, set up a monitor to ping the health endpoint: 1. Go to [UptimeRobot](https://uptimerobot.com/) and create a free account. 2. Click **Add New Monitor**. 3. **Monitor Type**: `HTTP(s)` 4. **Friendly Name**: `Ether Userbot` -5. **URL**: Your Render app URL (e.g., `https://your-app.onrender.com/`) +5. **URL**: `https://your-app.onrender.com/health` 6. **Monitoring Interval**: Every `5 minutes`. 7. Click **Create Monitor**. @@ -158,28 +185,50 @@ To keep a Render web service receiving inbound HTTP traffic, set up a monitor to If you need to trigger specific bot actions or ensure the web service remains active via external triggers: 1. Create an account at [Cron-job.org](https://cron-job.org/). 2. Create a **New Cronjob**. -3. **URL**: Your Render app URL. +3. **URL**: `https://your-app.onrender.com/health` 4. **Schedule**: Every 5 or 10 minutes. 5. This acts as a secondary heart-beat for your bot. --- #### 2. Heroku Deployment -Ideal for users familiar with the Heroku ecosystem. +Heroku should be deployed as a container **worker** dyno. Do not run a web dyno unless you add a separate web process. + 1. Click the **Deploy to Heroku** button above. 2. Enter a unique app name and fill in the required environment variables. 3. Once the build finishes, go to the **Resources** tab. -4. **Important:** Turn off the `web` dyno and turn **ON** the `worker` dyno. -5. Render will automatically build and deploy the container. +4. Confirm the `worker` dyno is enabled and the `web` dyno is disabled. +5. Set `WEB_SERVICE=false` for worker-only Heroku deployments. +6. Check logs: + ```bash + heroku logs --tail --ps worker -a your-app-name + ``` +7. Open your Telegram bot and run `/login`. + +CLI deployment: +```bash +heroku create your-app-name +heroku stack:set container -a your-app-name +heroku config:set API_ID=... API_HASH=... OWNER_ID=... BOT_TOKEN=... MONGO_URI=... WEB_SERVICE=false -a your-app-name +git push heroku main +heroku ps:scale web=0 worker=1 -a your-app-name +``` + +> [!NOTE] +> Heroku no longer has free dynos. Use a paid dyno type appropriate for a long-running worker. --- #### 3. JustRunMyApp (One-Click) -A simple, zero-config deployment platform. +Use this path only if the platform supports long-running Docker containers and runtime environment variables. + 1. Click the **Deploy Now** button for JustRunMyApp above. -2. Paste the repository URL: `https://github.com/LearningBotsOfficial/Ether` -3. Follow the on-screen prompts to set your Environment Variables. -4. Launch the app and wait for the status to show "Running". +2. Paste the repository URL: `https://github.com/LearningBotsOfficial/Ether`. +3. Choose Dockerfile-based deployment. +4. Set the required environment variables from [Configuration](#configuration). +5. If the platform requires an HTTP endpoint, set `WEB_SERVICE=true` and `PORT` to the platform-provided port. +6. Launch the app and wait for the status to show `Running`. +7. If a public URL is provided, verify `/health`. #### 4. Docker Deployment (Local / VPS) The preferred method for developers and privacy-focused users. @@ -192,10 +241,20 @@ cp .env.example .env nano .env # 3. Build and launch with Docker Compose -docker-compose up -d --build +docker compose up -d --build + +# 4. Verify the service +docker compose ps +curl http://localhost:8080/health ``` + +For Windows PowerShell, the health check command is: +```powershell +Invoke-RestMethod http://localhost:8080/health +``` + > [!TIP] -> Using Docker Compose handles the health checks and automatic restarts for you. +> Docker Compose sets `WEB_SERVICE=true`, exposes `${PORT:-8080}`, and uses the `/health` endpoint for container health checks. If you set `PORT` in `.env`, use that value instead of `8080` in the health check URL. #### 5. Manual Setup (Linux / VPS / Windows) For users who want full control over the environment. @@ -222,7 +281,8 @@ For users who want full control over the environment. .venv\Scripts\activate # Install dependencies - pip install -r requirements.txt + python -m pip install --upgrade pip + python -m pip install -r requirements.txt ``` 4. **Configure Environment Variables** @@ -238,6 +298,12 @@ For users who want full control over the environment. python main.py ``` + If your host requires a health endpoint, set: + ```bash + export WEB_SERVICE=true + export PORT=8080 + ``` + --- ### Managing Dependencies & Upgrading @@ -245,30 +311,28 @@ For users who want full control over the environment. #### Adding or Removing Packages To add a new library: ```bash -pip install -# Then update requirements.txt -pip freeze > requirements.txt +python -m pip install +# Then add the reviewed direct dependency pin to requirements.txt ``` To remove a library: ```bash -pip uninstall -# Then update requirements.txt -pip freeze > requirements.txt +python -m pip uninstall +# Then remove the direct dependency pin from requirements.txt ``` -#### Upgrading All Packages -To upgrade all dependencies to their latest versions: +#### Syncing Pinned Dependencies +Install exactly the versions listed in `requirements.txt`: ```bash -pip install --upgrade -r requirements.txt -pip freeze > requirements.txt +python -m pip install -r requirements.txt ``` -#### Syncing Environment -Whenever you pull new changes from GitHub that include an updated `requirements.txt`, simply run: +If you use `uv`: ```bash -pip install -r requirements.txt +uv pip install -r requirements.txt ``` -This ensures your local `.venv` matches the project's requirements. + +#### Upgrading Dependency Pins +Pinned requirements do not upgrade automatically. To upgrade safely, check the latest package versions, edit `requirements.txt`, sync the environment, and run the verification commands in the deployment section. --- diff --git a/app.json b/app.json index 42d81f6..4d0efd2 100644 --- a/app.json +++ b/app.json @@ -34,7 +34,7 @@ "required": true }, "WEB_SERVICE": { - "description": "Set to true to enable the keep-alive web service (requires 'web' process type).", + "description": "Set to false for the default Heroku worker dyno. Use true only if you add a web process.", "value": "false", "required": false }, @@ -51,4 +51,4 @@ } }, "stack": "container" -} \ No newline at end of file +} diff --git a/docker-compose.yml b/docker-compose.yml index e4b5cde..119945a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: ether-userbot: build: . @@ -7,15 +5,18 @@ services: restart: unless-stopped env_file: - .env + environment: + WEB_SERVICE: "true" + PORT: "${PORT:-8080}" + ports: + - "${PORT:-8080}:${PORT:-8080}" volumes: - # Map the specific directories where data is generated - ./media:/app/media - ./logs:/app/logs - # Map session files explicitly to persist logins - ./sessions:/app/sessions - # Note: Since the bot creates session files in the root dir by default - # you may need to map them explicitly or configure SESSION_DIR in .env - - ./:/app/sessions_data # Or bind mount specific .session files - # If the app relies heavily on an external MongoDB, - # network settings can be configured here. - network_mode: bridge + healthcheck: + test: ["CMD-SHELL", "python -c \"import os, urllib.request; urllib.request.urlopen('http://127.0.0.1:' + os.getenv('PORT', '8080') + '/health', timeout=5).read()\""] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s diff --git a/heroku.yml b/heroku.yml index 7b13190..c8ad1f4 100644 --- a/heroku.yml +++ b/heroku.yml @@ -1,3 +1,5 @@ build: docker: worker: Dockerfile +run: + worker: python main.py diff --git a/render.yaml b/render.yaml index 145e9d4..220a95e 100644 --- a/render.yaml +++ b/render.yaml @@ -32,7 +32,7 @@ services: - key: MONGO_URI sync: false - # Port (Render will override with dynamic port) + # Public HTTP port for the health-check web service. - key: PORT value: "10000"