Page 1 of 2

My Email Script :)

Posted: Sat Jul 25, 2009 6:02 am
by jackpf
Hi all,
I've been working at this for a while now, and I've just managed to send my first email :D

I was just wondering if anyone could see any potential problems with it. It's worked fine for me so far.

Also, if anyone wants a light weight email script with authentication, feel free to nick it from me.

Code: Select all

/*
:)
Since people have shown an interest in using the script for themselves, I've decided to host it myself
So I can easily keep versions up to date with changes and stuff
 
To download the script with examples and stuff, visit my blog - http://jackpf.co.uk/blog/Programming
*/
Thanks :)

Jack.

Re: My Email Script :)

Posted: Sat Jul 25, 2009 6:22 am
by jackpf
Hmm...how odd.

This works fine on my localhost, connecting to my website's server and sending the email.

However, if I run this script on my webserver and try and connect to the server, from the server, I get a warning from fsockopen saying it couldn't connect to the remote server.

Does anyone know why this could be?

Thanks,
Jack.

Re: My Email Script :)

Posted: Sat Jul 25, 2009 8:13 am
by Eric!
What smtp server are you using on your remote server? Is it local to that server? Have you tried to telnet to it on the same port you're trying to use with your script?

Some hosts don't require authentication for localhost connections, but I would think you could still open the socket...

Re: My Email Script :)

Posted: Sat Jul 25, 2009 11:43 am
by jackpf
Aha it works with localhost, thanks.

However, I tried with hotmail, and it puts the email into a spam folder.

The whole point of this script is to get emails not to be sent as spam...

Do you have any idea why they're being labeled as spam?

Thanks a lot,
Jack.

Re: My Email Script :)

Posted: Sat Jul 25, 2009 4:31 pm
by Eric!
It is probably the header format. There are a few things spam filters look for to weigh it as spam or not. Most often the return path field is missing. Some filters really like to see envelope information.

The second thing some filters tag is the from address without a plain text field or a strange plain text field. Some filters actually block "Jack <jackpf@jacksplace.com>" because the plain text is too generic and lacking a last name. Strange, I know.

Also make sure the date and time stamps conform to the standards as that can trip a spam filter too.

One final thing is on a shared host, some other numbnut could be sending out junk mail and your host server has ended up as a potential SPAM IP or smtp spam domain. This isn't usual, because they often tag spam via domain names only. But you should check the status of your domain against common spam blacklists. In the meantime you can also contact the people filtering your messages (hotmail, etc.) and ask them why they are filtering your domain. I got hacked and it took months finding all the providers that had suddenly added my domain to their spam list.

If all your headers look right and you're stuck, post them here and I'll see if I can see something.

Re: My Email Script :)

Posted: Sat Jul 25, 2009 5:08 pm
by alex.barylski
OP: You should look into SwiftMailer class and see if you can't borrow ideas or maybe join Chris. No point in re-inventing the wheel and SwiftMailer is quite robust, lightweight and flexible enough to meet all SMTP mail requirements.

Re: My Email Script :)

Posted: Sat Jul 25, 2009 7:24 pm
by jackpf
@Eric! thanks a lot; that's really helpful. I'll have a look at my headers and if I can't figure it out, i'll post them here in a sec.
It's weird though, cause google mail doesn't mark it as spam. I guess they're not as strict...or maybe it's because I have previous messages from myself. Who knows...I'll go experiment :D

And PCSpectra yeah...the thing is, I've coded 100% of my website, and that's the point of it really. I don't really like using other people's code...I'm sure a fellow coder can understand that :)

Re: My Email Script :)

Posted: Sat Jul 25, 2009 7:47 pm
by jackpf
Right...this is the all new & improved code:

Code: Select all

<?php
    class mail
    {
        var $connection, $servers, $recipient, $sender, $log = array(), $user, $password;
        
        function __construct($sender, $server = null, $user = null, $password = null)
        {
            list($this->sender['name'], $this->sender['domain']) = explode('@', $sender);
            
            $this->user     = $user;
            $this->password = $password;
            
            if($server != null)
                $this->servers = (!is_array($server)) ? array($server) : $server;
            else
            {
                getmxrr($this->sender['domain'], $this->servers, $server_weight);
                
                if(is_array($this->servers))
                    array_multisort($this->servers, $server_weight);
            }
            
        }
        public function send($recipient, $subject, $message)
        {
            if(!is_array($this->servers))
                return false;
            
            list($this->recipient['name'], $this->recipient['domain']) = explode('@', $recipient);
            
            foreach($this->servers as $domain)
            {
                $this->connection = fsockopen($domain, 25);
                
                if(!$this->connection)
                    continue;
                
                if(!$this->_response(220))
                    continue;
                
                $this->_send('EHLO '.$domain);
                if(!$this->_response(220))
                    continue;
                
                if(!in_array(null, array($this->user, $this->password)))
                {
                    $this->_send('AUTH LOGIN');
                    if(!$this->_response(220))
                        continue;
                    
                    $this->_send(base64_encode($this->user));
                    if(!$this->_response(250))
                        continue;
                    
                    $this->_send(base64_encode($this->password));
                    if(!$this->_response(250))
                        continue;
                }
                
                $this->_send('MAIL FROM: <'.$this->sender['name'].'@'.$this->sender['domain'].'>');
                if(!$this->_response(array(220, 250)))
                    continue;
                
                $this->_send('RCPT TO: <'.$this->recipient['name'].'@'.$this->recipient['domain'].'>');
                if(!$this->_response(250))
                    continue;
                
                $this->_send('DATA');
                if(!$this->_response(250))
                    continue;
                
                $this->_send('To: '.$this->recipient['name'].'@'.$this->recipient['domain']);
                $this->_send('From: '.$this->sender['name'].'@'.$this->sender['domain']);
                $this->_send('Subject: '.$subject, true);
                $this->_send(/*'Message: '.*/$message);
                $this->_send('.');
                
                $this->_send('QUIT');
                
                return true;
                break;
            }
            
            mail($recipient, $subject, $message, 'From:'.$this->sender['name'].'@'.$this->sender['domain']);
            
            return false;
        }
        private function _send($message, $double_crlf = false)
        {
            array_push($this->log, $message);
            
            fputs($this->connection, $message."\n".(($double_crlf) ? "\n" : null));
            
            return true;
        }
        private function _response($response_code)
        {
            $response = fgets($this->connection);
            
            array_push($this->log, $response);
            
            $response_code = (!is_array($response_code)) ? array($response_code) : $response_code;
            
            if(in_array(substr($response, 0, 3), $response_code))
                return true;
            else
                return false;
        }
    }
