Skip to Content

Configuring Doctrine for Email Queue Management in Mautic with Cron Jobs

Estimated Reading Time: 3 Minutes

 

Configuring Doctrine for Email Queue Management in Mautic with Cron Jobs

Overview

This guide provides a detailed process to configure Mautic to use Doctrine for managing email queues, implementing cron jobs to automate the process, and ensuring efficient and stable email delivery.

Step 1: Setting Up Doctrine for Email Queues

Option 1: Configuring via local.php File

  1. Locate the local.php File
    • The local.php file is typically found in the app/config directory of your Mautic installation.
  2. Edit the Configuration File
    • Add or modify the following settings in the local.php file:
    <?php
    
    return array(
    // Other Mautic configuration settings...
    
    'messenger' => [
        'default_bus' => 'messenger.bus.default',
        'transports' => [
            'doctrine' => [
                'dsn' => 'doctrine://default?table_name=messenger_messages',
            ],
        ],
    ],
    
    // Additional configuration settings...
    );
            
  3. Save the File
    • Save the changes. These settings will be applied during the next queue processing.

Option 2: Configuring via Mautic's Queue Configuration Screen

  1. Access the Queue Configuration Screen
    • Log in to your Mautic dashboard.
    • Navigate to Settings > Queue Settings.
  2. Configure the Queue Settings
    • Queue Transport: Doctrine
    • Scheme: doctrine
    • Host: default
    • Table Name: messenger_messages
  3. Save the Configuration
    • Click Save & Close to apply the changes.

Step 2: Implementing Cron Jobs for Automated Email Sending

Creating the Shell Script

  1. Create the Script
    • Save the following script as /path/to/mautic/var/lock/consume_mautic.sh:
    #!/bin/bash
    
    # Path to the lock file
    LOCKFILE="/path/to/mautic/var/lock/consume_mautic.lock"
    LOGFILE="/path/to/mautic/var/logs/mautic_consume_detailed.log"
    
    # Define the lock file timeout (9 minutes = 540 seconds)
    LOCKFILE_TIMEOUT=540
    
    # Function to log messages
    log() {
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOGFILE"
    }
    
    log "Script started."
    
    # Check if the lock file exists
    if [ -e $LOCKFILE ]; then
        LOCKFILE_AGE=$(($(date +%s) - $(stat -c %Y $LOCKFILE)))
        if [ $LOCKFILE_AGE -ge $LOCKFILE_TIMEOUT ]; then
            log "Lock file is older than $LOCKFILE_TIMEOUT seconds. Removing stale lock file."
            rm -f $LOCKFILE
        else
            log "Process is already running. Exiting."
            exit 1
        fi
    fi
    
    # Create the lock file
    touch $LOCKFILE
    log "Lock file created."
    
    # Run the messenger:consume command for emails with increased verbosity and log the output
    log "Starting to consume messages..."
    /usr/bin/php /path/to/mautic/bin/console messenger:consume email --limit=60 --time-limit=480 --memory-limit=128M -vvv >> "$LOGFILE" 2>&1
    
    log "Finished consuming messages."
    
    # Remove the lock file when done
    rm -f $LOCKFILE
    log "Lock file removed."
    
    log "Script finished."
            
  2. Make the Script Executable
    • Grant execute permissions to the script:
    chmod +x /path/to/mautic/var/lock/consume_mautic.sh
            

Configuring the Cron Job

  1. Open the Crontab
    • Edit your crontab with the following command:
    crontab -e
            
  2. Add the Cron Job
    • Add this line to your crontab:
    */10 * * * * /path/to/mautic/var/lock/consume_mautic.sh >> /path/to/mautic/var/logs/mautic_consume.log 2>&1
            

    This schedules the script to run every 10 minutes, logging output to mautic_consume.log.

Setting Up Directories and Permissions

  1. Create Necessary Directories
    • Ensure the required directories exist:
    mkdir -p /path/to/mautic/var/lock
    mkdir -p /path/to/mautic/var/logs
            
  2. Check Permissions
    • Verify that the user running the cron job has appropriate permissions for these directories.

Testing the Setup

  1. Run the Script Manually
    • Test the script by running it manually:
    /path/to/mautic/var/lock/consume_mautic.sh
            
  2. Check the Logs
    • Monitor the log file to ensure the script is processing emails correctly:
    tail -f /path/to/mautic/var/logs/mautic_consume.log
            

Step 3: Monitoring and Troubleshooting

Disk Space and Table Management

  • Warning: The messenger_messages table can fill up quickly, especially under heavy load. Regularly monitor disk space and consider implementing automated cleanup routines to prevent crashes.
  • Alternative Queues: If Doctrine struggles with high volumes, consider switching to a more scalable queue system like Redis or RabbitMQ.

Additional Logging

  • Verbose Logs: The -vvv flag in the script provides detailed logs that can help diagnose issues.

Common Issues

  • Lock File Persistence: Ensure the script removes the lock file after processing to avoid blocking future executions.
  • Message Backlog: If the messenger_messages table fills up, consider adjusting cron timings or migrating to a different transport.
Configuring Doctrine for Email Queue Management in Mautic with Cron Jobs
  • Nice script - thank you! Just to be clear, there will be two log files outputted ? consume and consume_derailed. Also could you explain how we could use this to set the frequency of mail sends. In Mautic 4 you used to be able to play with this by the number of sends per batch and setting the cron mautic:emails:send frequency

    • Hello, Mautic 4 created a series of files in a tmp folder, each file was a message in the queue. Now, since Mautic 5 (and because Symphony now works like that), emails are queued in a table in the database and are sent from there. So now, you have to work this in 2 steps 1) Send the emails to the database, 1 per line 2) Create a worker (like a daemon) to send the messages from the DB There are many ways to set up the worker, one of those is the simplest (the one I am using here) but also limited to rather small databases (200k o so leads). It can be far easier than how I set it up here, but the issue is that the workers can be persistent if they are not stopped, so you can easily add a timeout or a stop condition in a simple command, but is really frequent that something wrong happens and the worker stays on because the condition is not met or there is an error and then each time you run the process, a new worker is added until all server resources are filled and crashes or become unusable. This configuration I am using has all the possible guardrails to prevent that the worker stays up. My opinion about this new way to send message (not files but DB): There are loads of advantages on that approach and it's easier to control

  • COMMENT