In order to track email open rates, I'm firing a pixel in a mass email I'm sending from my server. The script is working in Mac Mail. The email is received and the pixel is downloaded.
However, it's not working in the Yahoo mail client. The email is received, the referenced images are downloaded and shown, however the pixel does not fire/download, nor does the php script run (to my knowledge). Does anyone know why this would happen with Yahoo mail client and potentially other clients that I have yet to test?
Here is the html img tag:
<img src="http://mysite.com/email_track.php?email=email_value&country=country_value&state=state_value" />
Here is the php script:
<?php
// Database code omitted
$result= mysql_query("INSERT INTO `CelebrationOpens` SET `time` = NOW(), `country` = '$country', `state` = '$state', `email` = '$email' ") or die(mysql_error());
// Create an image, 1x1 pixel in size
$im=imagecreate(1,1);
// Set the background colour
$white=imagecolorallocate($im,255,255,255);
// Allocate the background colour
imagesetpixel($im,1,1,$white);
// Set the image type
header("content-type:image/jpg");
// Create a JPEG file from the image
imagejpeg($im);
// Free memory associated with the image
imagedestroy($im);
?>
I've also tried to fire the pixel like this:
$name = './concert/pixel.png';
$fp = fopen($name, 'rb');
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
fpassthru($fp);
exit;
You mentioned you are using all embedded images, which is why they always show, independently of whether you opt to download images for your email. Embedding images is the workaround for image blocking, but results in a large filesize for the email.
All non-embedded images need to be shown to work. Your tracking pixel is one. Apple clients download all images by default, while other clients do not. The tracking image is not firing because you haven't downloaded images on your email in Yahoo (or any other client).
Unfortunately this is a limitation to open tracking and why the data is incomplete and always skewed towards Apple clients. Open tracking really means 'They opened it and unblocked the images OR They opened on Apple'.
I was able to find the culprit, and it was related to caching the pixel link. I appended a random string to the img src and it works in both ymail and gmail now.
The image tag now looks something like this:
<img src="http://mysite.com/email_track.php?email=email_value&country=country_value&state=state_value&random_value=<?php echo rand() ?>" />
Thanks for the help in guiding me towards this discovery.
Related
I want to make a program similar to the chrome extension mailtrack.
It can track when a user opens an email, and I want to do the same.
I have made an image on my webserver so that it will open and write to a file whenever it is requested. (e.g a tracking pixel).
This doesn't work, because google proxies, and caches the image; rewriting the url to https://foo.googleusercontent.com/proxy/foobarfoobarfoobar#myoriginalurl.
This causes the request not to be made to my server, but googles.
How can I fix this?
And if it is impossible, ok, but then how would the aforementioned mailtrack work?
My code is:
<?php
$file = 'image.png';
$fp = fopen('log.log', 'a');
fwrite($fp, 'Opened' . PHP_EOL);
header('Content-Type: image/png');
readfile($file);
?>
When you send an email, Mailtrack automatically adds a tracking pixel (a really small image) to that email. Then, when it is opened the tracking pixel is downloaded and sends a call to our servers to let us know the mail has been opened.
Also,
Mailtrack is an email tracking tool. It tells you if your emails have been opened or not, and how many times, through its pixel-based tracking system.
I have fixed it. I use python to do it now.
My server code for others wondering is:
import flask
import random
app = flask.Flask(__name__)
#app.route('/sig.png')
def sig():
print(f'Requested {random.randint(1,9999)}')
return flask.send_file('images/sig.png', 'image/png')
app.run('0.0.0.0', 8080)
I've implemented a very common approach to email open rate tracking using a 1x1px transparent image:
<img src="https://myserver/trackresponse?source=1&action=1"
style="border:0;width:1px;height:1px;" alt="" />
And the php code to track response and return the image looks like this:
header('Content-Type: image/png');
(Record response on DB)....
$im=imagecreatefrompng("/images/pixel.png");
imagepng($im);
imagedestroy($im);
On viewing the email the request for the image is executed (I know this as the the response is recorded on the DB).
Although Gmail (webmail and iphone app) and even Outlook.live.com displays the email correctly (as in you can't see the tracking pixel), the Windows mail app (Windows 10) displays this:
Any ideas?
I am trying to implement a custom Tracking Pixel for Emails sent out from wordpress.
Thanks to these post:
Tracking email with PHP and image
Tracking email opens with a real image
and especially
http://www.phpdevtips.com/2013/06/email-open-tracking-with-php-and-mysql/
I was able to implement the core idea.
The email loads the tracking pixel via
<img src="https://www.example.com/tracking.php?order_id=1" width="100" height="100" />
and in the tracking.php
$graphic_http = 'https://www.example.com/GIF-example.gif';
header('Content-Type: image/gif');
readfile( $graphic_http );
Opening the tracking.php file in a browser opens up the gif image for download.
However the Tracking pixel/Tracking image doesn't show up in the Gmail Email. There is only a broken image logo and when I click to show the image this link is opened
https://ci5.googleusercontent.com/proxy/l2xUKFGnNFKm64zEYmJhOcUmEJm15w9MC1txRRF01tpKlcL3t3O16aMJgbYQkucBySV0xV2T0EsCwikOAC0Z4em6uPzSs38lkHrYBvosRRAk14EfPoEXqC5JdLxRm8ToZmGSQqt_RwHCaBE_3uLgQDVEB05Rdtkq-Xzuw30=s0-d-e1-ft#https://www.example.com/tracking.php?order_id=1
which states a Google 404:
Google 404. That’s an error.
The requested URL /proxy/l2xUKFGnNFKm64zEYmJhOcUmEJm15w9MC1txRRF01tpKlcL3t3O16aMJgbYQkucBySV0xV2T0EsCwikOAC0Z4em6uPzSs38lkHrYBvosRRAk14EfPoEXqC5JdLxRm8ToZmGSQqt_RwHCaBE_3uLgQDVEB05Rdtkq-Xzuw30=s0-d-e1-ft was not found on this server. That’s all we know.
It seems to be a problem that Google's proxy cannot read the php script. Both the tracking.php and the GIF-example.gif files have 775 rights and are accesible publicly.
On Hotmail this does work so it really seems to be a problem with the Google Proxies.
Does anybody know how to let the Google Proxies access this Tracking pixel?
I figured out the answer: The problem was with the Google Proxies and the question mark ? in https://www.example.com/tracking.php?order_id=1
The Google Proxies address got messed up because it already had a question mark and resulted in a 404.
I resolved it using https://www.example.com/tracking.php/order_id=1 instead and then on the tracking.php I didn't use $_GET but $_SERVER['REQUEST_URI'] and parsed the /order_id= String.
The tracking pixel shows up in Gmail and it gets tracked in the tracking.php script.
All your headers are trying to force the browser to download the file and ignore it's file type (since you never say what file type it is). For images to be displayed in the browser, you need to set the correct header.
This is basically all you need to do:
$orderId = isset($_GET['order_id']) ? $_GET['order_id'] : null;
if ($orderId) {
// Save stuff in your DB or how you want to log it.
}
header('Content-Type: image/gif');
echo file_get_contents('/absolute/path/to/image.gif');
exit; // Not really necessary, but just to make sure there's no more output.
I have a question. I would like to add rotating links inside my email signature to
track results on my site. I can make these dynamic tracking urls on google as you may know
but I would like to rotate them inside my email signature to see which text draws the most
conversions or returning visitors.
Is this possible?
I found this for instance:
$mybanners[1] = '<img src="banner1.jpg">';
$mybanners[2] = '<img src="banner1.jpg">';
$id = rand(1,2);
echo $mybanners[$id];
But when I look into my windows live mail I can only upload html files.
Does someone know how to do this?
You can't provide PHP scripts in a mail, since it is a server-side language and it will be opened by a mail client. Even Javascript is very often blocked for security reason.
What you can do is make a "fake" image which will be in fact generate by a PHP script. YOu can find inspiration by looking to script made for forum avatar rotation. The idea is to generate an image, which will be displayed to the client but, in the same time, save some data about the user who requests the image if you want:
<?php
// Save whatever you want about the user
file_put_content("log/user.txt", $_SERVER['HTTP_REFERER']);
// Render a valid PNG image
header('Content-Type: image/png');
readfile("/path/to/banner.png");
?>
This script should be used as a standard image (with, if you want, a nice URL rewrite to make a .png link):
<img src="http://www.example.com/my_super_banner.php" />
where my_super_banner.php is the script described before.
I've installed the GD Library on my Apache just now, and it seems that my script below doesn't work.
I'm trying to add a layer "play.png" to a youtube video thumbnail (http://img.youtube.com/vi/VIDEOID/default.jpg)
I've tried it with many different videoID's but the image doesn't load. There is a message that the graphic couldn't be opened because it contains errors.
I'm opening the file with postimage.php?v=7yV_JtFnIwo
http://img.youtube.com/vi/7yV_JtFnIwo/default.jpg opens correctly too...
Does anyone know where the issue could be?
Thanks in advance!
<?php
// The header line informs the server of what to send the output
// as. In this case, the server will see the output as a .png
// image and send it as such
header ("Content-type: image/png");
// Defining the background image. Optionally, a .jpg image could
// could be used using imagecreatefromjpeg, but I personally
// prefer working with png
$background = imagecreatefromjpeg("http://img.youtube.com/vi/".$_GET['v']."/default.jpg");
// Defining the overlay image to be added or combined.
$insert = imagecreatefrompng("play.png");
// Select the first pixel of the overlay image (at 0,0) and use
// it's color to define the transparent color
imagecolortransparent($insert,imagecolorat($insert,0,0));
// Get overlay image width and hight for later use
$insert_x = imagesx($insert);
$insert_y = imagesy($insert);
// Combine the images into a single output image. Some people
// prefer to use the imagecopy() function, but more often than
// not, it sometimes does not work. (could be a bug)
imagecopymerge($background,$insert,0,0,0,0,$insert_x,$insert_y,100);
// Output the results as a png image, to be sent to viewer's
// browser. The results can be displayed within an HTML document
// as an image tag or background image for the document, tables,
// or anywhere an image URL may be acceptable.
imagepng($background,"",100);
?>
Do not close (avoid whitespaces or newslines) your script with ?> and use NULL instead "".
imagepng($background, NULL);
Then, in imagepng the quality parameter is between 0 and 9, as in http://it.php.net/manual/en/function.imagepng.php.