fix: rename script
This commit is contained in:
684
html_mail_send.sh
Executable file
684
html_mail_send.sh
Executable file
@@ -0,0 +1,684 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# html_mail_send.sh - A sophisticated HTML email sender
|
||||
# Sends HTML emails via SMTP with style
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# COLORS & STYLING
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
# Reset
|
||||
RST='\033[0m'
|
||||
|
||||
# Regular Colors
|
||||
BLK='\033[0;30m' RED='\033[0;31m' GRN='\033[0;32m' YLW='\033[0;33m'
|
||||
BLU='\033[0;34m' MAG='\033[0;35m' CYN='\033[0;36m' WHT='\033[0;37m'
|
||||
|
||||
# Bold Colors
|
||||
BBLK='\033[1;30m' BRED='\033[1;31m' BGRN='\033[1;32m' BYLW='\033[1;33m'
|
||||
BBLU='\033[1;34m' BMAG='\033[1;35m' BCYN='\033[1;36m' BWHT='\033[1;37m'
|
||||
|
||||
# Background Colors
|
||||
BGBLK='\033[40m' BGRED='\033[41m' BGGRN='\033[42m' BGYLW='\033[43m'
|
||||
BGBLU='\033[44m' BGMAG='\033[45m' BGCYN='\033[46m' BGWHT='\033[47m'
|
||||
|
||||
# Special
|
||||
DIM='\033[2m' ITALIC='\033[3m' ULINE='\033[4m' BLINK='\033[5m'
|
||||
|
||||
# Gradient colors (256 color mode)
|
||||
G1='\033[38;5;39m' # Light blue
|
||||
G2='\033[38;5;38m' # Cyan
|
||||
G3='\033[38;5;37m' # Teal
|
||||
G4='\033[38;5;36m' # Sea green
|
||||
G5='\033[38;5;35m' # Green
|
||||
|
||||
# Accent colors
|
||||
ACC1='\033[38;5;213m' # Pink
|
||||
ACC2='\033[38;5;207m' # Hot pink
|
||||
ACC3='\033[38;5;171m' # Purple
|
||||
ACC4='\033[38;5;135m' # Violet
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# UNICODE SYMBOLS
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
SYM_CHECK="✓"
|
||||
SYM_CROSS="✗"
|
||||
SYM_ARROW="→"
|
||||
SYM_MAIL="✉"
|
||||
SYM_LOCK="🔒"
|
||||
SYM_SEND="📤"
|
||||
SYM_DOT="●"
|
||||
SYM_STAR="★"
|
||||
SYM_BOLT="⚡"
|
||||
SYM_INFO="ℹ"
|
||||
SYM_WARN="⚠"
|
||||
|
||||
# Box drawing characters
|
||||
BOX_TL="╭" BOX_TR="╮" BOX_BL="╰" BOX_BR="╯"
|
||||
BOX_H="─" BOX_V="│" BOX_HB="━"
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# CONFIGURATION
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
VERSION="1.0.0"
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
|
||||
# Default values
|
||||
SMTP_SERVER=""
|
||||
SMTP_PORT="587"
|
||||
SMTP_USER=""
|
||||
SMTP_PASS=""
|
||||
SMTP_TLS="yes"
|
||||
FROM_EMAIL=""
|
||||
FROM_NAME=""
|
||||
TO_EMAIL=""
|
||||
SUBJECT=""
|
||||
HTML_FILE=""
|
||||
VERBOSE=false
|
||||
DRY_RUN=false
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# HELPER FUNCTIONS
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
print_header() {
|
||||
local width=60
|
||||
echo ""
|
||||
echo -e "${G1}${BOX_TL}$(printf '%*s' $((width-2)) '' | tr ' ' "$BOX_H")${BOX_TR}${RST}"
|
||||
echo -e "${G2}${BOX_V}${RST} ${BMAG}${SYM_MAIL}${RST} ${BWHT}S E N D _ M A I L${RST} ${ACC1}v${VERSION}${RST}$(printf '%*s' 23 '')${G2}${BOX_V}${RST}"
|
||||
echo -e "${G3}${BOX_V}${RST} ${DIM}${ITALIC}Sophisticated HTML Email Sender${RST}$(printf '%*s' 18 '')${G3}${BOX_V}${RST}"
|
||||
echo -e "${G4}${BOX_BL}$(printf '%*s' $((width-2)) '' | tr ' ' "$BOX_H")${BOX_BR}${RST}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_section() {
|
||||
local title="$1"
|
||||
echo -e "\n${ACC3}${SYM_STAR}${RST} ${BCYN}${title}${RST}"
|
||||
echo -e "${DIM}$(printf '%*s' 50 '' | tr ' ' '─')${RST}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${BGRN}${SYM_CHECK}${RST} ${GRN}$1${RST}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${BRED}${SYM_CROSS}${RST} ${RED}$1${RST}" >&2
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${BYLW}${SYM_WARN}${RST} ${YLW}$1${RST}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BCYN}${SYM_INFO}${RST} ${CYN}$1${RST}"
|
||||
}
|
||||
|
||||
print_step() {
|
||||
echo -e " ${ACC1}${SYM_ARROW}${RST} ${WHT}$1${RST}"
|
||||
}
|
||||
|
||||
print_value() {
|
||||
local label="$1"
|
||||
local value="$2"
|
||||
printf " ${DIM}%-15s${RST} ${BWHT}%s${RST}\n" "$label:" "$value"
|
||||
}
|
||||
|
||||
spinner() {
|
||||
local pid=$1
|
||||
local message="${2:-Processing}"
|
||||
local spinchars='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
|
||||
local i=0
|
||||
|
||||
tput civis # Hide cursor
|
||||
while kill -0 "$pid" 2>/dev/null; do
|
||||
printf "\r ${ACC2}${spinchars:i++%${#spinchars}:1}${RST} ${WHT}%s...${RST}" "$message"
|
||||
sleep 0.1
|
||||
done
|
||||
tput cnorm # Show cursor
|
||||
printf "\r%*s\r" 50 "" # Clear line
|
||||
}
|
||||
|
||||
progress_bar() {
|
||||
local current=$1
|
||||
local total=$2
|
||||
local width=30
|
||||
local percent=$((current * 100 / total))
|
||||
local filled=$((current * width / total))
|
||||
local empty=$((width - filled))
|
||||
|
||||
local bar=""
|
||||
for ((i=0; i<filled; i++)); do
|
||||
if ((i < filled / 3)); then
|
||||
bar+="${G1}${SYM_DOT}${RST}"
|
||||
elif ((i < 2 * filled / 3)); then
|
||||
bar+="${G3}${SYM_DOT}${RST}"
|
||||
else
|
||||
bar+="${G5}${SYM_DOT}${RST}"
|
||||
fi
|
||||
done
|
||||
for ((i=0; i<empty; i++)); do
|
||||
bar+="${DIM}○${RST}"
|
||||
done
|
||||
|
||||
printf "\r [%s] ${BWHT}%3d%%${RST}" "$bar" "$percent"
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# USAGE & HELP
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
show_usage() {
|
||||
print_header
|
||||
|
||||
echo -e "${BWHT}USAGE${RST}"
|
||||
echo -e " ${GRN}$SCRIPT_NAME${RST} ${CYN}[OPTIONS]${RST} ${YLW}-s SERVER -u USER -p PASS -f FROM -t TO -j SUBJECT -h FILE${RST}"
|
||||
echo ""
|
||||
|
||||
echo -e "${BWHT}REQUIRED OPTIONS${RST}"
|
||||
echo -e " ${BCYN}-s, --server${RST} ${DIM}SERVER${RST} SMTP server hostname"
|
||||
echo -e " ${BCYN}-u, --user${RST} ${DIM}USER${RST} SMTP username"
|
||||
echo -e " ${BCYN}-p, --pass${RST} ${DIM}PASS${RST} SMTP password (or use SMTP_PASSWORD env var)"
|
||||
echo -e " ${BCYN}-f, --from${RST} ${DIM}EMAIL${RST} Sender email address"
|
||||
echo -e " ${BCYN}-t, --to${RST} ${DIM}EMAIL${RST} Recipient email address"
|
||||
echo -e " ${BCYN}-j, --subject${RST} ${DIM}TEXT${RST} Email subject line"
|
||||
echo -e " ${BCYN}-h, --html${RST} ${DIM}FILE${RST} Path to HTML file"
|
||||
echo ""
|
||||
|
||||
echo -e "${BWHT}OPTIONAL${RST}"
|
||||
echo -e " ${BCYN}-P, --port${RST} ${DIM}PORT${RST} SMTP port (default: 587)"
|
||||
echo -e " ${BCYN}-n, --name${RST} ${DIM}NAME${RST} Sender display name"
|
||||
echo -e " ${BCYN} --no-tls${RST} Disable TLS/STARTTLS"
|
||||
echo -e " ${BCYN} --ssl${RST} Use SSL (port 465)"
|
||||
echo -e " ${BCYN}-v, --verbose${RST} Verbose output"
|
||||
echo -e " ${BCYN} --dry-run${RST} Show what would be sent without sending"
|
||||
echo -e " ${BCYN} --help${RST} Show this help message"
|
||||
echo -e " ${BCYN} --version${RST} Show version"
|
||||
echo ""
|
||||
|
||||
echo -e "${BWHT}EXAMPLES${RST}"
|
||||
echo -e " ${DIM}# Basic usage${RST}"
|
||||
echo -e " ${GRN}$SCRIPT_NAME${RST} -s smtp.gmail.com -u user@gmail.com -p 'app-password' \\"
|
||||
echo -e " -f user@gmail.com -t recipient@example.com \\"
|
||||
echo -e " -j 'Hello World' -h email.html"
|
||||
echo ""
|
||||
echo -e " ${DIM}# Using environment variable for password${RST}"
|
||||
echo -e " ${YLW}export SMTP_PASSWORD='your-password'${RST}"
|
||||
echo -e " ${GRN}$SCRIPT_NAME${RST} -s smtp.example.com -u user -f sender@example.com \\"
|
||||
echo -e " -t recipient@example.com -j 'Subject' -h template.html"
|
||||
echo ""
|
||||
echo -e " ${DIM}# With sender name and custom port${RST}"
|
||||
echo -e " ${GRN}$SCRIPT_NAME${RST} -s mail.example.com -P 465 --ssl \\"
|
||||
echo -e " -u user -p pass -f sender@example.com -n 'John Doe' \\"
|
||||
echo -e " -t recipient@example.com -j 'Important' -h message.html"
|
||||
echo ""
|
||||
|
||||
echo -e "${BWHT}ENVIRONMENT VARIABLES${RST}"
|
||||
echo -e " ${BCYN}SMTP_PASSWORD${RST} SMTP password (alternative to -p flag)"
|
||||
echo ""
|
||||
|
||||
echo -e "${DIM}─────────────────────────────────────────────────────${RST}"
|
||||
echo -e "${DIM}Requires: curl with SMTP support${RST}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_version() {
|
||||
echo -e "${BMAG}${SYM_MAIL}${RST} ${BWHT}html_mail_send.sh${RST} ${ACC1}v${VERSION}${RST}"
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# VALIDATION
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
validate_email() {
|
||||
local email="$1"
|
||||
if [[ "$email" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
validate_file() {
|
||||
local file="$1"
|
||||
if [[ -f "$file" && -r "$file" ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
if ! command -v curl &>/dev/null; then
|
||||
print_error "curl is required but not installed"
|
||||
echo -e " ${DIM}Install with: ${RST}${CYN}sudo apt install curl${RST}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if curl has SMTP support
|
||||
if ! curl -V | grep -q 'smtp'; then
|
||||
print_warning "curl may not have SMTP support"
|
||||
fi
|
||||
}
|
||||
|
||||
validate_inputs() {
|
||||
local errors=0
|
||||
|
||||
print_section "Validating Configuration"
|
||||
|
||||
# Check required fields
|
||||
if [[ -z "$SMTP_SERVER" ]]; then
|
||||
print_error "SMTP server is required (-s, --server)"
|
||||
((errors++))
|
||||
else
|
||||
print_success "SMTP server: $SMTP_SERVER"
|
||||
fi
|
||||
|
||||
if [[ -z "$SMTP_USER" ]]; then
|
||||
print_error "SMTP username is required (-u, --user)"
|
||||
((errors++))
|
||||
else
|
||||
print_success "SMTP user: $SMTP_USER"
|
||||
fi
|
||||
|
||||
if [[ -z "$SMTP_PASS" ]]; then
|
||||
# Try environment variable
|
||||
if [[ -n "${SMTP_PASSWORD:-}" ]]; then
|
||||
SMTP_PASS="$SMTP_PASSWORD"
|
||||
print_success "SMTP password: (from environment)"
|
||||
else
|
||||
print_error "SMTP password is required (-p, --pass or SMTP_PASSWORD env var)"
|
||||
((errors++))
|
||||
fi
|
||||
else
|
||||
print_success "SMTP password: ********"
|
||||
fi
|
||||
|
||||
if [[ -z "$FROM_EMAIL" ]]; then
|
||||
print_error "From email is required (-f, --from)"
|
||||
((errors++))
|
||||
elif ! validate_email "$FROM_EMAIL"; then
|
||||
print_error "Invalid from email format: $FROM_EMAIL"
|
||||
((errors++))
|
||||
else
|
||||
print_success "From: ${FROM_NAME:+$FROM_NAME <}$FROM_EMAIL${FROM_NAME:+>}"
|
||||
fi
|
||||
|
||||
if [[ -z "$TO_EMAIL" ]]; then
|
||||
print_error "To email is required (-t, --to)"
|
||||
((errors++))
|
||||
elif ! validate_email "$TO_EMAIL"; then
|
||||
print_error "Invalid to email format: $TO_EMAIL"
|
||||
((errors++))
|
||||
else
|
||||
print_success "To: $TO_EMAIL"
|
||||
fi
|
||||
|
||||
if [[ -z "$SUBJECT" ]]; then
|
||||
print_error "Subject is required (-j, --subject)"
|
||||
((errors++))
|
||||
else
|
||||
print_success "Subject: $SUBJECT"
|
||||
fi
|
||||
|
||||
if [[ -z "$HTML_FILE" ]]; then
|
||||
print_error "HTML file is required (-h, --html)"
|
||||
((errors++))
|
||||
elif ! validate_file "$HTML_FILE"; then
|
||||
print_error "HTML file not found or not readable: $HTML_FILE"
|
||||
((errors++))
|
||||
else
|
||||
local size
|
||||
size=$(stat -c%s "$HTML_FILE" 2>/dev/null || stat -f%z "$HTML_FILE" 2>/dev/null || echo "?")
|
||||
print_success "HTML file: $HTML_FILE (${size} bytes)"
|
||||
fi
|
||||
|
||||
if ((errors > 0)); then
|
||||
echo ""
|
||||
print_error "Found $errors error(s). Please fix and try again."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_success "All validations passed!"
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# EMAIL SENDING
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
generate_boundary() {
|
||||
echo "----=_Part_$(date +%s%N)_$(od -An -tx4 -N4 /dev/urandom | tr -d ' ')"
|
||||
}
|
||||
|
||||
send_email() {
|
||||
print_section "Preparing Email"
|
||||
|
||||
local boundary
|
||||
boundary=$(generate_boundary)
|
||||
|
||||
# Build From header
|
||||
local from_header
|
||||
if [[ -n "$FROM_NAME" ]]; then
|
||||
from_header="$FROM_NAME <$FROM_EMAIL>"
|
||||
else
|
||||
from_header="$FROM_EMAIL"
|
||||
fi
|
||||
|
||||
# Generate message ID
|
||||
local msg_id
|
||||
msg_id="<$(date +%s%N).$(od -An -tx4 -N4 /dev/urandom | tr -d ' ')@${SMTP_SERVER}>"
|
||||
|
||||
# Current date in RFC 2822 format
|
||||
local date_header
|
||||
date_header=$(date -R)
|
||||
|
||||
print_step "Building MIME message..."
|
||||
|
||||
# Create temporary file for email content
|
||||
local tmp_email
|
||||
tmp_email=$(mktemp)
|
||||
# Store in global for cleanup trap
|
||||
_TMP_EMAIL="$tmp_email"
|
||||
trap 'rm -f "$_TMP_EMAIL"' EXIT
|
||||
|
||||
# Build the email with proper CRLF line endings for SMTP
|
||||
{
|
||||
printf 'From: %s\r\n' "$from_header"
|
||||
printf 'To: %s\r\n' "$TO_EMAIL"
|
||||
printf 'Subject: %s\r\n' "$SUBJECT"
|
||||
printf 'Date: %s\r\n' "$date_header"
|
||||
printf 'Message-ID: %s\r\n' "$msg_id"
|
||||
printf 'MIME-Version: 1.0\r\n'
|
||||
printf 'Content-Type: multipart/alternative; boundary="%s"\r\n' "$boundary"
|
||||
printf 'X-Mailer: html_mail_send.sh/%s\r\n' "$VERSION"
|
||||
printf '\r\n'
|
||||
printf -- '--%s\r\n' "$boundary"
|
||||
printf 'Content-Type: text/plain; charset="UTF-8"\r\n'
|
||||
printf 'Content-Transfer-Encoding: 7bit\r\n'
|
||||
printf '\r\n'
|
||||
printf 'This email requires an HTML-capable email client.\r\n'
|
||||
printf '\r\n'
|
||||
printf -- '--%s\r\n' "$boundary"
|
||||
printf 'Content-Type: text/html; charset="UTF-8"\r\n'
|
||||
printf 'Content-Transfer-Encoding: base64\r\n'
|
||||
printf '\r\n'
|
||||
# Base64 encode with 76-char lines and convert LF to CRLF
|
||||
base64 -w 76 "$HTML_FILE" | sed 's/$/\r/'
|
||||
printf '\r\n'
|
||||
printf -- '--%s--\r\n' "$boundary"
|
||||
} > "$tmp_email"
|
||||
|
||||
print_success "MIME message created"
|
||||
|
||||
# Show summary
|
||||
print_section "Email Summary"
|
||||
print_value "From" "$from_header"
|
||||
print_value "To" "$TO_EMAIL"
|
||||
print_value "Subject" "$SUBJECT"
|
||||
print_value "SMTP Server" "${SMTP_SERVER}:${SMTP_PORT}"
|
||||
print_value "TLS/SSL" "$([[ "$SMTP_TLS" == "yes" ]] && echo "Enabled" || echo "Disabled")"
|
||||
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
echo ""
|
||||
print_warning "DRY RUN - Email would be sent with the above settings"
|
||||
print_info "Email content saved to: $tmp_email"
|
||||
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
print_section "Email Content Preview"
|
||||
echo -e "${DIM}"
|
||||
head -50 "$tmp_email"
|
||||
echo -e "${RST}"
|
||||
echo -e "${DIM}[... truncated ...]${RST}"
|
||||
fi
|
||||
|
||||
# Don't delete temp file in dry run
|
||||
trap - EXIT
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_section "Sending Email"
|
||||
|
||||
# Build curl command
|
||||
local curl_opts=()
|
||||
curl_opts+=(--url "smtp://${SMTP_SERVER}:${SMTP_PORT}")
|
||||
curl_opts+=(--user "${SMTP_USER}:${SMTP_PASS}")
|
||||
curl_opts+=(--mail-from "$FROM_EMAIL")
|
||||
curl_opts+=(--mail-rcpt "$TO_EMAIL")
|
||||
curl_opts+=(--upload-file "$tmp_email")
|
||||
|
||||
if [[ "$SMTP_TLS" == "yes" ]]; then
|
||||
curl_opts+=(--ssl-reqd)
|
||||
elif [[ "$SMTP_TLS" == "ssl" ]]; then
|
||||
curl_opts=(--url "smtps://${SMTP_SERVER}:${SMTP_PORT}" "${curl_opts[@]:1}")
|
||||
fi
|
||||
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
curl_opts+=(--verbose)
|
||||
else
|
||||
curl_opts+=(--silent --show-error)
|
||||
fi
|
||||
|
||||
# Send the email
|
||||
echo -ne " ${ACC2}⠋${RST} ${WHT}Connecting to SMTP server...${RST}"
|
||||
|
||||
local start_time
|
||||
start_time=$(date +%s)
|
||||
|
||||
if curl "${curl_opts[@]}" 2>&1; then
|
||||
local end_time
|
||||
end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
printf "\r%*s\r" 50 ""
|
||||
echo ""
|
||||
echo -e " ${BGGRN}${BLK} ${SYM_CHECK} SUCCESS ${RST}"
|
||||
echo ""
|
||||
print_success "Email sent successfully!"
|
||||
print_info "Delivery time: ${duration}s"
|
||||
echo ""
|
||||
|
||||
# Fun success animation
|
||||
echo -e " ${G1}${SYM_SEND}${RST} ${SYM_ARROW} ${G3}${SYM_ARROW}${RST} ${G5}${SYM_ARROW}${RST} ${ACC1}${SYM_MAIL}${RST} ${DIM}→ ${TO_EMAIL}${RST}"
|
||||
echo ""
|
||||
else
|
||||
printf "\r%*s\r" 50 ""
|
||||
echo ""
|
||||
echo -e " ${BGRED}${WHT} ${SYM_CROSS} FAILED ${RST}"
|
||||
echo ""
|
||||
print_error "Failed to send email"
|
||||
print_info "Try running with --verbose for more details"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# ARGUMENT PARSING
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-s|--server)
|
||||
SMTP_SERVER="$2"
|
||||
shift 2
|
||||
;;
|
||||
-P|--port)
|
||||
SMTP_PORT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-u|--user)
|
||||
SMTP_USER="$2"
|
||||
shift 2
|
||||
;;
|
||||
-p|--pass)
|
||||
SMTP_PASS="$2"
|
||||
shift 2
|
||||
;;
|
||||
-f|--from)
|
||||
FROM_EMAIL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-n|--name)
|
||||
FROM_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-t|--to)
|
||||
TO_EMAIL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-j|--subject)
|
||||
SUBJECT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--html)
|
||||
HTML_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-tls)
|
||||
SMTP_TLS="no"
|
||||
shift
|
||||
;;
|
||||
--ssl)
|
||||
SMTP_TLS="ssl"
|
||||
SMTP_PORT="${SMTP_PORT:-465}"
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE=true
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
--version)
|
||||
show_version
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
print_error "Unknown option: $1"
|
||||
echo -e " Run ${CYN}$SCRIPT_NAME --help${RST} for usage"
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
print_error "Unexpected argument: $1"
|
||||
echo -e " Run ${CYN}$SCRIPT_NAME --help${RST} for usage"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# INTERACTIVE MODE
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
prompt_input() {
|
||||
local prompt="$1"
|
||||
local var_name="$2"
|
||||
local default="${3:-}"
|
||||
local is_password="${4:-false}"
|
||||
|
||||
local current_value="${!var_name}"
|
||||
|
||||
if [[ -n "$default" ]]; then
|
||||
printf " ${ACC1}${SYM_ARROW}${RST} ${WHT}%s${RST} ${DIM}[%s]${RST}: " "$prompt" "$default"
|
||||
else
|
||||
printf " ${ACC1}${SYM_ARROW}${RST} ${WHT}%s${RST}: " "$prompt"
|
||||
fi
|
||||
|
||||
local input
|
||||
if [[ "$is_password" == "true" ]]; then
|
||||
read -rs input
|
||||
echo ""
|
||||
else
|
||||
read -r input
|
||||
fi
|
||||
|
||||
if [[ -z "$input" && -n "$default" ]]; then
|
||||
eval "$var_name='$default'"
|
||||
elif [[ -n "$input" ]]; then
|
||||
eval "$var_name='$input'"
|
||||
fi
|
||||
}
|
||||
|
||||
interactive_mode() {
|
||||
print_header
|
||||
|
||||
print_section "SMTP Configuration"
|
||||
prompt_input "SMTP Server" SMTP_SERVER
|
||||
prompt_input "SMTP Port" SMTP_PORT "587"
|
||||
prompt_input "SMTP Username" SMTP_USER
|
||||
|
||||
if [[ -z "$SMTP_PASS" && -z "${SMTP_PASSWORD:-}" ]]; then
|
||||
prompt_input "SMTP Password" SMTP_PASS "" true
|
||||
else
|
||||
print_info "Using password from environment or argument"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e " ${DIM}TLS/SSL Options:${RST}"
|
||||
echo -e " ${CYN}1${RST}) STARTTLS (port 587) ${DIM}- recommended${RST}"
|
||||
echo -e " ${CYN}2${RST}) SSL/TLS (port 465)"
|
||||
echo -e " ${CYN}3${RST}) None (insecure)"
|
||||
printf " ${ACC1}${SYM_ARROW}${RST} ${WHT}Select encryption${RST} ${DIM}[1]${RST}: "
|
||||
read -r tls_choice
|
||||
|
||||
case "${tls_choice:-1}" in
|
||||
2)
|
||||
SMTP_TLS="ssl"
|
||||
SMTP_PORT="465"
|
||||
;;
|
||||
3)
|
||||
SMTP_TLS="no"
|
||||
;;
|
||||
*)
|
||||
SMTP_TLS="yes"
|
||||
;;
|
||||
esac
|
||||
|
||||
print_section "Email Details"
|
||||
prompt_input "From Email" FROM_EMAIL
|
||||
prompt_input "From Name (optional)" FROM_NAME
|
||||
prompt_input "To Email" TO_EMAIL
|
||||
prompt_input "Subject" SUBJECT
|
||||
prompt_input "HTML File Path" HTML_FILE
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# MAIN
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
main() {
|
||||
# Parse command line arguments
|
||||
parse_args "$@"
|
||||
|
||||
# If no arguments provided, run interactive mode
|
||||
if [[ -z "$SMTP_SERVER" && -z "$HTML_FILE" ]]; then
|
||||
interactive_mode
|
||||
else
|
||||
print_header
|
||||
fi
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies
|
||||
|
||||
# Validate all inputs
|
||||
validate_inputs
|
||||
|
||||
# Send the email
|
||||
send_email
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user