?>
Ok, so sending to my gmail, I get this:
Array
(
[0] => 220-bumblebeeman.enixns.com ESMTP Exim 4.69 #1 Sun, 26 Jul 2009 01:38:51 +0100

[1] => EHLO jackpf.co.uk
[2] => 220-We do not authorize the use of this system to transport unsolicited,

[3] => AUTH LOGIN
[4] => 220 and/or bulk e-mail.

[5] => *base64_encod-ed username*
[6] => 250-bumblebeeman.enixns.com Hello cpc2-ipsw1-0-0-cust414.colc.cable.ntl.com [82.28.21.159]

[7] => *base64_encod-ed password*
[8] => 250-SIZE 52428800

[9] => MAIL FROM: <webmaster@jackpf.co.uk>
[10] => 250-PIPELINING

[11] => RCPT TO: <jack.philip.farrelly@gmail.com>
[12] => 250-AUTH PLAIN LOGIN

[13] => DATA
[14] => 250-STARTTLS

[15] => To: jack.philip.farrelly@gmail.com
[16] => From: webmaster@jackpf.co.uk
[17] => Subject: Subject
[18] => Message :)
[19] => .
[20] => QUIT
)
I've removed my smtp username and password, but apart from that, that's the entire transaction.
That works fine.

However, when sending that to a hotmail address, it either marks it as spam, or doesn't show up in either inbox or spam. It's ridiculous...I get all this facebook <span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span> but I can't send a proper email.

Any ideas how I can make this email look "real"? :)

Thanks for your help guys,
Jack.

Re: My Email Script :)

Posted: Sat Jul 25, 2009 7:59 pm
by Eran
spam detection goes beyond checking email headers and content. The mail server has to properly identify itself and be available for reverse DNS checks. If you are sending from localhost or shared hosting, this is most likely not properly configured and emails will end up in the spam folder of services that check for spam this way (such as hotmail, gmail, yahoo and others).

Run your mailserver domain in this checker and see what it gives you - http://www.mxtoolbox.com/diagnostic.aspx

Re: My Email Script :)

Posted: Sat Jul 25, 2009 8:08 pm
by jackpf
This is what I got:
untitled.JPG
untitled.JPG (116.95 KiB) Viewed 769 times
Right, so basically people are allowed to send emails unauthenticated. However, I tried this originally, and it only lets you send 5 or something within like an hour...so I doubt anyone's been spamming from it.

:)

Re: My Email Script :)

Posted: Sat Jul 25, 2009 8:10 pm
by Eran
Check the other tests there as well (such as blacklist etc.) Also check the headers of the failed emails in your spam folder, often the mail service puts the reason for failing there

Re: My Email Script :)

Posted: Sat Jul 25, 2009 8:23 pm
by jackpf
Right...I read up on the filtering that hotmail does here, and apparently it consists of checking emails were sent from the domain they claim to have been sent from...

But surely I can't fail that - I'm sending it from my own domain.

Wow...checking blacklists, I'm apparently on 3 :/ A bit worrying...

Well...is there anything I can really do about that?

Re: My Email Script :)

Posted: Sat Jul 25, 2009 9:02 pm
by Eran
There are several channels you can go through to ask removal from a blacklist. I think dnsstuff (http://www.dnsstuff.com/) does that, google for more if they can't help you

Re: My Email Script :)

Posted: Sat Jul 25, 2009 9:47 pm
by jackpf
Hmm...I've had a look around on google and I can't find anything to remove me from the blacklists...

dnsstuff want me to pay for mx lookups and stuff, screw them :P

Well...I've tested the script with gmail, yahoo, mailinator, and my email address on my site, and they all work fine. Looks like it's just hotmail that's the problem. I blame microsoft - they have to ruin everything....

Re: My Email Script :)

Posted: Sun Jul 26, 2009 9:35 am
by Eric!
Well, like I mentioned, different sites use different filters. They are all based on the header information and some content checking. They check format, missing fields, incorrect fields, suspecious fields, multiple destination domains and envelope data. They also then scan the message body looking for spam type things, keywords, links, etc. Then they do a final check against known blacklists, either their own or other peoples or a combination. They check your email domain, the server domain, and often look at all the destination domains. Then they weigh all the bits of data together to decide if it is spam.

Since your message ended up in the SPAM folder and not just deleted, you obviously didn't score high enough on the SPAM scale to get the message deleted. So they only found one or two things they didn't like.

If you are on a blacklist you should double check to make sure your mail system is secure.

Since your domain name is pretty unique, it is unlikely that it was previously owned (and possibly abused). Like I said, sometimes you are guilty by association on a shared host. Some blacklists are not very picky and multiple domains can get blocked if just one on a shared IP is spamming.

You can contact hotmail and request to be removed from their blacklist. It takes a lot of time and effort to get removed from blacklists. You should also contact your host provider and let them know the situation because it is in their interest to keep themselves off those kind of lists.