cakephp Activation Email Sending slow - email

I have a simple email sender for user account activation. Depending on which email address I use, I get significantly different response times: University email - 1 minute, Gmail - 3-4 hours, Yahoo - 1 or 2 days -- which seems bizarre. Has anyone else seen this phenomenon?
EDIT:
There weren't many responses (even for a bounty), but I'll try to explain my problem more clearly.
This probably isn't greylsting -- If I so a simple:
php mail ($to, $subject, $body) // this delivers instantly.
My cakephp code:
function __sendActivationEmail($id) {
$User = $this->User->read ( null, $id );
$this->set ( 'suffix_url', $User ['User'] ['id'] . '/' . $this->User->getActivationHash () );
$this->set ( 'username', $User ['User'] ['username'] );
$this->Email->to = $User ['User'] ['email'];
$this->Email->subject = 'Test.com - ' . __ ( 'please confirm your email address', true );
$this->Email->from = 'noreply#test.com';
$this->Email->template = 'user_confirm';
$this->Email->sendAs = 'text';
$this->Email->delivery = 'mail';
$this->Email->send ();
}
Causes delays from 13 minutes (ok; we'll deal with it) to 5-6 hours (less okay, since this is an activation email). For some of my users, it works instantly, but for other users (of the same service provider, i.e., gmail, it sees these delays).
Any clues?

The code looks fine, but it of course doesn't tell anything about the mail server's configuration.
3-4 hours I would put down to Greylisting, but 1-2 days is definitely too much. Is this reproducible? How many addresses have you tried this with?
What do the full headers of the (received) mails look like? The "received from: .... "path should tell you at which point it took 1-2 days to deliver.

Maybe you can install PHPMailer as a Vendor and create a Component called "Mail"...
And don't forget to authenticate with your SMTP server! :)

Ignore the whole PHP element of it for a moment.
If its a linux server for example, send a mail from the command line e.g. mail myemail#me.com
see if the same thing is happening that way. Its quite likely its a server configuration issue not a php or cakePHP issue.
Look up a few basics like having a FQDN and maybe look into setting up SPF records for your email. Make sure the emails are coming from your domain name not someone elses e.g. not the users email.
Also check if you have email spam software set up that could be grey listing you email on the way out (unlikely but possible). the mostly like thing is the destination spam filter is delaying it. Try send to a gmail account and see if it gets through fine or goes into spam.
Do all this without touching PHP, if all is going fine there then set up a basic php script to do a basic email not using CakePHP, if that works fine then you know its CakePHP etc but I doubt it.

So after further digging, I realized that it was our server host's problem. We use Slicehost, and it just so happens that a range of ips that had been blacklisted included our own ip. We got our name off the list, and we're good to go.

Related

building faster webmail script

i want bulid faster webmail
i've built small webmail script based on ( php imap functions ( imap port connection ) )
but it take a long time to connect and get the mail ..
So, i decided to read the mail manually without connect ( by my own functions ) ..
i've built my own functions, that go to the ( user mails ) path, and then i use ( scandir function )
to get all mails in the folder, and then read/get them manually!
i'll show you an example code
<?
$current_folder = 'new';
$virtual_user = 'someone';
$path_to_mails = '/home/user/mail/' . $virtual_user . '/' . $current_folder;
$all_emails = scandir( $path_to_mails );
foreach ( $all_emails as $mail_file ) {
$file = file_get_contents ( $mail_file ) ;
//Now i've the mail file ..
//i'll explode it and extract the important information from it
}
?>
Now i got emails without connect to any port
i think it faster than the ( php imap functions ) ...
but it also take a long time to get and read the file!!
why gmail and yahoo is soooooooooooooooooooo faster??? may be they using database to store their webmail files?
NOW MY QUESTIONS IS
1 - is my own functions really faster than the php imap functions theoretically? ( may be i am wrong )
2 - ( Gmail , Yahoo , Hotmail ) where they storing their mail files? database or hard disk? they are so faster and
in the same time they allow you to connect to their server via imap and get your mails via php, that mean they using hard disk to store email files!!
or may be they use database and they customized their webmail softwares
3 - is there any way to customize the postfix, store the mails to database instant of the hard disk??
4 - tell me the best idea to build a faster and strong webmail system
PLEASE DO NOT IGNORE ANY OF THIS QUESTIONS
i am working on this project 3 months ago.. i've tired!
1 - Yes.
2 - Depends on the provider. I assume Yahoo and Hotmail might be using actual IMAP servers but I don't think they disclose their infrastructure.
3 - This does not relate to postfix. Postfix is just the MTA after all. It doesn't store the mails it just transfers them. So you can of course code your own database driven service. Daunting task ;)
4 - Build on existing tools. The easiest choice is to build on top of the Horde Webmail
Webmail is a daunting task. The small snippet of PHP code you showed is really light years away from reality if you consider the complexity of modern webmailers. If you really want something working you need to start with existing building blocks. Horde is the best option there because it is a development framework, provides efficient IMAP caching capabilities, a decent AJAX backend and so on. Nevertheless: Your own webmail service will remain a daunting task nevertheless.

Change 'From' field of magento contact form email to the sender

How would one go about changing the 'From' field of the contact form email to that of the sender's? For instance, if a customer was to fill in the form with the email 'test#test.com', how can I make the generated email be from 'test#test.com'?
I've looked at the 'email sender' field in the system admin panels, but this only allows for a range of preset store emails.
Many thanks
The place where this gets sent is in app/code/core/Mage/Contacts/controllers/IndexController.php at abouts line 100. It looks like the reply-to address for the emails is already set to the email address from the post, so if you're just looking to get easier replies, I'd suggest not fooling with it.
Another issue that you'll likely see is that sending email with a spoofed "from" address may cause your site to quickly become blacklisted from many email providers, which may affect the rest of your business.
That said, if you still want to do this, in that file change this code a bit:
$mailTemplate->setDesignConfig(array('area' => 'frontend'))
->setReplyTo($post['email'])
->sendTransactional(
Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE),
Mage::getStoreConfig(self::XML_PATH_EMAIL_SENDER), // change this
Mage::getStoreConfig(self::XML_PATH_EMAIL_RECIPIENT),
null,
array('data' => $postObject)
);
Hope that helps!
Thanks,
Joe
Magento Contact Form - been receiving email from myself is a newer duplicate of this question and Joe's answer got me on the right path. In my answer to the duplicate question, I wrote a custom module to override app/code/core/Mage/Contacts/controllers/IndexController.php and ended up changing the indicated line above to array('name'=>$post['name'], 'email'=>$post['email']), to make the fix.
IMHO, when I do urgent small fixes in the core that have to stay until properly overloaded, I'm sure to end each line with a comment with my initials twice //CKCK hack to fix ___ and then you can grep for this and see all of your mods via ssh shell: app/code/core$ grep -rn "CKCK" *
I'm also using github for version control, which helps, too.

