Use with caution and adopt to your needs. Its still work in progress!
#!/bin/bash
# Variables for the script
phpinterpreter="php -d memory_limit=1G"
pathtoconsole="../code/bin/console"
lockfile="/tmp/cronjob.lock"
# Email sending settings
emails_per_batch=14 # Number of emails per batch and rate limit (14 emails/sec)
# Limits for other Mautic commands
segments_update_limit=900
campaigns_rebuild_limit=300
broadcasts_send_limit=800
import_limit=500
# Loop control
max_loops=60
current_loop=0
milliseconds_per_second=1000
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Locking mechanism
if [ -f "$lockfile" ]; then
# Colored output in the console
echo "${RED}Script is already running.${NC}"
# No color codes in the log file
echo "Script is already running." >> "$log_file"
exit 1
fi
touch "$lockfile"
trap 'rm -f "$lockfile"; exit' INT TERM EXIT
# Log file for the current run
log_file="$log_dir/$(date +'%Y%m%d_%H%M%S').log"
# Function to execute Mautic commands
execute_command() {
local command="$1"
# Colored output in the console (stdout)
echo "${BLUE}Executing: $command${NC}"
# Output without colors in the log file
echo "Executing: $command" >> "$log_file"
# Execute command and capture both stdout and stderr
output=$($phpinterpreter $pathtoconsole $command 2>&1)
# Colored output in the console (stdout and stderr)
if [ $? -eq 0 ]; then
echo "${GREEN}$output${NC}"
else
echo "${RED}$output${NC}" >&2
fi
# Output without colors in the log file
echo "$output" >> "$log_file"
return $? # Return command exit status
}
# Calculate dynamic sleep time in microseconds
calculate_sleep_time() {
local duration=$1 # Duration in milliseconds
local target_duration=$((milliseconds_per_second)) # Target duration in milliseconds for 14 emails per second
local sleep_time=$(( (target_duration - duration) * 1000 )) # Convert to microseconds
echo "$sleep_time"
}
# Execute other commands before the email sending loop
execute_command "mautic:segments:update --batch-limit=$segments_update_limit"
execute_command "mautic:campaigns:rebuild --batch-limit=$campaigns_rebuild_limit"
execute_command "mautic:campaigns:trigger"
execute_command "mautic:broadcasts:send --batch=$broadcasts_send_limit"
# Loop for sending emails
while [ $current_loop -lt $max_loops ]
do
# Increment the loop counter
current_loop=$((current_loop+1))
# Capture start time in milliseconds
start_time=$(date +%s%3N)
# Execute the command to send emails
output=$(execute_command "messenger:consume email --limit=$emails_per_batch --time-limit=1")
# Capture end time in milliseconds
end_time=$(date +%s%3N)
# Calculate the duration of the command in milliseconds
duration=$((end_time - start_time))
# Calculate the sleep time to maintain the rate limit
sleep_time=$(calculate_sleep_time $duration)
# Ensure the command was successful
if [ $? -ne 0 ]; then
echo "${RED}Error during email sending. Exiting loop.${NC}" >&2
echo "Error during email sending. Exiting loop." >> "$log_file"
break
fi
# If the number of sent emails is less than the batch limit, exit the loop
sent_emails=$(echo "$output" | grep -oP '\b\d+(?= emails sent)' || echo 0)
if [ "$sent_emails" -lt "$emails_per_batch" ]; then
echo "${RED}Less than $emails_per_batch emails sent. Exiting loop.${NC}"
echo "Less than $emails_per_batch emails sent. Exiting loop." >> "$log_file"
break
fi
# Pause for the calculated sleep time
if [ "$sleep_time" -gt 0 ]; then
usleep "$sleep_time"
fi
done
# Execute additional Mautic commands
execute_command "mautic:unusedip:delete"
execute_command "mautic:import --limit=$import_limit"
execute_command "mautic:webhooks:process"
execute_command "mautic:reports:scheduler"
# Remove the lock file at the end
rm -f "$lockfile"