14

I am sending email newsletters using php mail() function.

I have to track the newsletter emails status.

The status would be
1. Num.Of Sent.
2. Num.Of Delivered.
3. Delivered date.
4. Total Num.Of Read.
5. Unique Num.Of Read.
6. Read date.
7. Num.Of Bounced.
8. Total Num.Of users clicked the links in the email.
9. Unique Num.Of users clicked the links in the email.

From the above status i could track the following:
1. Is Sent. // This is tracked as it is sent from coding.
8. Total Num.Of clicked the links in the email. // This is tracked by adding additional parameters in url.
9. Unique Num.Of clicked the links in the email. // This is tracked by adding additional parameters in url.

How to track the other status of the emails sent from mail() function?
I have to send and track emails from same server.

6
  • 2
    The easy answer, MailChimp or similar.
    – Marcel
    Commented Jun 15, 2011 at 7:24
  • yes we need to do something like that in our website, currently we are also using silverpop.com.
    – Jagadeesan
    Commented Jun 15, 2011 at 7:25
  • +1 for MailChimp. They provide analytics for your emails and are wonderful for newsletters. Transactional mail is a different story, and might be better off with another provider.
    – JonLim
    Commented Jun 16, 2011 at 18:20
  • I have created a script called Newsletter Mailer. codecanyon.net/item/newsletter-mailer-v12/149365
    – ynh
    Commented Jun 16, 2011 at 20:08
  • 3
    Don't do it! Email tracking statistics are a SCAM. These mail services are being dishonest. The MAJORITY of email clients and webmail block all forms of tracking beacons by default. That means that right from the start you're getting only a misleading subset of the true statistics which makes them largely pointless. Ironically the MORE tracking you attempt the LESS mail will actually be read - since most tracking methods trigger spam heuristics. Be honest with your clients and they'll understand - mine do. Let them track the success of a campaign by the increase in sales or site visitors.
    – SpliFF
    Commented Jun 30, 2011 at 2:45

7 Answers 7

16

You can't directly track the other status from the mail() function. Technically Is Sent only tells you that the mail was passed over to the server's outbound mail queue successfully - you can't actually tell if it left your server.

1,. You will need to check your mail server logs to see exactly when the email left the server.

2,3. Num of delivered and delivered date - again you would need to check your mail server logs to see when the mail was handed over (successfully) to a third party mail server. However it would depend on your definition of delivered (into the end-users mailbox? Into their email client?) as to how reliable these stats would be.

4,5,6. Total number read, unique number read, read date. You can't accurately track this. However if you sent HTML email you could embed an image into the email whereby the source of the image was your webserver. If each image URL had a unique identifier for the person you sent the email to then you could track this from your server logs (or via php if the url was a php script that returned an image). However this relies on the end user allowing the loading of images from external webservers (Outlook and gmail for example have this turned off by default).

7,. If you sent the from address to be a script on your server it could parse the bounce message and determine how many bounced. Alternatively you can just have the from address be a mailbox that you go into and check manually.

8, 9. Each link in the email would need to be a link to a url on your webserver. That URL could be a script that would track who clicked (by the use of a query variable) and what they want to see (another query variable) and then redirect them (header function in php) to where you want them to end up.

4
  • 1
    yes, i could understand but some websites doing real time tracking with the above mentioned status and its count by date. is this possible with any other web developing language?
    – Jagadeesan
    Commented Jun 15, 2011 at 6:14
  • 1
    There are a number of solutions to this problem. You could implement your own mail server for sending email within php. Alternatively you could use an off the shelf library for this, again in php. It won't let you track everything (e.g. bounces may not be processed in real time).
    – dunos
    Commented Jun 15, 2011 at 6:26
  • 3
    Another method may be to parse the mail server logs (again using php) to track what it is doing in real time. Your mail server may even have an API with which you can talk to to determine the status of mails in its queue. Either way you need to read about integrating with your mail server.
    – dunos
    Commented Jun 15, 2011 at 6:28
  • 1
    Regarding point 7: "the from address to be a script on your server" is misleading - you cannot specify a script as the from address but rather have to use a mailbox your programm reads.
    – Steffen
    Commented Jun 27, 2011 at 14:23
10
+50

To get all these stats, you will have to use different systems:

Checking for number sent

The return code of the mail function is not reliable, it only tells you that the system will start to try to send the mail. You would have to use a specialised PHP class that communicates via SMTP itself or parse the systems mail logs. But remember this number is near meaningless, which leads to the next point...

Checking for number delivered

Even if you would start to parse the mail logs or use a specialised PHP class to send via SMTP yourself, you could only check the first server in the chain you pass the email to. For example, in a big company the mail might be passed to a central mail server, which you can check. Then it is sent to another internal mail server of the company, which refuses the mail. You'll never know. Not even speaking of spam filters. So, there is no way to tell whether a mail was delivered - until the next point...

Checking number of reads

More formally, you'd have to say "checking number of emails opened". For that, you add an image with an unique URL to your HTML mail, for example http://mywebsite.com/images/IDOFRECIPIENT/IDOFMAILING/logo.jpg - when the URL is requested, you know the corresponding recipient opened the mailing. Downside: if the recipient blocks loading of external contents, there is nothing you can do about it, you'll never know about his reading.

Number of clicks on links

That one is simple: replace all the links in the mail with links on your own domain. When these links are visited, a counter is raised and the visitor is forwarded to the real site. Beware: if the link text in your HTML email contains the name of a domain, but you link to another domain, most email clients will believe it is spam. So for example,

www.citibank.com
is bad.

Bounces