How do I check if an email address is valid without sending anything to it?

I have a client with 5000 emails from an old list he has that he wants to promote his services to. He wants to know which emails on the list are still valid. I want to check them for him - without sending out 5K emails randomly and then being listed as a spammer or something. Ideas?
You can validate the email via SMTP without sending an actual email.
http://code.google.com/p/php-smtp-email-validation/
You could also send emails out, and check for bounces.
bucabay's answer is the way forward. What a library like that essentially does is checking for existing DNS record for (mail) servers at specified domains (A, MX, or AAAA). After that, it do what's termed callback verification. That's where you connect to the mail server, tell it you want to send to a particular email address and see if they say OK.
For callback verification, you should note greylisting servers say OK to everything so there is no 100% guarantee possible without actually sending the emails out. Here's some code I used when I did this manually. It's a patch onto the email address parser from here.
#
# Email callback verification
# Based on http://uk2.php.net/manual/en/function.getmxrr.php
#
if (strlen($bits['domain-literal'])){
$records = array($bits['domain-literal']);
}elseif (!getmxrr($bits['domain'], $mx_records, $mx_weight)){
$records = array($bits['domain']);
}else{
$mxs = array();
for ($i = 0; $i < count($mx_records); $i++){
$mxs[$mx_records[$i]] = $mx_weight[$i];
}
asort($mxs);
$records = array_keys($mxs);
}
$user_okay = false;
for ($j = 0; $j < count($records) && !$user_okay; $j++){
$fp = #fsockopen($records[$j], 25, $errno, $errstr, 2);
if($fp){
$ms_resp = "";
$ms_resp .= send_command($fp, "HELO ******.com");
$ms_resp .= send_command($fp, "MAIL FROM:<>");
$rcpt_text = send_command($fp, "RCPT TO:<" . $email . ">");
$ms_resp .= $rcpt_text;
$ms_code = intval(substr($rcpt_text, 0, 3));
if ($ms_code == 250 || $ms_code == 451){ // Accept all user account on greylisting server
$user_okay = true;
}
$ms_resp .= send_command($fp, "QUIT");
fclose($fp);
}
}
return $user_okay ? 1 : 0;
I think you need to send the emails to find out. Also, this is pretty much exactly what a spammer is, thus the reason for getting put on spammer lists. Sending in bursts will help you hide this fact though.
You'll have to email them at least once.
Create a new email list. Send the old list an email with a link they need to click on to continue receiving messages (re-subscribe).
Send them all an email and collect all reply-to bounces on a real email account, then purge those bounced emails from your main list.
Send them all an HTML email, and one of the images is remotely hosted and requires a unique ID to request it that you set in each email. When your web server returns that image to their client, you can then consider that email as active. This is called a web bug, and will only work if the person automatically loads remote images in their client.
https://github.com/kamilc/email_verifier is a rubygem that will check that the MX record exists and that the SMTP server says the address has a valid mailbox.
You can use a paid service like Kickbox to do this as well.
You can consider the MailboxValidator service http://www.mailboxvalidator.com/ which should be adequate for your requirement. You can get either a bulk plan where you can upload a CSV file containing your email list or get the API plan if you require programmatic integrations.

