get IP address and email id when receiver open the email - php

I am using php mail() function. but i want that when receiver open email, his/her IP address and email id will save in my db table.
my mail function codes are-
<?php
require("phpmailer/class.phpmailer.php");
$mail = new PHPMailer();
// ---------- adjust these lines ---------------------------------------
$mail->Username = "mymail#gmail.com"; // your GMail user name
$mail->Password = "";
$mail->AddAddress("$userid"); // recipients email
$mail->FromName = "Nikhil Garg"; // readable name
$mail->Subject = "Newletter Subscription";
$mail->Body = "$usermsg";
//-----------------------------------------------------------------------
$mail->SMTPSecure = "ssl";
$mail->Host='smtp.gmail.com';
$mail->Port = 465;
$mail->IsSMTP(); // use SMTP
$mail->SMTPKeepAlive = true;
$mail->Mailer = "smtp";
$mail->CharSet = 'utf-8';
$mail->SMTPDebug = 0;
$mail->SMTPAuth = true; // turn on SMTP authentication
$mail->From = $mail->Username;
if(!$mail->Send())
echo "Mailer Error: " . $mail->ErrorInfo;
else
echo "Message has been sent";
}
?>
They are working well. but i don't understand how to get receiver IP address and email Id when they open this email.
Actually i have more then 5000 email list and i want to sort them by city, state, country. with ip address, i can do that. if you know any other way please suggest
my goal is simple and genuine. I just want to know their country so that i will send emails according their country occasions for better selling results. for sending emails to more then 5000 users and ask them for details is not right way.

Make the email HTML formatted
Include a reference to an image on your server in it
Add a unique identifier to the query string for that image
Have your server record the time, query string id, and request source ip for requests to it
Note that:
You must familiarise yourself with the relevant privacy laws that you'll be interacting with by doing this (noting that you'll almost certainly be operating internationally)
This won't work if the user doesn't load the images in the email (and most email clients don't load images by default so that this sort of tracking won't be successful)
Adding this sort of tracking id will weight your email towards SPAM in some spam filters
Some of your customers will be upset/offended by you doing this
You will get the same id from multiple people if someone forwards the email

What you are looking for is called a web beacon, you can use it as far as you give a link back to your privacy policy and in your privacy policy you have to specify about it.
How it works
Basically, a 1x1 image is placed in the email, which is requested from your server where you can get the ip address..
Drawback
Many mail clients do not load images automatically, so it can't give you accurate stats
*code
in your mail place an image:
<img src="http://example.com/file.php" />
In file.php:
//get ip address
//43byte 1x1 transparent pixel gif
echo base64_decode("R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==");

I have done this, and it works! the problem is that gmail loads the info from their own servers, so, every time a user opens the email, the recorded IP comes from Gmail servers, so it shows a Google IP address instead of the recipient IP, so it can be done with link tracking, as the recipient clicks the link and it opens a new tab, so you can capture the correct IP

You can't with normal mail.
You send the message (text) away, and have NO control over what the user does afterwards. Now I have NO idea what a mail id is, but there are several tricks to get the user's IP, tough I agree with above users that it's not really nice.
You can put the mailcontent on your server. If the user is trusting/dumb enough to click, you can open a link (with an id) and get the info from the loaded webpage
You can add images, is the user loads those (not default!) you get some information
etc. But for sending plain mail like this: no chance.

In all honesty, I don't think this is possible at all.
There is a "read receipt" system built into some email clients which can send automatic notification to the sender when an email is opened, but it's optional - the recipient may have disabled it, or may be using email software that doesn't support it.
But in any case, that doesn't include the user's IP address in the notification.
If you send HTML mails, you could include an embedded graphic in the message which would load from your server. But most email clients block external graphics for security reasons (ie precisely to avoid sharing their IP address and other details with an unknown sender).
You can't use Javascript because it also doesn't work in emails for security reasons.
Regardless, whatever you do will be entirely dependent on the capabilities of the recipient's email system and their settings. You have no control over that, and most user's settings will probably block whatever you try to do.
In short, you're not going to get what you want.
Simple answer: Just ask the users for the information you need, rather than trying to steal it from them. Maybe you should have town and country fields as part of the form that your users fill in to sign up to your mailing list.