Thats a hard one. Specifiy a "Sender" Header in your email. This is the address the email is bounced to. You can use another address than the "From" Header, which means that when a recipient hits the "Reply" button, he can send an email to [email protected], but if it bounces, the email goes to [email protected].

The trick is to create the bouncing addresses as a catch-all for the whole domain - so every email sent to "[email protected]" should go to the same inbox. Inside the email adress, you save the id of the recipient and of the mailing: bounces-[recipientid]-[mailingid]@newsletter.yourdomain.com. The recipient address is the only reliable data when bouncing, everything else might be removed by the mailserver of the recipient.

Then just code a PHP script that fetches the mails via POP3 and checks the sender.

Hope I could help you!

4

For number of sent, you can use a basic wrapper:

class Mailer
{
    /**
     * Events
     *
     * @var array
     */
    protected $_events = array();

    /**
     * Number of successful emails
     *
     * @var int
     */ 
    protected $_numFailures = 0;

    /**
     * Number of failed emails
     *
     * @var int
     */ 
    protected $_numSuccesses = 0;

    /**
     * Send email using PHP mail() function
     * 
     * @param string $to Send to email address
     * @param string $subject Email subject
     * @param string $message Email message
     * @param string $additionalHeaders Optional. Additional headers
     * @param string $additionalParams Optional. Additional params
     * @return Mailer
     */
    public function mail($to, $subject, $message, $additionalHeaders = '', $additionalParams = '')
    {
        $result = mail($to, $subject, $message, $additionalHeaders, $additionalParams);

        if ($result) {
            $this->_numSuccesses++;
        } else {
            $this->_numFailures++;
        }

        if (isset($this->_events['mail'])) {
            foreach ($this->_events['mail'] as $event) {
                $event($result, $to, $subject, $message);
            }
        }

        return $this;
    }

    /**
     * Get total number of emails sent
     *
     * @return int
     */
    public function count()
    {
        return $this->_numSuccesses + $this->_numFailures;
    }

    /**
     * Get number of successes
     *
     * @return int
     */
    public function getSuccessCount()
    {
        return $this->_numSuccesses;
    }

    /**
     * Get number of failures
     *
     * @return int
     */
    public function getFailureCount()
    {
        return $this->_numFailures;
    }

    /**
     * Add event
     * 
     * @param string $subject Event subject
     * @param Closure $event Event to execute when subject called
     * @return Mailer
     */
    public function addEvent($subject, Closure $event)
    {
        if (!is_string($subject)) {
            throw new InvalidArgumentException('$subject must be a string');
        }
        $this->_events[$subject][] = $event;
        return $this;
    }
}

/** Mailer */
$mailer = new Mailer();

$mailer->addEvent('mail', function($result, $to, $subject, $message) {
    // Code to log to database
});

$mailer->mail($to, $subject, $message);

// Execution order:
// 1. Mailer::mail()
// 2. Increase successes or failures, as appropriate
// 3. Execute 'mail' events
// 4. Closure with code to log to database executed
3
  • 3
    Your wrapper just counts that PHP could pass the mail to mail delivery system. It does not count whether it was sent - the mail might get stuck on your server forever.
    – Steffen
    Commented Jun 27, 2011 at 13:12
  • There are certainly varying degrees of mail tracking. Even so, this proof of concept still may help those who do not need higher level tracking. Commented Jun 29, 2011 at 6:17
  • 1
    Of course, did not want to say your code is useless - it just does not count sent emails. But the very nice example for a lambda function as event handler makes up for it ;-)
    – Steffen
    Commented Jun 29, 2011 at 15:30
3

You can easily log any outgoing mail traffic that's going through PHP's mail() function.

This is done by creating a wrapper that will take care of both: logging and sending the emails. This is relativly easy to accomplish and can be controlled via php.ini settings.

I can recommend: How To Log Emails Sent With PHP's mail() Function To Detect Form Spam for more details if you're running linux.

1
  • 2
    +1 for the only real answer here which shows how to solve this issue. Commented Mar 3, 2012 at 12:23
1

As PHP newsletter script in the email marketing,we usually inserted a small picture or sentences in the email to make which invisible. The PHP function will give back the echo from the small pictures to return the tracking status to the your mail server. When you open the newsletter, and allow to appear all pictures in the email, this tracking function will be activated.

For the bounces system, it must refer to the server environment. Only when you configure the code in your VPS or some other server, this could be activated. I believe you should see http://www.phpnewsletter.org

1

You can track emails and get read receipts by adding some additional code to the php script and mail funciton (changes to email message).

Here is a link which helps you to track email read receipts - php script

0

(EDITED)

The basic concept here is that you record the sends on your PHP side. Each message will have some embedded HTML and an image. When the user opens the emails the image will launch a ping to the server sending the fact that the email was opened (read) and the date (this can come from the server) plus other information such as mail client used to open the message (request headers).

On the delivered parameters I am not entirely sure. I know that you can get this from certain types of mail servers (Microsoft Exchange for example), but I don't know if your standard POP3 servers support this.

You can collect a decent amount of data automatically with this method. It will work like a standard web page ad tracker really. For the server-side I would recommend a CMS framework such as Drupal or a PHP framework such as CodeIgniter.

If you go Drupal then most of the heavy lifting will already be done for you. You just have to assemble the puzzle pieces in a way that you like. Personally I would recommend using MailChimp to track your emails. They have a Drupal module for integrating with it as well (http://drupal.org/project/mailchimp).

1
  • 1
    Virtually every email client strips all Javascript from an email before displaying it to the user. Commented Jun 23, 2011 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.