Using CakePHP's Email component

I try to send a simple Email via CakePHP's Email Component. I'm using following code from the cookbook documentation:
$this->Email->from = 'Irgendjemand <irgendjemand#example.com>';
$this->Email->to = 'Irgendjemand Anderes <irgendjemand.anderes#example.com>';
$this->Email->subject = 'Test';
$this->Email->send('Dies ist der Nachrichtenrumpf!');
The send()-method does only return a boolean value with the value false - but no error or warning occurs.
Does somebody have a solution for that?
Have you tried changing the delivery options? There are three options: mail, smtp and debug.
$this->Email->delivery = 'debug';
$this->Email->send('test message');
debug($this->Session->read('Message.email'));
You can debug with EMail. Set the delivery to debug and the email message will be set to Session.message:
if (Configure::read('debug') > 1) {
$this->Email->delivery = 'debug';
}
$ret = $this->Email->send();
if (Configure::read('debug') > 1) {
pr($this->Session->read('Message.email'));
}
Which OS are you on? If Windows, this note may be of interest:
Note: The Windows implementation of mail() differs in many ways from the Unix implementation.
...
As such, the to parameter should not be an address in the form of
"Something <someone#example.com>". The mail command may not parse this properly while talking with the MTA.
Secondly, it may just be the case that no mail server will accept outgoing mail from your local machine due to spam protection. I have often seen that the same mail() function will not work locally, but works fine once uploaded to a trustworthy server. You could try to use an authenticated mail relay in that case (SMTP).

How to make an email bot that replies to users not reply to auto-responses and get itself into mail loops

I have a bot that replies to users. But sometimes when my bot sends its reply, the user or their email provider will auto-respond (vacation message, bounce message, error from mailer-daemon, etc). That is then a new message from the user (so my bot thinks) that it in turn replies to. Mail loop!
I'd like my bot to only reply to real emails from real humans. I'm currently filtering out email that admits to being bulk precedence or from a mailing list or has the Auto-Submitted header equal to "auto-replied" or "auto-generated" (see code below). But I imagine there's a more comprehensive or standard way to deal with this. (I'm happy to see solutions in other languages besides Perl.)
NB: Remember to have your own bot declare that it is autoresponding! Include
Auto-Submitted: auto-reply
in the header of your bot's email.
My original code for avoiding mail loops follows. Only reply if realmail returns true.
sub realmail {
my($email) = #_;
$email =~ /\nSubject\:\s*([^\n]*)\n/s;
my $subject = $1;
$email =~ /\nPrecedence\:\s*([^\n]*)\n/s;
my $precedence = $1;
$email =~ /\nAuto-Submitted\:\s*([^\n]*)\n/s;
my $autosub = $1;
return !($precedence =~ /bulk|list|junk/i ||
$autosub =~ /(auto\-replied|auto\-generated)/i ||
$subject =~ /^undelivered mail returned to sender$/i
);
}
(The Subject check is surely unnecessary; I just added these checks one at a time as problems arose and the above now seems to work so I don't want to touch it unless there's something definitively better.)
RFC 3834 provides some guidance for what you should do, but here are some concrete guidelines:
Set your envelope sender to a different email address than your auto-responder so bounces don't feed back into the system.
I always store in a database a key of when an email response was sent from a specific address to another address. Under no circumstance will I ever respond to the same address more than once in a 10 minute period. This alone stopped all loops, but doesn't ensure nice behavior (auto-responses to mailing lists are annoying).
Make sure you add any permutation of header that other people are matching on to stop loops. Here's the list I use:
X-Loop: autoresponder
Auto-Submitted: auto-replied
Precedence: bulk (autoreply)
Here are some header regex's I use to avoid loops and to try to play nice:
/^precedence:\s+(?:bulk|list|junk)/i
/^X-(?:Loop|Mailing-List|BeenThere|Mailman)/i
/^List-/i
/^Auto-Submitted:/i
/^Resent-/i
I also avoid responding if any of these are the envelop senders:
if ($sender eq ""
|| $sender =~ /^(?:request|owner|admin|bounce|bounces)-|-(?:request|owner|admin|bounce|bounces)\#|^(?:mailer-daemon|postmaster|daemon|majordomo|ma
ilman|bounce)\#|(?:listserv|listsrv)/i) {
That really sounds like something that's probably available as a module from CPAN, but I didn't find anything clearly relevant in five minutes of searching. Mail::Lite::Mbox::Processor looks like it might do what you want:
Mail::Lite::Message::Matcher is a
framework for automated mail
processing. For example you have a
mail server and you have a need to
process some types of incoming mail
messages automatically. For example,
you can extract automated
notifications, invoices, alerts etc.
from your mail flow and perform some
tasks based on content of those
messages.
but its docs are sparse enough that it isn't immediately obvious whether it provides those example functions itself or if you have to provide the code to drive them.
In any case, though, if you haven't already checked CPAN, that's where I would start if I wanted to do something like this.
My answer here only deals with bounces which is more straightforward.
Using DSN (Delivery Status Notification) identifier will help you detect a DSN/bounced message. It should go to Return-Path and not Reply-To.
Here's a sample of a typical DSN message. The header information includes the message id, content type has specific values (delivery-status) etc.
Not able to provide you any codes in perl, just my 2 cents of idea.
PS: Do note that not all mail servers or MTA conforms to this, but I guess most do.
There should be a standard way of dealing with this, but the problem is that you'd have to assume that systems that send auto-replies comply to that standard, when most the time, they just don't.
How do you get the address that you reply to? I hope you aren't using the From: header. Check the Reply-to: header first and if that doesn't exist, use the Return-path:.
But whatever you do, you will simply have to keep a log of what you sent to whom and throttle your bot to some sensible value of messages per time.