#!/bin/bash # filepath: /mnt/storagessd1tb/ABD Texting Testing/ui_bulk_sender_working.sh # Working bulk SMS sender with correct send button coordinates and variable substitution DEVICE_IP="10.0.0.193:5555" CSV_FILE="contacts_cleaned.csv" SEND_X=1300 SEND_Y=2900 DELAY_SECONDS=3 LOG_FILE="sms_log_$(date +%Y%m%d_%H%M%S).txt" # Colors GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' CYAN='\033[0;36m' NC='\033[0m' echo -e "${GREEN}=== Bulk SMS Sender with Variables ===${NC}" echo "Using send button at: ($SEND_X, $SEND_Y)" echo "" # Initialize log echo "SMS Send Log - $(date)" > "$LOG_FILE" echo "================================" >> "$LOG_FILE" # Function to set/customize message template set_message_template() { echo -e "${CYAN}=== Message Template Setup ===${NC}" echo "You can use variables in your message:" echo " {name} - Person's name from CSV" echo " {phone} - Phone number" echo " {date} - Current date" echo " {time} - Current time" echo " {custom1}, {custom2}, etc - Any additional CSV columns" echo "" echo "Examples:" echo " 'Hi {name}, this is a test message!'" echo " 'Hello {name}, reminder for {date} at {time}'" echo "" echo "Choose message option:" echo "1. Use message from CSV file" echo "2. Use same custom message for everyone" echo "3. Use custom template with variables" read -r choice case "$choice" in 1) MESSAGE_MODE="csv" echo -e "${GREEN}Using messages from CSV file${NC}" ;; 2) echo "Enter your message:" read -r CUSTOM_MESSAGE MESSAGE_MODE="custom" echo -e "${GREEN}Using custom message: $CUSTOM_MESSAGE${NC}" ;; 3) echo "Enter your message template (use {variable} for substitution):" read -r MESSAGE_TEMPLATE MESSAGE_MODE="template" echo -e "${GREEN}Using template: $MESSAGE_TEMPLATE${NC}" ;; *) MESSAGE_MODE="csv" echo "Default: Using CSV messages" ;; esac echo "" } # Function to substitute variables in message substitute_variables() { local template="$1" local phone="$2" local csv_message="$3" local name="$4" shift 4 local custom_fields=("$@") # Start with the template local final_message="$template" # Replace standard variables final_message="${final_message//\{phone\}/$phone}" final_message="${final_message//\{name\}/$name}" final_message="${final_message//\{date\}/$(date +%Y-%m-%d)}" final_message="${final_message//\{time\}/$(date +%H:%M)}" final_message="${final_message//\{message\}/$csv_message}" # Replace custom fields (custom1, custom2, etc) local i=1 for field in "${custom_fields[@]}"; do final_message="${final_message//\{custom$i\}/$field}" ((i++)) done echo "$final_message" } # Send function with correct coordinates send_sms() { local phone="$1" local message="$2" local count="$3" echo -e "${BLUE}[$count] Sending to: $phone${NC}" echo " Message: $message" # Log to file echo "[$(date +%H:%M:%S)] Sending to $phone: $message" >> "$LOG_FILE" # Clear state adb -s "$DEVICE_IP" shell input keyevent KEYCODE_HOME > /dev/null 2>&1 sleep 1 # Open SMS adb -s "$DEVICE_IP" shell "am start \ -a android.intent.action.SENDTO \ -d 'sms:$phone' \ --es sms_body '$message' \ --activity-clear-top" > /dev/null 2>&1 # Wait for load sleep 3 # Tap send button at correct coordinates adb -s "$DEVICE_IP" shell input tap $SEND_X $SEND_Y > /dev/null 2>&1 echo -e "${GREEN} ✓ Sent${NC}" echo " ✓ Sent successfully" >> "$LOG_FILE" # Return home sleep 1 adb -s "$DEVICE_IP" shell input keyevent KEYCODE_HOME > /dev/null 2>&1 } # Check CSV file exists and show contents if [[ ! -f "$CSV_FILE" ]]; then echo -e "${RED}ERROR: CSV file not found: $CSV_FILE${NC}" exit 1 fi echo "CSV Contents Preview:" head -5 "$CSV_FILE" | column -t -s',' echo "..." echo "Total lines in CSV: $(wc -l < "$CSV_FILE")" echo "" # Fix line endings in CSV file dos2unix "$CSV_FILE" 2>/dev/null || sed -i 's/\r$//' "$CSV_FILE" # Detect CSV columns and their positions IFS=',' read -r -a HEADERS < "$CSV_FILE" echo "Detected CSV columns: ${HEADERS[*]}" # Find column positions NAME_COL=-1 PHONE_COL=-1 MESSAGE_COL=-1 for i in "${!HEADERS[@]}"; do header=$(echo "${HEADERS[$i]}" | tr -d '"' | tr -d ' ' | tr '[:upper:]' '[:lower:]') case "$header" in "name"|"firstname"|"contact"|"person") NAME_COL=$i ;; "phone"|"phonenumber"|"number"|"tel"|"telephone"|"mobile"|"cell") PHONE_COL=$i ;; "message"|"msg"|"text"|"content"|"body") MESSAGE_COL=$i ;; esac done echo "Column positions - Name: $NAME_COL, Phone: $PHONE_COL, Message: $MESSAGE_COL" # Validate required columns if [[ $PHONE_COL -eq -1 ]]; then echo -e "${RED}ERROR: No phone column found in CSV. Expected columns: 'phone', 'phonenumber', or 'number'${NC}" exit 1 fi echo "" # Test device connection echo "Checking device connection..." if ! adb devices | grep -q "$DEVICE_IP"; then echo -e "${RED}ERROR: Device not connected${NC}" exit 1 fi echo -e "${GREEN}✓ Device connected${NC}" echo "" # Set up message template set_message_template # Confirm before starting echo -e "${YELLOW}Ready to send messages to all numbers in CSV?${NC}" echo "Press Enter to continue or Ctrl+C to cancel..." read -r echo "" echo -e "${YELLOW}Starting bulk SMS send...${NC}" echo "" # Process CSV count=0 skipped=0 sent=0 # Read CSV into array mapfile -t lines < "$CSV_FILE" echo "Total lines read: ${#lines[@]}" echo "" # Process each line for i in "${!lines[@]}"; do # Skip header if [[ $i -eq 0 ]]; then continue fi line="${lines[$i]}" # Parse CSV line into array IFS=',' read -r -a fields <<< "$line" # Extract fields by column position phone="" csv_message="" name="" # Get phone (required) if [[ $PHONE_COL -ge 0 && $PHONE_COL -lt ${#fields[@]} ]]; then phone="${fields[$PHONE_COL]}" fi # Get message (optional) if [[ $MESSAGE_COL -ge 0 && $MESSAGE_COL -lt ${#fields[@]} ]]; then csv_message="${fields[$MESSAGE_COL]}" fi # Get name (optional) if [[ $NAME_COL -ge 0 && $NAME_COL -lt ${#fields[@]} ]]; then name="${fields[$NAME_COL]}" fi # Get any additional custom fields (skip the main columns we already extracted) custom_fields=() for ((j=0; j<${#fields[@]}; j++)); do if [[ $j -ne $PHONE_COL && $j -ne $MESSAGE_COL && $j -ne $NAME_COL ]]; then custom_fields+=("${fields[$j]}") fi done # Debug output echo "DEBUG: Processing line $i - phone='$phone', csv_message='$csv_message', name='$name'" # Skip empty lines if [[ -z "$phone" ]]; then echo " Skipping empty line" ((skipped++)) continue fi # Clean inputs phone=$(echo "$phone" | tr -d '"' | tr -d ' ' | tr -d '\r' | sed 's/[^0-9+]//g') csv_message=$(echo "$csv_message" | tr -d '"' | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') name=$(echo "$name" | tr -d '"' | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') # Verify phone number if [[ -z "$phone" ]]; then echo " Skipping - phone empty after cleaning" ((skipped++)) continue fi ((count++)) # Determine final message based on mode case "$MESSAGE_MODE" in "csv") final_message="$csv_message" ;; "custom") final_message="$CUSTOM_MESSAGE" ;; "template") final_message=$(substitute_variables "$MESSAGE_TEMPLATE" "$phone" "$csv_message" "$name" "${custom_fields[@]}") ;; *) final_message="$csv_message" ;; esac # Send the SMS send_sms "$phone" "$final_message" "$count" ((sent++)) # Delay between messages if [[ $count -lt $((${#lines[@]} - 1)) ]]; then echo " Waiting ${DELAY_SECONDS} seconds before next message..." sleep $DELAY_SECONDS fi echo "" done # Summary echo -e "${GREEN}=== Summary ===${NC}" echo "Lines processed: $((count + skipped))" echo "Messages sent: $sent" echo "Skipped: $skipped" echo "" # Log summary echo "" >> "$LOG_FILE" echo "================================" >> "$LOG_FILE" echo "Summary:" >> "$LOG_FILE" echo "Total sent: $sent" >> "$LOG_FILE" echo "Completed: $(date)" >> "$LOG_FILE" echo "Log saved to: $LOG_FILE" echo "" # Show what was actually sent echo -e "${YELLOW}Messages sent:${NC}" grep "Sending to" "$LOG_FILE" | grep -v "Summary" echo "" echo -e "${GREEN}✓ Complete! All messages have been sent.${NC}" echo "Check your Messages app to verify all messages appear in sent folder."