Agreed with #Daniel that it might not be legal to do so.
However, if I believe that your intentions are harmless, I'd suggest to use a hashed URL for an Image, unique per each e-mail sent. This URL points to a PHP file that matches it in a DB and marks the e-mail instance as delivered and read once the image is loaded.
Of course, the reader must have accepted to load the images from your e-mails. Otherwise, it won't work.

We can host tracking code in our c panel and generate one image link. Whenever image load into the email body it triggers the code and we can collect email id, ip address and time in csv file.

Related

What's the best way to send a newsletter with PHPMailer?

I'm trying to send a newsletter with PHPMailer meanwhile protecting my customers privacy.
At first I set the receiver configuration with mail->addAddress('customerEmail']); but I found out that sending it this way, every receiver could see other customer's subscribers E-mail addresses.
I changed the addAddress to mail->addBCC('customerEmail']); so that it doesn't show every E-Mail address (in fact now it even doesn't show the recipient E-mail address of the customer it's being send to), but this way if anyone wanted to reply to the E-mail, their response would also be sent to the rest of the subscribers...
What is for you the best option to face this problem?
As I was advised, the best way to manage a newsletter is to send the email individually to every customer although it means a slight increase on the sending time. This way you can offer automated unsubscription links and other features that otherwise you couldn't.
In order to achieve that, I just made a simple loop getting the addresses from my db:
$sql = "SELECT `email` FROM `emails`";
$statement = $db->prepare($sql);
$statement->execute();
while ($fila = $statement->fetch()) {
if(!empty($fila['email'])){
$mail->addAddress($fila['email']);
$success = $mail->Send();
$mail->clearAllRecipients(); //Don't forget this!
}
}
The method clearAllRecipients(); is very important as it's the one who will clear the last lap recipient so that the 'to' section of the email doesn't show all your newsletter recipients.
Email servers do not use the message headers to deliver messages. When you send an email your email client maintains a conversation* like this:
EHLO example.com
MAIL FROM: mail#example.com
RCPT TO: info#example.net, customers#example.org, john#example.com
DATA
From: Me <webmaster#example.com>
To: Customers <whatever#example.com>
Subject: Important info
Dear Blah,
Blah blah.
Regards,
.
(*) It is a conversation because it includes server response to each command but I've omitted that part.
What really counts is the information provided in the specific commands before the DATA block. Certainly, most mail tools will create headers to match the addresses in the processing instructions but such headers are for pure informational purposes and they don't need to be identical. In fact that's how Bcc actually works: you instruct your mailer to deliver email to such address but omit it from headers.
So:
You can do it fast (Bcc and a single message for all)
You can do it nice (To and one message per recipient)
If you ask for my opinion, it's always nice to know the exact e-mail address to which a newsletter is being sent—many of us have more than one address. And it's actually mandatory to send customised messages if you want to offer automated unsubscription links.

phpmailer - How to verify a sent email arrived at its destination

