Skip to content

Instantly share code, notes, and snippets.

@Zxce3
Created March 17, 2025 21:43
Show Gist options
  • Save Zxce3/08df2045829e72453f4358a5a6905ac2 to your computer and use it in GitHub Desktop.
Save Zxce3/08df2045829e72453f4358a5a6905ac2 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Telegram API Server Manager
# Author: Zxce3
# Date: 2025-03-17
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Default values
REPO_DIR="TelegramApiServer"
SESSION_NAME="session"
DEFAULT_PORT=9503
# Print banner
print_banner() {
echo -e "${GREEN}=================================${NC}"
echo -e "${GREEN} Telegram API Server Manager${NC}"
echo -e "${GREEN}=================================${NC}"
}
# Print usage information
print_usage() {
echo -e "Usage: $0 [command]"
echo
echo -e "Commands:"
echo -e " ${YELLOW}install${NC} - Install Telegram API Server"
echo -e " ${YELLOW}start${NC} - Start the server (in background)"
echo -e " ${YELLOW}stop${NC} - Stop the server"
echo -e " ${YELLOW}restart${NC} - Restart the server"
echo -e " ${YELLOW}status${NC} - Check server status"
echo -e " ${YELLOW}update${NC} - Update the server"
echo -e " ${YELLOW}logs${NC} - Show server logs"
echo -e " ${YELLOW}setup-auth${NC} - Set up authentication"
echo -e " ${YELLOW}add-session${NC} - Add a new session"
echo -e " ${YELLOW}session-list${NC} - List all sessions"
echo -e " ${YELLOW}unlink-session${NC} - Remove a session"
echo -e " ${YELLOW}interactive${NC} - Start interactive mode for authentication"
}
check_dependencies() {
local missing_deps=()
for cmd in git docker docker-compose curl jq; do
if ! command -v $cmd &> /dev/null; then
missing_deps+=($cmd)
fi
done
if [ ${#missing_deps[@]} -ne 0 ]; then
echo -e "${RED}Error: Missing dependencies: ${missing_deps[*]}${NC}"
echo -e "Please install the required dependencies and try again"
exit 1
fi
}
# Check if docker is running
check_docker_running() {
if ! docker info &> /dev/null; then
echo -e "${RED}Error: Docker is not running${NC}"
echo -e "Please start Docker service and try again"
exit 1
fi
}
# Check if the repo directory exists
check_repo_exists() {
if [ ! -d "$REPO_DIR" ]; then
echo -e "${RED}Error: Telegram API Server not installed${NC}"
echo -e "Please run '$0 install' first"
exit 1
fi
}
# Install Telegram API Server
install_server() {
echo -e "${GREEN}Installing Telegram API Server...${NC}"
# Clone repository if it doesn't exist
if [ ! -d "$REPO_DIR" ]; then
git clone https://github.com/xtrime-ru/TelegramApiServer.git "$REPO_DIR"
else
echo -e "${YELLOW}Directory $REPO_DIR already exists${NC}"
fi
# Navigate to repository directory
cd "$REPO_DIR"
# Copy environment file if it doesn't exist
if [ ! -f ".env.docker" ]; then
cp .env.docker.example .env.docker
echo -e "${YELLOW}Created .env.docker from example file${NC}"
fi
# Pull Docker images
docker-compose pull
echo -e "${GREEN}Installation completed${NC}"
echo -e "${YELLOW}Next steps:${NC}"
echo -e "1. Edit .env.docker file to add app_id and app_hash from my.telegram.org"
echo -e " Command: nano $REPO_DIR/.env.docker"
echo -e "2. Start the server in interactive mode to authenticate:"
echo -e " Command: $0 interactive"
}
# Start the server in background
start_server() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Starting Telegram API Server...${NC}"
docker-compose up -d
echo -e "${GREEN}Server started${NC}"
}
# Stop the server
stop_server() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Stopping Telegram API Server...${NC}"
docker-compose down
echo -e "${GREEN}Server stopped${NC}"
}
# Restart the server
restart_server() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Restarting Telegram API Server...${NC}"
docker-compose restart
echo -e "${GREEN}Server restarted${NC}"
}
# Check server status
check_status() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Checking Telegram API Server status...${NC}"
docker-compose ps
}
# Update the server
update_server() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Updating Telegram API Server...${NC}"
# Pull latest changes
git fetch
git reset --hard origin/master
# Remove vendor directory
rm -rf vendor/
# Compare environment files and prompt for update if needed
echo -e "${YELLOW}Please check if your .env.docker file needs to be updated${NC}"
echo -e "You can compare .env.docker with .env.docker.example"
# Recreate containers
docker-compose pull
docker-compose down
docker-compose up -d
echo -e "${GREEN}Update completed${NC}"
}
# Show server logs
show_logs() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Showing Telegram API Server logs...${NC}"
docker-compose logs "$@"
}
# Start interactive mode for authentication
interactive_mode() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Starting Telegram API Server in interactive mode...${NC}"
echo -e "${YELLOW}Follow the prompts to authenticate your session${NC}"
echo -e "${YELLOW}Press Ctrl+C to exit when completed${NC}"
docker-compose run --rm api
}
# Configure authentication in .env.docker
setup_auth() {
check_repo_exists
cd "$REPO_DIR"
local env_file=".env.docker"
local temp_file=".env.docker.tmp"
echo -e "${GREEN}Setting up authentication...${NC}"
# Security mode options
echo -e "${YELLOW}Select security mode:${NC}"
echo "1. IP whitelist only (default)"
echo "2. Basic auth with username and password"
echo "3. Both IP whitelist and basic auth"
read -p "Select option [1-3]: " security_option
# Handle IP whitelist
if [[ "$security_option" == "1" || "$security_option" == "3" ]]; then
read -p "Enter comma-separated IP whitelist (leave blank for localhost only): " ip_whitelist
ip_whitelist=${ip_whitelist:-127.0.0.1}
else
ip_whitelist=""
fi
# Handle basic auth
if [[ "$security_option" == "2" || "$security_option" == "3" ]]; then
read -p "Enter username: " username
read -s -p "Enter password: " password
echo
passwords="{\"$username\":\"$password\"}"
else
passwords="{}"
fi
# Update .env.docker file
cat "$env_file" | sed "s/^IP_WHITELIST=.*$/IP_WHITELIST=$ip_whitelist/" | \
sed "s/^PASSWORDS=.*$/PASSWORDS=$passwords/" > "$temp_file"
mv "$temp_file" "$env_file"
echo -e "${GREEN}Authentication settings updated${NC}"
# Ask if user wants to set up Telegram API credentials
read -p "Do you want to set up Telegram API credentials? [y/N]: " setup_api
if [[ "$setup_api" == "y" || "$setup_api" == "Y" ]]; then
read -p "Enter Telegram app_id: " app_id
read -p "Enter Telegram app_hash: " app_hash
# Update API credentials
cat "$env_file" | sed "s/^TELEGRAM_API_ID=.*$/TELEGRAM_API_ID=$app_id/" | \
sed "s/^TELEGRAM_API_HASH=.*$/TELEGRAM_API_HASH=$app_hash/" > "$temp_file"
mv "$temp_file" "$env_file"
echo -e "${GREEN}Telegram API credentials updated${NC}"
fi
# Ask if server should be restarted
read -p "Do you want to restart the server to apply changes? [y/N]: " restart_now
if [[ "$restart_now" == "y" || "$restart_now" == "Y" ]]; then
restart_server
fi
}
# Add a new session
add_session() {
check_repo_exists
read -p "Enter session name: " new_session
if [ -z "$new_session" ]; then
echo -e "${RED}Error: Session name cannot be empty${NC}"
return 1
fi
# Create override file if it doesn't exist
if [ ! -f "$REPO_DIR/docker-compose.override.yml" ]; then
cat > "$REPO_DIR/docker-compose.override.yml" <<EOL
services:
EOL
fi
# Generate a unique port number
local port=$((DEFAULT_PORT + 10))
while grep -q "$port:$DEFAULT_PORT" "$REPO_DIR/docker-compose.override.yml" 2>/dev/null; do
port=$((port + 1))
done
# Add new service to override file
cat >> "$REPO_DIR/docker-compose.override.yml" <<EOL
api-$new_session:
extends:
file: docker-compose.base.yml
service: base-api
ports:
- "127.0.0.1:$port:$DEFAULT_PORT"
command:
- "-s=$new_session"
EOL
echo -e "${GREEN}Added new session '$new_session' on port $port${NC}"
echo -e "${YELLOW}Restart the server to apply changes:${NC} $0 restart"
}
# List all sessions
list_sessions() {
check_repo_exists
cd "$REPO_DIR"
echo -e "${GREEN}Available sessions:${NC}"
# List default session
echo -e "Default session: ${YELLOW}$SESSION_NAME${NC} (port $DEFAULT_PORT)"
# List sessions from override file
if [ -f "docker-compose.override.yml" ]; then
echo -e "\nAdditional sessions:"
grep -A 3 "command:" docker-compose.override.yml | grep -E '("-s=|port)' | \
awk 'BEGIN{RS="--";FS="\n"} {for(i=1;i<=NF;i++) print $i}' | \
sed -n 'N;s/.*"-s=\(.*\)".*127.0.0.1:\([0-9]*\).*/ \1 (port \2)/p'
fi
# Check running sessions
echo -e "\n${GREEN}Running sessions:${NC}"
docker-compose ps | grep -v "Name"
}
# Remove a session
unlink_session() {
check_repo_exists
cd "$REPO_DIR"
# Show available sessions
list_sessions
read -p "Enter session name to remove: " session_to_remove
if [ -z "$session_to_remove" ]; then
echo -e "${RED}Error: Session name cannot be empty${NC}"
return 1
fi
# Check if it's the default session
if [ "$session_to_remove" == "$SESSION_NAME" ]; then
echo -e "${RED}Cannot remove default session${NC}"
return 1
fi
# Remove session from override file
if [ -f "docker-compose.override.yml" ]; then
# Create a temporary file
temp_file=$(mktemp)
# Extract the service section to remove
start_line=$(grep -n "api-$session_to_remove:" docker-compose.override.yml | cut -d: -f1)
if [ -z "$start_line" ]; then
echo -e "${RED}Session '$session_to_remove' not found${NC}"
rm "$temp_file"
return 1
fi
# Find the end of the service section
end_line=$(tail -n +$((start_line + 1)) docker-compose.override.yml | grep -n "^ [a-zA-Z]" | head -1 | cut -d: -f1)
if [ -z "$end_line" ]; then
# If this is the last service, count to the end of file
end_line=$(wc -l < docker-compose.override.yml)
else
end_line=$((start_line + end_line))
fi
# Remove the service section
sed -n "1,$((start_line - 1))p" docker-compose.override.yml > "$temp_file"
sed -n "$((end_line + 1)),\$p" docker-compose.override.yml >> "$temp_file"
# Replace the original file
mv "$temp_file" docker-compose.override.yml
echo -e "${GREEN}Session '$session_to_remove' removed${NC}"
echo -e "${YELLOW}Restart the server to apply changes:${NC} $0 restart"
echo -e "${YELLOW}Note: Session file still exists. To remove it completely, use:${NC}"
echo -e "curl http://127.0.0.1:$DEFAULT_PORT/system/unlinkSessionFile?session=$session_to_remove"
else
echo -e "${RED}No override file found${NC}"
return 1
fi
}
# Main script execution
print_banner
check_dependencies
# Process command
case "$1" in
install)
check_docker_running
install_server
;;
start)
check_docker_running
start_server
;;
stop)
stop_server
;;
restart)
check_docker_running
restart_server
;;
status)
check_status
;;
update)
check_docker_running
update_server
;;
logs)
show_logs "${@:2}"
;;
setup-auth)
setup_auth
;;
interactive)
check_docker_running
interactive_mode
;;
add-session)
add_session
;;
session-list)
list_sessions
;;
unlink-session)
unlink_session
;;
*)
print_usage
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment