From f62a24ececd9405a5cdb15234f8f5672c5e49536 Mon Sep 17 00:00:00 2001 From: Corrado Mulas Date: Fri, 19 Jun 2026 11:33:42 +0200 Subject: [PATCH] Added Argo Manifests --- CONFIGURATION_GUIDE.md | 2 - IMPLEMENTATION_COMPLETE.md | 1 - README.md | 14 ++++- argocd/application.yaml | 18 ++++++ deployment.yaml | 35 ------------ examples/configmap.yaml | 16 ++++++ examples/secret.yaml | 14 +++++ k8s/deployment.yaml | 66 ++++++++++++++++++++++ namespace.yaml => k8s/namespace.yaml | 0 k8s/service.yaml | 17 ++++++ scripts/generate_telegram_session.py | 82 ++++++++++++++++++++++++++++ src/config.py | 14 +++-- src/main.py | 4 +- 13 files changed, 236 insertions(+), 47 deletions(-) create mode 100644 argocd/application.yaml delete mode 100644 deployment.yaml create mode 100644 examples/configmap.yaml create mode 100644 examples/secret.yaml create mode 100644 k8s/deployment.yaml rename namespace.yaml => k8s/namespace.yaml (100%) create mode 100644 k8s/service.yaml create mode 100755 scripts/generate_telegram_session.py diff --git a/CONFIGURATION_GUIDE.md b/CONFIGURATION_GUIDE.md index 315d6d5..f6371da 100644 --- a/CONFIGURATION_GUIDE.md +++ b/CONFIGURATION_GUIDE.md @@ -277,7 +277,6 @@ Make sure these are set in your `.env` file: ```bash TELETHON_API_ID=your_api_id TELETHON_API_HASH=your_api_hash -TELEGRAM_BOT_TOKEN=your_bot_token TELETHON_TOKEN=your_session_token MONGODB_URI=mongodb://localhost:27017 @@ -328,7 +327,6 @@ services: environment: TELETHON_API_ID: ${TELETHON_API_ID} TELETHON_API_HASH: ${TELETHON_API_HASH} - TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN} TELETHON_TOKEN: ${TELETHON_TOKEN} MONGODB_URI: mongodb://mongo:27017 MONGODB_DATABASE: groupfactory diff --git a/IMPLEMENTATION_COMPLETE.md b/IMPLEMENTATION_COMPLETE.md index 113407c..773a980 100644 --- a/IMPLEMENTATION_COMPLETE.md +++ b/IMPLEMENTATION_COMPLETE.md @@ -205,7 +205,6 @@ The telegram-groupfactory bot now has a complete **admin-only configuration syst # Telegram TELETHON_API_ID=your_api_id TELETHON_API_HASH=your_api_hash -TELEGRAM_BOT_TOKEN=your_bot_token TELETHON_TOKEN=your_session_token # MongoDB diff --git a/README.md b/README.md index 454c2b1..a9d8bb6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # telegram-groupfactory -A Telegram bot for managing user groups with MongoDB backend and admin-only configuration. +A Telegram user API service for managing groups with MongoDB backend and admin-only configuration. ## Features @@ -10,7 +10,7 @@ A Telegram bot for managing user groups with MongoDB backend and admin-only conf - ✅ GroupHelp settings backup QR storage for `.importbackup` - ✅ Interactive admin role selection for group creators - ✅ Modular architecture with separation of concerns -- ✅ Telegram bot integration using Telethon +- ✅ Telegram user API integration using Telethon ## Architecture @@ -31,7 +31,6 @@ The application follows a modular architecture with the following components: ``` TELETHON_API_ID=your_api_id TELETHON_API_HASH=your_api_hash - TELEGRAM_BOT_TOKEN=your_bot_token TELETHON_TOKEN=your_session_token MONGODB_URI=mongodb://localhost:27017 @@ -42,6 +41,15 @@ The application follows a modular architecture with the following components: FACTORY_BOT_ID=your_bot_id ``` + Generate `TELETHON_TOKEN` with: + ```bash + TELETHON_API_ID=your_api_id TELETHON_API_HASH=your_api_hash \ + python3 scripts/generate_telegram_session.py + ``` + + The script performs a Telegram user login and prints the `TELETHON_TOKEN` + value to store in the Kubernetes Secret. + 2. Install dependencies: ```bash pip install -r requirements.txt diff --git a/argocd/application.yaml b/argocd/application.yaml new file mode 100644 index 0000000..820aaf0 --- /dev/null +++ b/argocd/application.yaml @@ -0,0 +1,18 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: groupfactory + namespace: argocd +spec: + project: default + source: + repoURL: https://github.com/YOUR_ORG/telegram-groupfactory.git + targetRevision: main + path: k8s + destination: + server: https://kubernetes.default.svc + namespace: groupfactory + syncPolicy: + syncOptions: + - CreateNamespace=true + - PruneLast=true diff --git a/deployment.yaml b/deployment.yaml deleted file mode 100644 index 8c11963..0000000 --- a/deployment.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: groupfactory - namespace: groupfactory - labels: - app: groupfactory -spec: - replicas: 1 - selector: - matchLabels: - app: groupfactory - template: - metadata: - labels: - app: groupfactory - spec: - containers: - - name: groupfactory - image: /groupfactory:latest - envFrom: - - configMapRef: - name: telegram-config - - secretRef: - name: groupfactory-tg-auth - env: - - name: MONGODB_URI - valueFrom: - secretKeyRef: - name: groupfactory-tg-auth - key: MONGODB_URI - - name: MONGODB_DATABASE - value: "imsuserbot" - - name: MONGODB_COLLECTION - value: "ghconfig" \ No newline at end of file diff --git a/examples/configmap.yaml b/examples/configmap.yaml new file mode 100644 index 0000000..ea779e0 --- /dev/null +++ b/examples/configmap.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: telegram-config + namespace: groupfactory + labels: + app.kubernetes.io/name: groupfactory +data: + API_HOST: "0.0.0.0" + API_PORT: "8000" + LOG_LEVEL: "INFO" + MONGODB_DATABASE: "imsuserbot" + MONGODB_COLLECTION: "ghconfig" + TELETHON_API_ID: "123456" + STAFF_CHAT_ID: "-1001234567890" + FACTORY_BOT_ID: "123456789" diff --git a/examples/secret.yaml b/examples/secret.yaml new file mode 100644 index 0000000..9252a5a --- /dev/null +++ b/examples/secret.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: groupfactory-tg-auth + namespace: groupfactory + labels: + app.kubernetes.io/name: groupfactory +type: Opaque +stringData: + API_KEY: "change-me-api-key" + MONGODB_URI: "mongodb://mongo:27017" + TELETHON_API_HASH: "replace-with-telegram-api-hash" + # Generate with: python3 scripts/generate_telegram_session.py + TELETHON_TOKEN: "replace-with-telethon-session-token" diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml new file mode 100644 index 0000000..abe3827 --- /dev/null +++ b/k8s/deployment.yaml @@ -0,0 +1,66 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: groupfactory + namespace: groupfactory + labels: + app.kubernetes.io/name: groupfactory + app.kubernetes.io/component: app +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: groupfactory + app.kubernetes.io/component: app + template: + metadata: + labels: + app.kubernetes.io/name: groupfactory + app.kubernetes.io/component: app + spec: + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + containers: + - name: groupfactory + image: registry.example.com/groupfactory:latest + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8000 + envFrom: + - configMapRef: + name: telegram-config + - secretRef: + name: groupfactory-tg-auth + readinessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 30 + periodSeconds: 20 + startupProbe: + httpGet: + path: /health + port: http + failureThreshold: 30 + periodSeconds: 5 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL diff --git a/namespace.yaml b/k8s/namespace.yaml similarity index 100% rename from namespace.yaml rename to k8s/namespace.yaml diff --git a/k8s/service.yaml b/k8s/service.yaml new file mode 100644 index 0000000..4ae5f5d --- /dev/null +++ b/k8s/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: groupfactory + namespace: groupfactory + labels: + app.kubernetes.io/name: groupfactory + app.kubernetes.io/component: app +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: groupfactory + app.kubernetes.io/component: app + ports: + - name: http + port: 8000 + targetPort: http diff --git a/scripts/generate_telegram_session.py b/scripts/generate_telegram_session.py new file mode 100755 index 0000000..12f52c5 --- /dev/null +++ b/scripts/generate_telegram_session.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +"""Generate a Telethon StringSession for TELETHON_TOKEN. + +Examples: + TELETHON_API_ID=123456 TELETHON_API_HASH=abc123 \ + python3 scripts/generate_telegram_session.py + + python3 scripts/generate_telegram_session.py \ + --api-id 123456 \ + --api-hash abc123 \ + --phone +391234567890 +""" + +import argparse +import asyncio +import os +import sys + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Generate a Telethon StringSession for the TELETHON_TOKEN secret." + ) + parser.add_argument( + "--api-id", + default=os.environ.get("TELETHON_API_ID"), + help="Telegram API ID. Defaults to TELETHON_API_ID.", + ) + parser.add_argument( + "--api-hash", + default=os.environ.get("TELETHON_API_HASH"), + help="Telegram API hash. Defaults to TELETHON_API_HASH.", + ) + parser.add_argument( + "--phone", + default=os.environ.get("TELETHON_PHONE"), + help="Telegram user phone number. Defaults to TELETHON_PHONE.", + ) + + args = parser.parse_args() + if not args.api_id: + parser.error("--api-id or TELETHON_API_ID is required") + try: + args.api_id = int(args.api_id) + except ValueError: + parser.error("--api-id or TELETHON_API_ID must be an integer") + if not args.api_hash: + parser.error("--api-hash or TELETHON_API_HASH is required") + return args + + +async def generate_session(args: argparse.Namespace) -> str: + from telethon import TelegramClient + from telethon.sessions import StringSession + + client = TelegramClient(StringSession(), args.api_id, args.api_hash) + try: + phone = args.phone or input("Telegram phone number, including country code: ") + await client.start(phone=phone) + return client.session.save() + finally: + await client.disconnect() + + +def main() -> int: + args = parse_args() + print( + "Starting Telegram user login. The final stdout line is the TELETHON_TOKEN value.", + file=sys.stderr, + ) + session_string = asyncio.run(generate_session(args)) + if not session_string: + print("Failed to generate a session string.", file=sys.stderr) + return 1 + + print(session_string) + print("Store this value as TELETHON_TOKEN in the Kubernetes Secret.", file=sys.stderr) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/config.py b/src/config.py index d44d16b..4aa5dc6 100644 --- a/src/config.py +++ b/src/config.py @@ -2,11 +2,11 @@ import os from pymongo import MongoClient from pymongo.errors import ConnectionFailure from telethon import TelegramClient +from telethon.sessions import StringSession # Telegram configuration TELETHON_TOKEN = os.environ.get("TELETHON_TOKEN") TELETHON_API_HASH = os.environ.get("TELETHON_API_HASH") -TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN") TELETHON_API_ID = int(os.environ.get("TELETHON_API_ID", 0)) STAFF_CHAT_ID = int(os.environ.get("STAFF_CHAT_ID", 0)) FACTORY_BOT_ID = int(os.environ.get("FACTORY_BOT_ID", 0)) @@ -19,6 +19,12 @@ MONGODB_COLLECTION = os.environ.get('MONGODB_COLLECTION', '') # Logging configuration LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') +def get_telegram_session(): + """Return a Telethon session backed by TELETHON_TOKEN when configured.""" + if TELETHON_TOKEN: + return StringSession(TELETHON_TOKEN) + return 'session' + # MongoDB helper functions def get_mongo_client(): """Create and return MongoDB client""" @@ -34,7 +40,7 @@ def get_telegram_client(): """Create and return Telegram client""" try: client = TelegramClient( - 'session', + get_telegram_session(), TELETHON_API_ID, TELETHON_API_HASH ) @@ -65,7 +71,7 @@ def load_config(): 'telegram': { 'api_id': TELETHON_API_ID, 'api_hash': TELETHON_API_HASH, - 'bot_token': TELEGRAM_BOT_TOKEN, + 'session': get_telegram_session(), 'session_file': 'session', 'staff_chat_id': STAFF_CHAT_ID, 'factory_bot_id': FACTORY_BOT_ID @@ -178,4 +184,4 @@ def get_user_admin_role(user_id: int) -> bool: return False except Exception as e: print(f"Failed to get user admin role: {e}") - return False \ No newline at end of file + return False diff --git a/src/main.py b/src/main.py index 63f619a..b587a2f 100644 --- a/src/main.py +++ b/src/main.py @@ -44,7 +44,7 @@ async def main(): # Create Telegram client client = TelegramClient( - config['telegram']['session_file'], + config['telegram']['session'], config['telegram']['api_id'], config['telegram']['api_hash'] ) @@ -350,4 +350,4 @@ async def main(): logger.info("Application shutdown complete") if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + asyncio.run(main())