phpmailer is working fine and able to use it in various ways, but.... I'm trying to find a way to determine if a valid looking email address actually made it to some destination. I am NOT talking about validating addresses such as...
if (!$mail->validateAddress($email)) {echo 'Not a valid squiloople email pattern';}
This is my setup is using SMTP through gmail...
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->SMTPDebug = 0;
$mail->isHTML(true);
$mail->Host = 'smtp.gmail.com';
$mail->Username = "XXXl#gmail.com";
$mail->Password = "XXX";
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
If the email address looks like a duck and quacks like a duck then...
$result = $mail->send(); Will Always return true!
var_dump($mail->send()); // Also returns Boolean
Is there a way to test if the email was actually received somewhere? Or is this strictly a one-way shout-out through google's SMTP gmail servers???
Any tips, tricks, or pointers would be appreciated.
$mail->send() will not always return true. It returns true if the part of the sending process it was involved with works. So if you send to an unknown address, but do so via gmail, gmail's servers don't know whether the address exists or not at the time, so it will be accepted and bounced later. If you were sending to a gmail address when sending through gmail, then it would fail immediately.
If an account does not exist at all, most servers (including gmail) will still give a 5.1.1 "Unknown user" response, and that will be reported correctly by PHPMailer if you send by SMTP directly to the recipient's supposed mail server (but not if you send via an intermediate server (like gmail) or using mail()). PHPMailer doesn't have built-in support for doing that, but doing it yourself only involves a call to getmxrr and setting Host manually. Also you won't need to use authentication if you send that way.
You can do various things like check if a domain exists at all - if it doesn't, mail delivery won't work. Some servers will accept all addresses and send bounces later (e.g. if they have a spam filter with a long processing queue), but if you get rejected up-front, it's a pretty sure indication that the address doesn't exist.
You need to look into bounce handling too which will allow you to remove addresses that looked ok but later proved not to be, which is an entirely separate thing from anything that PHPMailer does. I will warn you now - bounce handling is extremely unpleasant!
You should also send using tls on port 587, not ssl on 465; see the gmail example provided with PHPMailer.
The only reliable way to confirm delivery is to get the recipient to answer. Tracking pixels don't work very well, or at all, and delivery receipts are often disallowed. Bounced emails only identify dead mailboxes that generate a non-delivery report - not all do - and won't identify a mailbox that's active but ignored. If the people you are emailing want something from you, don't give it to them until they've confirmed their address by responding to an email.
You can ask for a receipt but the user has a choice and most people like me will not let it acknowledge receipt. All you can do is to make sure all your headers are correct and monitor the bounced emails.
Yes this can be done by - Using imap to read the bounced mail notification that gmail mailer-daemon sends back for undelivered mail and then parsing out the bogus address. Using that you can go back to your database and clean it up. My login/registration system will not require a valid email for basic access, but for elevated privileges it will. I'll just make an admin class function that processes privilege requests and also does database cleanup for basic accounts so there will be no lag-time for new user registration.
Thanks to all that had a look and contributed!!! Now that I'm about done I'll have a look at getmxrr and see if that is better, but still plan to expand imap to automate email proxy account maintenance(deleteing, moving, ect...).
The solution I found was :
1) To save a copy of the email in a mysql database with an ID.
2) Make sure the email is signed with the domain in 1024
3) Add a img to the email requesting an image from a PHP file like https://www.example.com/img.php?id=emailid with the email ID instead of emailid
4) In img.php get the email ID and update the corresponding entry of your database with the time and date and render a base64 image.
So now you can know when the email is open and the time and date.
Try this:
if ( !PHPMailer::ValidateAddress($email) )
or
if ( !$mail->validateAddress($email) )

Why my email sent by my site is marked as spam in google and hotmail using codeigniter phpmailer

