#!/bin/bash # ๐Ÿš€ SwiftGram MTProxy โ€” Smart Modular Manager # v1.0.5 โ€” Final Working Version (TCP + UDP Calls) # ะŸะพะปะฝั‹ะน ั„ัƒะฝะบั†ะธะพะฝะฐะป, ะฑะตะท ั€ะตะบะปะฐะผั‹, ะธัะฟั€ะฐะฒะปะตะฝะฐ ะปะพะณะธะบะฐ ะฟะพั€ั‚ะพะฒ. # โ”€โ”€ ะะฐัั‚ั€ะพะนะบะธ ั€ะตะฟะพะทะธั‚ะพั€ะธั โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ REPO_RAW_URL="https://git.bargcraft.top/kobalt/swiftgram/raw/branch/main" # โ”€โ”€ ะฆะฒะตั‚ะฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ RED='\033[0;31m' GREEN='\033[0;32m' CYAN='\033[0;36m' YELLOW='\033[1;33m' MAGENTA='\033[0;35m' BLUE='\033[0;34m' WHITE='\033[1;37m' NC='\033[0m' # โ”€โ”€ ะšะพะฝั„ะธะณ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ CONTAINER_NAME="swiftgram-proxy" BOT_DIR="/opt/swiftgram" SERVICE_NAME="swiftgram-bot" # โ”€โ”€ ะกะฟะธะฝะฝะตั€ ะธ ะฟั€ะพะณั€ะตัั-ะฑะฐั€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ spin_pid="" spinner_start() { local msg="${1:-ะŸะพะดะพะถะดะธั‚ะต...}" ( local frames=('โ ‹' 'โ ™' 'โ น' 'โ ธ' 'โ ผ' 'โ ด' 'โ ฆ' 'โ ง' 'โ ‡' 'โ ') local i=0 while true; do printf "\r ${CYAN}${frames[$i]}${NC} ${msg}" >&2 i=$(( (i+1) % ${#frames[@]} )) sleep 0.12 done ) & spin_pid=$! } spinner_stop() { [ -n "$spin_pid" ] && kill "$spin_pid" 2>/dev/null && wait "$spin_pid" 2>/dev/null spin_pid="" printf "\r\033[K" >&2 } progress_bar() { local current="$1" total="$2" label="${3:-}" local pct=$(( current * 100 / total )) local filled=$(( pct / 2 )) local empty=$(( 50 - filled )) local bar="" for ((i=0; i&2 [ "$current" -eq "$total" ] && echo "" >&2 } run_with_progress() { local label="$1"; shift spinner_start "$label" "$@" >/dev/null 2>&1 local rc=$? spinner_stop if [ $rc -eq 0 ]; then echo -e " ${GREEN}โœ“${NC} $label" else echo -e " ${RED}โœ—${NC} $label ${RED}(ะพัˆะธะฑะบะฐ)${NC}" fi return $rc } # โ”€โ”€ ะŸั€ะพะฒะตั€ะบะธ ัะธัั‚ะตะผั‹ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ if [ "$EUID" -ne 0 ]; then echo -e "${RED}ะ—ะฐะฟัƒัั‚ะธั‚ะต ั sudo / root.${NC}" exit 1 fi install_pkg() { if command -v apt-get &>/dev/null; then apt-get update -qq && apt-get install -y -qq "$@" elif command -v dnf &>/dev/null; then dnf install -y "$@" 2>/dev/null elif command -v yum &>/dev/null; then yum install -y "$@" fi } # โ”€โ”€ ะžะฟั‚ะธะผะธะทะฐั†ะธั ะกะตั‚ะธ (BBR) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ optimize_system() { if ! sysctl net.ipv4.tcp_congestion_control | grep -q "bbr"; then spinner_start "ะžะฟั‚ะธะผะธะทะฐั†ะธั ัะตั‚ะตะฒะพะณะพ ัั‚ะตะบะฐ (BBR)..." { echo "net.core.default_qdisc=fq" echo "net.ipv4.tcp_congestion_control=bbr" echo "net.ipv4.ip_local_port_range=1024 65535" echo "net.core.somaxconn=65535" } >> /etc/sysctl.conf sysctl -p >/dev/null 2>&1 spinner_stop echo -e " ${GREEN}โœ“${NC} BBR ัƒัะบะพั€ะตะฝะธะต ะฒะบะปัŽั‡ะตะฝะพ" fi } # โ”€โ”€ Firewall (ะคะธะบั ะทะฒะพะฝะบะพะฒ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ fix_firewall() { local port="$1" if command -v ufw &>/dev/null && ufw status | grep -q "active"; then ufw allow "$port"/tcp >/dev/null 2>&1 ufw allow "$port"/udp >/dev/null 2>&1 elif command -v firewall-cmd &>/dev/null && systemctl is-active --quiet firewalld; then firewall-cmd --permanent --add-port="$port"/tcp >/dev/null 2>&1 firewall-cmd --permanent --add-port="$port"/udp >/dev/null 2>&1 firewall-cmd --reload >/dev/null 2>&1 fi echo -e " ${GREEN}โœ“${NC} Firewall: ะฟะพั€ั‚ั‹ $port (TCP/UDP) ะพั‚ะบั€ั‹ั‚ั‹" } # โ”€โ”€ ะฃัั‚ะฐะฝะพะฒะบะฐ ะทะฐะฒะธัะธะผะพัั‚ะตะน โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ install_base_deps() { local steps=0 total=4 progress_bar $steps $total "ะŸั€ะพะฒะตั€ะบะฐ ะทะฐะฒะธัะธะผะพัั‚ะตะน..." if ! command -v curl &>/dev/null; then run_with_progress "ะฃัั‚ะฐะฝะพะฒะบะฐ curl" install_pkg curl; fi steps=$((steps+1)); progress_bar $steps $total "curl" if ! command -v docker &>/dev/null; then spinner_start "ะฃัั‚ะฐะฝะพะฒะบะฐ Docker..." curl -fsSL https://get.docker.com | sh >/dev/null 2>&1 systemctl enable --now docker >/dev/null 2>&1 spinner_stop fi steps=$((steps+1)); progress_bar $steps $total "docker" if ! command -v qrencode &>/dev/null; then run_with_progress "ะฃัั‚ะฐะฝะพะฒะบะฐ qrencode" install_pkg qrencode; fi steps=$((steps+1)); progress_bar $steps $total "qrencode" if ! docker info &>/dev/null 2>&1; then systemctl start docker 2>/dev/null; sleep 2; fi steps=$((steps+1)); progress_bar $steps $total "ะ“ะพั‚ะพะฒะพ" echo "" } # โ”€โ”€ ะฃั‚ะธะปะธั‚ั‹ IP ะธ ะŸะพั€ั‚ะพะฒ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ get_ip4() { curl -s -4 --max-time 5 https://api.ipify.org || echo "0.0.0.0"; } get_ip6() { curl -s -6 --max-time 5 https://api6.ipify.org || echo ""; } check_port() { local port="$1" if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then local hp=$(docker inspect "$CONTAINER_NAME" --format='{{range $p,$c := .HostConfig.PortBindings}}{{(index $c 0).HostPort}} {{end}}' 2>/dev/null) for p in $hp; do [ "$p" = "$port" ] && return 1; done fi local line=$(ss -tlnp 2>/dev/null | grep -E ":${port}\b" | head -1) [ -n "$line" ] && { echo "$line"; return 0; } return 1 } find_smart_port() { local port=443 if ss -tlnp | grep -qE ":${port}\b"; then echo -e " ${YELLOW}โ„น ะŸะพั€ั‚ 443 ะทะฐะฝัั‚ (Hiddify/Nginx). ะŸั€ะพะฑัƒัŽ 8443...${NC}" >&2 port=8443 if ss -tlnp | grep -qE ":${port}\b"; then port=$(( (RANDOM % 10000) + 20000 )) echo -e " ${YELLOW}โ„น ะŸะพั€ั‚ 8443 ั‚ะพะถะต ะทะฐะฝัั‚. ะ’ั‹ะฑั€ะฐะฝ ัะปัƒั‡ะฐะนะฝั‹ะน: $port${NC}" >&2 fi fi echo "$port" } # โ”€โ”€ ะ˜ะฝั‚ะตะปะปะตะบั‚ัƒะฐะปัŒะฝั‹ะน ะฐะฝะฐะปะธะท ะดะพะผะตะฝะฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ analyze_best_domain() { spinner_start "ะะฝะฐะปะธะท ะดะพะผะตะฝะพะฒ ะดะปั Fake TLS..." local test_domains=("google.com" "wikipedia.org" "github.com" "habr.com" "microsoft.com") local best="google.com" local min=999 for d in "${test_domains[@]}"; do local t=$(ping -c 1 -W 1 "$d" 2>/dev/null | grep 'time=' | awk -F'time=' '{print $2}' | awk '{print $1}') if [ -n "$t" ] && (( $(echo "$t < $min" | bc -l 2>/dev/null || [ ${t%.*} -lt ${min%.*} ]) )); then min=$t; best=$d fi done spinner_stop echo "$best" } # โ”€โ”€ ะŸะพะบะฐะทะฐั‚ัŒ ะดะฐะฝะฝั‹ะต ะฟะพะดะบะปัŽั‡ะตะฝะธั โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ show_config() { if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo -e "${RED}ะŸั€ะพะบัะธ ะฝะต ะทะฐะฟัƒั‰ะตะฝ!${NC}"; return fi local DATA=$(cat "$BOT_DIR/proxy.json" 2>/dev/null) local PORT=$(echo "$DATA" | grep -oP '(?<="port": ")[^"]*') local SECRET=$(echo "$DATA" | grep -oP '(?<="secret": ")[^"]*') local IP4=$(get_ip4) local IP6=$(get_ip6) local LINK="tg://proxy?server=$IP4&port=$PORT&secret=$SECRET" echo -e "\n${CYAN}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" echo -e "${CYAN}โ•‘ ะ”ะะะะซะ• ะŸะžะ”ะšะ›ะฎะงะ•ะะ˜ะฏ โ•‘${NC}" echo -e "${CYAN}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" echo -e " IPv4: ${WHITE}$IP4${NC}" [ -n "$IP6" ] && echo -e " IPv6: ${WHITE}$IP6${NC}" echo -e " ะŸะพั€ั‚: ${WHITE}$PORT${NC} (TCP + UDP)" echo -e " Secret: ${WHITE}$SECRET${NC}" echo -e "\n ะกัั‹ะปะบะฐ: ${BLUE}$LINK${NC}" echo "" qrencode -t ANSIUTF8 "$LINK" } # โ”€โ”€ 1) ะฃัั‚ะฐะฝะพะฒะบะฐ MTProxy โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ menu_install() { clear echo -e "${CYAN}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" echo -e "${CYAN}โ•‘ ะ’ั‹ะฑะตั€ะธั‚ะต ะดะพะผะตะฝ ะดะปั ะผะฐัะบะธั€ะพะฒะบะธ (Fake TLS) โ•‘${NC}" echo -e "${CYAN}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" local domains=( "google.com" "wikipedia.org" "habr.com" "github.com" "coursera.org" "udemy.com" "medium.com" "stackoverflow.com" "bbc.com" "cnn.com" "reuters.com" "nytimes.com" "lenta.ru" "rbc.ru" "ria.ru" "kommersant.ru" "stepik.org" "duolingo.com" "khanacademy.org" "ted.com" ) local best_suggest=$(analyze_best_domain) echo -e " ${GREEN}โ†’ ะ ะตะบะพะผะตะฝะดัƒะตะผั‹ะน ะดะพะผะตะฝ (ะปัƒั‡ัˆะธะน ะฟะธะฝะณ): $best_suggest${NC}\n" for i in "${!domains[@]}"; do printf " ${YELLOW}%2d)${NC} %-22s" "$((i+1))" "${domains[$i]}" [[ $(( (i+1) % 2 )) -eq 0 ]] && echo "" done echo -e "\n ${CYAN}21)${NC} ะ’ะฒะตัั‚ะธ ัะฒะพะน ะดะพะผะตะฝ" local d_idx DOMAIN read -p "ะ’ะฐัˆ ะฒั‹ะฑะพั€ [1-21]: " d_idx if [ "$d_idx" = "21" ]; then read -p " ะ’ะฒะตะดะธั‚ะต ะดะพะผะตะฝ: " DOMAIN DOMAIN=$(echo "$DOMAIN" | tr -d '[:space:]') else DOMAIN=${domains[$((d_idx-1))]} fi DOMAIN=${DOMAIN:-$best_suggest} local PORT=$(find_smart_port) echo -e " ${GREEN}โœ“${NC} ะ˜ั‚ะพะณะพะฒั‹ะน ะฟะพั€ั‚: ${WHITE}$PORT${NC}" optimize_system fix_firewall "$PORT" spinner_start "ะ—ะฐะฟัƒัะบ ะบะพะฝั‚ะตะนะฝะตั€ะฐ (ะบะพะผะฐะฝะดะฐ ะพั€ะธะณะธะฝะฐะปะฐ)..." docker pull nineseconds/mtg:2 >/dev/null 2>&1 local SECRET=$(docker run --rm nineseconds/mtg:2 generate-secret --hex "$DOMAIN" 2>/dev/null) docker stop "$CONTAINER_NAME" &>/dev/null docker rm "$CONTAINER_NAME" &>/dev/null # ะ˜ะกะŸะžะ›ะฌะ—ะฃะ•ะœ ะขะžะงะะฃะฎ ะšะžะœะะะ”ะฃ, ะšะžะขะžะ ะะฏ ะ ะะ‘ะžะขะะ›ะ ะ’ ะžะ ะ˜ะ“ะ˜ะะะ›ะ• docker run -d --name "$CONTAINER_NAME" --restart always \ -p "$PORT":"$PORT"/tcp \ -p "$PORT":"$PORT"/udp \ nineseconds/mtg:2 simple-run \ -n 1.1.1.1 -i prefer-ipv4 \ 0.0.0.0:"$PORT" "$SECRET" > /dev/null 2>&1 sleep 2 spinner_stop if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then mkdir -p "$BOT_DIR" echo "{\"domain\": \"$DOMAIN\", \"port\": \"$PORT\", \"secret\": \"$SECRET\"}" > "$BOT_DIR/proxy.json" echo -e "\n${GREEN}โœ“ SwiftGram ัƒัะฟะตัˆะฝะพ ะทะฐะฟัƒั‰ะตะฝ!${NC}" show_config else echo -e "\n${RED}โœ— ะžัˆะธะฑะบะฐ ะทะฐะฟัƒัะบะฐ. ะŸั€ะพะฒะตั€ัŒั‚ะต: docker logs $CONTAINER_NAME${NC}" fi read -p "ะะฐะถะผะธั‚ะต Enter..." } # โ”€โ”€ 3) ะะฐัั‚ั€ะพะนะบะฐ ะฑะพั‚ะฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ menu_setup_bot() { clear echo -e "${CYAN}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" echo -e "${CYAN}โ•‘ ะะะกะขะ ะžะ™ะšะ TELEGRAM ะ‘ะžะขะ โ•‘${NC}" echo -e "${CYAN}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" if ! command -v python3 &>/dev/null; then run_with_progress "ะฃัั‚ะฐะฝะพะฒะบะฐ Python3" install_pkg python3 python3-pip python3-venv; fi mkdir -p "$BOT_DIR" cd "$BOT_DIR" spinner_start "ะ—ะฐะณั€ัƒะทะบะฐ ะผะพะดัƒะปะตะน ะฑะพั‚ะฐ..." curl -sL "$REPO_RAW_URL/requirements.txt" -o "requirements.txt" curl -sL "$REPO_RAW_URL/bot.py" -o "bot.py" spinner_stop [ ! -d "venv" ] && python3 -m venv venv >/dev/null 2>&1 ./venv/bin/pip install --upgrade pip -q ./venv/bin/pip install -r requirements.txt -q echo -e "\n${YELLOW}ะ’ะฒะตะดะธั‚ะต BOT_TOKEN:${NC}" read -r TOKEN echo -e "${YELLOW}ะ’ะฐัˆ Telegram ID:${NC}" read -r ADMIN_ID { echo "BOT_TOKEN=$TOKEN" echo "ALLOWED_IDS=$ADMIN_ID" echo "CONTAINER_NAME=$CONTAINER_NAME" echo "CONFIG_PATH=$BOT_DIR/proxy.json" } > .env chmod 600 .env cat > "/etc/systemd/system/${SERVICE_NAME}.service" << EOF [Unit] Description=SwiftGram Bot Service After=network.target docker.service [Service] Type=simple WorkingDirectory=$BOT_DIR ExecStart=$BOT_DIR/venv/bin/python $BOT_DIR/bot.py Restart=always [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now "$SERVICE_NAME" systemctl restart "$SERVICE_NAME" echo -e "\n${GREEN}โœ“ ะ‘ะพั‚ ะทะฐะฟัƒั‰ะตะฝ!${NC}" read -p "ะะฐะถะผะธั‚ะต Enter..." } # โ”€โ”€ 7) ะฃะดะฐะปะตะฝะธะต โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ menu_remove() { clear echo -e "${RED}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" echo -e "${RED}โ•‘ ะฃะ”ะะ›ะ•ะะ˜ะ• SWIFTGRAM โ•‘${NC}" echo -e "${RED}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" read -p " ะฃะดะฐะปะธั‚ัŒ ะฟะพะปะฝะพัั‚ัŒัŽ? (y/N): " yn [[ "$yn" != "y" ]] && return local words=("ะฃะ”ะะ›ะ˜ะขะฌ" "SWIFTGRAM" "ะžะงะ˜ะกะขะšะ") local confirm_word="${words[$((RANDOM % ${#words[@]}))]}" echo -e " ะ’ะฒะตะดะธั‚ะต ัะปะพะฒะพ: ${WHITE}$confirm_word${NC}" read -p " >>> " input_word [[ "$input_word" != "$confirm_word" ]] && return spinner_start "ะžั‡ะธัั‚ะบะฐ..." docker stop "$CONTAINER_NAME" &>/dev/null; docker rm "$CONTAINER_NAME" &>/dev/null systemctl stop "$SERVICE_NAME" 2>/dev/null; systemctl disable "$SERVICE_NAME" 2>/dev/null rm -f "/etc/systemd/system/${SERVICE_NAME}.service"; rm -rf "$BOT_DIR"; rm -f /usr/local/bin/swiftgram spinner_stop echo -e "${GREEN}โœ“ ะกะธัั‚ะตะผะฐ ะพั‡ะธั‰ะตะฝะฐ.${NC}"; read -p "Enter..." } # โ”€โ”€ ะ“ะปะฐะฒะฝั‹ะน ั†ะธะบะป โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ install_base_deps SELF="$(realpath "$0")" [ "$SELF" != "/usr/local/bin/swiftgram" ] && { cp "$SELF" /usr/local/bin/swiftgram; chmod +x /usr/local/bin/swiftgram; } while true; do clear echo -e "${MAGENTA}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" echo -e "${MAGENTA}โ•‘ SWIFTGRAM MANAGER (Professional) โ•‘${NC}" echo -e "${MAGENTA}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$" && echo -e " ะŸั€ะพะบัะธ: ${GREEN}ะ ะะ‘ะžะขะะ•ะข${NC}" || echo -e " ะŸั€ะพะบัะธ: ${RED}ะ’ะซะšะ›ะฎะงะ•ะ${NC}" systemctl is-active --quiet "$SERVICE_NAME" && echo -e " ะ‘ะพั‚: ${GREEN}ะ ะะ‘ะžะขะะ•ะข${NC}" || echo -e " ะ‘ะพั‚: ${YELLOW}ะะ• ะะะกะขะ ะžะ•ะ${NC}" echo -e "\n ${GREEN}1)${NC} ะฃัั‚ะฐะฝะพะฒะธั‚ัŒ / ะžะฑะฝะพะฒะธั‚ัŒ ะฟั€ะพะบัะธ\n ${GREEN}2)${NC} ะŸะพะบะฐะทะฐั‚ัŒ ะดะฐะฝะฝั‹ะต (QR)\n ${CYAN}3)${NC} ะะฐัั‚ั€ะพะธั‚ัŒ Telegram-ะฑะพั‚ะฐ\n ${GREEN}4)${NC} ะŸะตั€ะตะทะฐะฟัƒัั‚ะธั‚ัŒ ะฟั€ะพะบัะธ\n ${GREEN}5)${NC} ะ›ะพะณะธ ะฟั€ะพะบัะธ\n ${RED}6)${NC} ะฃะดะฐะปะธั‚ัŒ SwiftGram\n ${WHITE}0)${NC} ะ’ั‹ั…ะพะด" read -p "ะŸัƒะฝะบั‚: " m_idx case $m_idx in 1) menu_install ;; 2) clear; show_config; read -p "ะะฐะถะผะธั‚ะต Enter..." ;; 3) menu_setup_bot ;; 4) docker restart "$CONTAINER_NAME"; echo "ะ“ะพั‚ะพะฒะพ"; sleep 1 ;; 5) docker logs --tail 50 "$CONTAINER_NAME"; read -p "Enter..." ;; 6) menu_remove ;; 0) exit 0 ;; esac done