This is a redundant question.
I am using phpmailer codeigniter library in sending email. I can send and recieve email however when I received it, it is marked as spam.
I think this info can be useful:
public $Mailer = 'mail';
public $Hostname = 'http://www.fhi365.com/';
public $Host = 'smtp.gmail.com';
public $Port = 465;
public $SMTPSecure = "ssl";
public $SMTPAuth = true;
What are the steps I need to do to solve this?
Thanks for help
This is not the issue of sending through server email servers.
For an email to be considered "safe" it has to meet A LOT of criteria, which, without full access to the server, I don't think can be configured.
First of all, you need to have DKIM and SPF key signatures that are actually valid. They are needed for the email service provider to be sure that you aren't a scam.
Next, you from email and domain (from email is what is before the #, and domain is what is after the #) have to be safe. Which means that when you send emails, people actually open your letter. Because let's say I set up a simple php email sending script and send some inappropriate pictures or some evil-evil programs. That is why ESP by default put your email into spam. That's why on most websites on registration, you are asked to check your spam folder. The website's domain does not have enough "positive" reputation to be considered trusted by the major ESP. If one person moves your letter from spam to inbox, you get a small reputation boost - but you need a lot of it.
Next, is the sender. The IP of the sender also has to be trusted. If you are sending from a PC IP that is known for spamming, even if you have all the previous criteria all set up, it will still be spam box for you all the time. That is called domain warming. You need reputation for your IP as well.
There are also minor things such as email content (if it looks like a casual letter, you have more chances of getting into inbox), the amount of styling and pictures you have in there.
Bottom line - don't bother a lot with getting your email to inbox. If the user KNOWS he is getting your letter in the email, he will get it out of the spam folder. Just notify the user about the email and you will be set.

Sending Mail To A Large Number of People

I have read lots of questions and answers about this issue on StackOverflow, but none of the ones I've read answered my question specifically.
I do not want to have a mailing list. People tick a box if they want to receive the bulk email. There are no wrong emails because accounts are activated using emails. So no bounce checking. However, I already use PHPMailer (so no issues with headers and such) and add every address to the 'to' field of the email. This means everyone can view all the emails (by reading the email source or hitting "reply to all" in their email client), which will not be desirable by other users. The question is:
1) should I send each email individually, or put all addresses in the 'bcc' field?
2) Won't this make some mailservers mark the email as "spam", no matter how well-structured it is? If so, is there a way to further prevent this (apart from adding the address to some whitelists or setting up domain keys or Unix cron jobs)?
Thanks!
All of the things mentioned here require the user to "subscribe" using a form, and then confirm their email address (like in PHPList). However, I already ask for confirmation when people register, so no sense in asking them again and again. My existing code checks the database; if their "receive-movie-mail" bit is set to 1 (these are gathered using an sql query), an email is sent to them when a new movie is added to the database. So, if you still believe this to be a mailing list (which I think it kind of is, but maybe my definition defies existing software features), I'd like it to have, 1) some way of subscribing users to the list with PHP code (E.G. if the "I want to receive an email every time a movie is uploaded to the database" checkbox is checked, in my form processing code I'll subscribe them), and 2) a way to mail people with PHP (I.E. a function like send_mail_to_list($content) that sends the email to the people I have subscribed, when the "Add Movie" form is submitted). Is there such a mailing list management software?
You should loop over the list of emails and send an individual email for each address:
$mail = new PHPMailer();
$mail->IsSMTP(); // set mailer to use SMTP
$mail->Host = "mail.{domain_name}.com"; // specify main and backup server
$mail->SMTPAuth = true; // turn on SMTP authentication
$mail->Username = "{username}"; // SMTP username
$mail->Password = "{password}"; // SMTP password
$emailFrom = '{email_address}';
$mail->From = $emailFrom;
$mail->IsHTML(true); // set email format to HTML if needed
$emailSubject = '{your subject}';
$emailBody = "Whatever content you are sending.";
$mail->Subject = $emailSubject;
$mail->Body = $emailBody;
foreach($emails => $email) {
$emailTo = $email['email'];
$emailToName = $email['name'];
// send an email to customer
$mail->AddAddress($emailTo, $emailToName);
if(!$mail->Send())
{
echo 'failed';
}
$mail->ClearAddresses();
}
1) should I send each email individually, or put all addresses in the
'bcc' field?
Definitely Individually. Bcc will have your email seen as spam.
2) Won't this make some mailservers mark the email as "spam", no
matter how well-structured it is? If so, is there a way to further
prevent this (apart from adding the address to some whitelists or
setting up domain keys or Unix cron jobs)?
using an SPF record might help. Make sure the reverse-dns to your server is not blacklisted, especially if it's a shared hosting.
I have not done this in php since I know that by default there is no hyper threading in php.
In other languages / frameworks like Ruby or .NET you would send individual emails out together by hyper/multi threading them. This is similar to the *nix cron jobs approach you know of except that it is executed at run time - you create say one thread for every 5 addresses you are sending and then all the threads send out 5 mails one after the other.
Keep in mind that even with this approach the bottle-neck shifts from the application to the mail server you are using. So lets say you are using the inbuilt postgre that ships with apache - it won't handle large volumes since each thread will add load to it.
And of course you should avoid this all together if you can use MailChimp!!
Send each user a separate email, addressed only to them.
Set up DKIM and SPF, or at least create appropriate SPF records. DKIM requires some configuration of the mail server that's actually sending the mail for you, but can help greatly with deliverability, especially to large email providers.
My tip next to others would be: maintain a queue of emails where you can limit delivery rate. Some email providers do not like when you try to deliver thousands of emails to their domain at once.
This should be possible with some MTA's.. But I haven't seen one which is flexible enough to do this. What I used for this was Pear class Mail_Queue + cron job.

How to hide sender email address using phpmailer?

I am using phpmailer to send email. I need to know how to hide or mask sender email address
You can specify any sender email address anyway, since SMTP by itself does not place any requirements on sender email addresses.
If the actual SMTP server you use places restrictions on email addresses (e.g. corporate servers which do not allow sender emails outside of the company domain) there's no way around that, unless of course you can influence the mail server configuration.
Update:
You say in a comment that you want to use gmail to send email where the sender's address is not a gmail address. There is no way to do that.
This is a rare situation you have here... if you do not have a mail server you can still tell PHPMailer to send from a different address just set the From attribute of the PHPMailer object to the address you want. But Wait! if your server doesn't exists, the client can't verify the account and then your mail will more likely be deleted (moved to spam in the more benevolent scenario). If you are trying to mimic third party mail, I'll help you no futher.
Note: Your mail server may be valid but clients are still unable to verify it, and thus you are getting mails delivered to spam or deleted. Check "Must Read" to below to have some inside on how to solve this.
On the other hand, if you already have a mail server, then tell PHPMailer you want to use it, set the Host and Port attributes to your domain name and port respectively. The same if you want to use an account form a different server, remember to set the attributes Username and Password correctly, you may also need to set SMTPAuth = true; and SMTPSecure = 'ssl'; depending on the server. [Note: Username and From may differ]
Now, if you want to use an account from Gmail, you could easily set an alias in Gmail to send as another account [Go to Settings-> Accounts And Import -> Send mail as -> (click) Send Mail From Another Address], that can be the case if you have a mail server but you cannot afford to have it online, you will need to start your server so you can receive the confirmation code Gmail generates to verify your account. Check recommended read for PHP side configuration details.
Lastly if for some rare circunstancies you can't tell PHPMailer to use your mail server, but you do in fact have one, and that one is able to recieve the mail... you can use AddReplyTo('me#example.com', 'My Name'); Most clients will understand that any reply to the message must be (unless explicitly defined by the user) directed to "me#example.com" in this case.
Disclaimer: I take no responsibility of any harm result of the use of the method I mention here, such as (but not limited to) your mail account getting banned.
Must read:
Coding Horror on sending mail via code
Recommended read: PHPMailer Tutorial (old version)
No need (neither a good way) to hide or mask whatsoever.
I assume you already know how to use the class you are talking about.
You probably have some variable for sending email, like
var $From = "someguy#whatever.com";
you can type whatever you want into that email address. Gmail dont care what email things is sent from.
And no, this dosent sound very legit.
One more thing: Gmail requires a gmail account to relay mails. Its no problem, it wont be visible.
You want to "show the company email address as sender" but you "didn't (sic) have any email server"?
Can anyone actually send you email at your company email address? If so, use that server which is hosting your email to send out from.
If you don't really have a company email address, then I suggest you get a gmail address like companyname#gmail.com and just send from that. Otherwise the email will appear as spam to a great many of your recipients.
Now, if the people you are about to send an email to actually signed up to be on your mailing list then you can use a third party application like Constant Contact to do your broadcasts from.
If they haven't, then I suggest you not send an email at all.
in mail headers you can have both a Sender: and a From: header which in most mail clients is displayed as either just the From or in some cases Sender on behalf of From, using this way is a nice and clean way to be able to send From a different mail address then the actual Sender mail server
This is highly illegal.
var $From = "someguy#whatever.com";
Is the only option your have for trying to hide email address. But no matter what your email will be inscribed with IP. Someone who knows what they are doing will still be able to trace the email back to the source.

Categories