PHPMailer store finished mail - php

I'm searching for a good way to store the e-mail generated by PHPMailer,
in a database instead of sending it out directly via SMTP.
The reason for doing this is, that mails are getting sent via customer provided mail servers, which will probably be unreliable. So that's why I would like to queue mails in the database instead of directly sending them.
The obvious idea would be to store PHPMailers internal $MIMEHeader, $MIMEBody and similar variables and then later put them back into the PHPMailer object.
Unfortunatly this isn't really possible, because most of these variables have protected-access modifiers set on them without any other way of accessing them.
I thought about doing things like Reflection to change the access modifiers to public, but that sounds like a crude hack, which is prone to breaking...
Also: I don't really want to modify PHPMailer itself, to be able to still update PHPMailer.
Serializing the whole PHPMailer object was another idea, but that would be a little bit impractical, because I'd need to make sure that (for example) attachments in the filesystem are still there when sending the mail.

You can get hold of a complete message without sending it by doing this:
$mail->preSend();
$message = $mail->getSentMIMEMessage();
You can drive the SMTP class by itself if you want to submit a pre-built message, but it's not especially straightforward - you are better off following the other suggestions of storing the parameters rather than the pre-built message.
Being able to set headers and body directly would imply that PHPMailer contains a complete MIME parser, and that's just not its job. Also getting around the protected access is not sufficient because calling the send function would cause all your changes to be overwritten because the message is only built at send time (which is why those properties are protected in the first place - they are for internal use). In short, you're approaching this the wrong way.
As others have said though - you're queuing in the wrong place - this is what mail servers are for, they are very good at it, and you really don't want to write your own MTA. This is what I do, and I have no problem sending a million message per hour - my MTA takes care of all the reliability issues.

I'm searching for a good way to store the e-mail generated by PHPMailer
Perhaps it would be sufficient to store just data you build your mail content from (even as serialized arrays, JSON whatever). Then when needed, you can build the mail again and resend.
which will probably be unreliable
By the same logic your code will probably be buggy.
Jokes aside, once send() returned success, it's not your problem what will happen with the mail delivery. If it will fail, then it's not you who should fix it as the culprit is outside your code. Just add "reliable mail server" to your app's requirements :)

Related

How to track an ID on an email when the user replies?

I'm using Laravel 5.5. In my app, users can write something and send it through email to someone. The thing they wrote gets recorded as a "message" in my DB. I need to, somehow, send the ID of this message in the e-mail, so when the receiver replies through e-mail, I know which message he's replying to.
What's the easiest way to do this? I know there are APIS, but I need to implement a custom solution.
Thanks for any light on this.
Use extended addressing on your mail server - replies+specialcode#example.com ... although a lot of bad "email validation" methods think it isn't valid, so I changed the extension character to a hyphen instead of the + on my postfix setup.
All mail is delivered to replies#example.com but the to: and other headers keep the specialcode part which you can then use to route into a ticketing system, etc.
This feature is supported by Postfix (recipient_delimiter in main.cf), QMail, and several other SMTP servers. Note that you need the support for this on the incoming-to-you SMTP side, nowhere else, especially if you use a character that isn't typically declared as "wrong" by various filters. May be worth splitting off a subdomain so you can easily set up separate MX servers, etc. since I'm sure you don't want your regular corporate mail running through the same filters and processing (at least, I would...)

How to save all e-mails sent by Swiftmailer

I'm building a Symfony 2 web application. My e-mails are sent via Swiftmailer.
Since in the last version of my web app, I logged all e-mails sent by the mailer class/function in the database to keep track (see if the system works and have a certain proof that my e-mail was at least sent), I wanted to do the same in this version. At that time, I was using PHPMailer which I wrapped in a function to include the PDO calls.
Using Symfony and Swiftmailer now, I wondered how I could easily log all the e-mails in my database with, of course, doctrine ORM.
I guess the easiest thing would be to log it manually each time I send an e-mail, but I want it to be done automatically since I will be sending a whole lot of e-mails. I also want my class afterwards to be as flexible as Swiftmailer is, so wrapping everything in a "simple function" is not an alternative.
A first idea I had, was to extend the Swiftmailer class and add a custom send method that internally calls the herited send()-method. The issue with that is, that I do not exactly know where to place that class and also, I would need to connect or call it via custom services since the build-in service uses the Swiftmailer itself, wouldn't I?
In addition to that, there is the issue that e-mails are maybe spooled and in that case, send() does not give you feedback, if the e-mail has really been send. Or do I have a misunderstanding of way that works?
Did anybody else have a similar issue/request? If so, how did you solve it?
Thank you.
Ok, I've now found a bundle, the Swiftmailer-logger-bundle, that solves my issue.
https://github.com/tweedegolf/swiftmailer-logger-bundle
For those who have a similar issue: Have a look at that bundle. If it does not fit your needs, it will at least explain how to use the swiftmailer events.
There's a couple of approaches you could take here. First approach is as you said, persist email to the database and send email from the database and see if it was sent that way. The Automailer bundle does that for you.
I wouldn't recommend that approach as you'd need to maintain that table of data that can expand quickly and easily. You're also probably going to need to maintain an MTA.
What you're probably more interested in is if the email was received by the end user. If that's what you're trying to find out I would recommend using a transactional mail service such as Mandrill or Sendgrid. The reasons I'd recommend this are.
You don't need to operate an MTA
You don't need to worry about storing your email locally.
They have an API that makes sending tractional email very simple
They have API's that make it trivial to find out if the message you sent was received.

How to secure a simple PHP script that sends emails?

In a simple contact form, the HTML form triggers a Php script :
<form method="post" action="email.php">.....</form>
This email.php sends me an email :
<?php
$mess=$_POST['name']. "\r\n" .$_POST['site']. "\r\n" .$_POST['email']. "\r\n" .$_POST['meta']. "\r\n" .$_POST['message'];
mail('myemail#gmail.com', 'Subject', $mess);
?>
The HTML is using jQuery validate plugin, but nothing like this on the Php side.
A Security expert told me how insanely unsecure this php script was.
What can I do to enhance security ?
My guess is that your "security expert" saw you using raw $_POST data and using the mail() function, and he freaked out, but didn't stop to actually check how bad things were.
He has a point in that using $_POST without doing any validation on it is almost always a recipe for being hacked, but in fact in this particular case I don't think it's too bad, because you are the only recipient (so it's not going to be used for spam, which is the main thing to worry about in these cases), and because the body is plain text (so a hacker can't send you any nasty scripts or attachments).
Without any validation, you could get some really weird emails as a result of hackers trying to find a way around your defences, but not too much else.
PHP's mail() function is a well-known soft target for hackers because there is an awful lot of insecure code out there that uses it. However the real danger with mail() tends to be if you use the headers parameter (ie to set things like the sender address, etc), which you haven't used. Since you're not using headers, the risks are a lot lower, and mainly limited to making it easy for someone to mailbomb you.
If you are still worried about the security of the mail() function, the best solution is to use a library like phpMailer instead.
To be honest, my advice whenever anyone wants to use PHP's mail() function is always to use phpMailer or Swiftmailer instead. And it's not even just about security; even for simple cases, they can make your code a lot easier to read and maintain.
One big flaw is that an attacker could trivially fill your inbox with malicious or junk messages which, besides being very annoying, would likely cause Google to put your domain on their spam list.
They could do this by writing a short script to call that PHP function with some arbitrary data, and loop through it for however long they want.
This is an alternative way of solving what you asking for. And I hope this can be useful for other askers, as I see similar questions coming op consecutively.
If you intend to make professional application and focus on your core business, then I suggest you use some secured email portals with API from like mailgun, mandrill or others. Both service offer a dash board where you can see e-mail status of how many emails are sent and delivery status, and a lot of other statistics. It is FREE for small usage. It is worth it using it, because you will solve some of following issues:
You do not need to think about maintaining security of your smtp server
Or even correct configuring your smtp
Solving block and black IP addresses
Server attack
Spam problem
And name the more
Both solutions provide API for PHP or other platforms.
Note: I have been my self used my own smtp server few years back, and you know all the time I put to fixing and maintaining the smtp server is not worth it, because I could spent that time doing better stuff and leave e-mail service part for professionals.

phpmailer and server maillog

for those who use phpmailer, and love it, I have a question about getting server response information, if possible.
The limit I've seen is that I can send an email, but there's no way to get a post-message-sent response from the mail server. I am running my own mail server, and I usually watch the maillog file to see what comes back. And there's some interesting responses from places like yahoo, cox, and other mail servers.
Has any one done anything cool to capture such responses, and tie them back to phpmailer events?
The only recourse I can come up with is to log the entries to the maillog into a database, and somehow match the to= and time sent to any emails I send out using phpmailer. But I find that's not quite accurate.
So, I'm open to any ideas.
You should look at message IDs; any bounces should contain the original. You can use custom headers to add another unique identifier, but there's no guarantee you'll get it back in a bounce. Failing that, you need to use VERP addressing in order to identify bounced messages accurately, and you can set that explicitly via the Sender property in PHPMailer.

PHPMailer v. mail() for a simple Contact Form

I am new to PHP, but have a decent grasp of things (have not learned classes yet).
The question:
Which to choose? PHPMailer or mail() for my new contact form.
The form is simple:
Your name:
Your email:
Subject:
Body:
I have around 2,000 visitors per day and receive about 10 submissions per day, so I don't need anything too fancy. =)
Miscellaneous questions in my head:
Is PHPMailer going to better protect my Contact Form from CC: injection (major concern)? I already know the anti-spambot display:none CSS trick.
Will PHPMailer save me the step of having to write an email_validator() function?
Will PHPMailer save me any other time of having to write any custom functions?
Thanks! With any luck, I'll be answering questions soon. Lol
Here is all I could think of in one sitting, forgive me if there are any glaring omissions.
Advantages to using PHP's built-in mail function, no external library/wrapper:
You don't need anything outside of
PHP.
You don't need to learn a new API.
You don't have to worry about a PHP
upgrade or such breaking the script.
You don't have to worry about an
updated version not working on your
PHP installation.
You don't have to worry about
potential security vulnerabilities as
a result of using that script.
If it's a simple task, you'll be done
in a few minutes.
Advantages to using an external library/wrapper:
If you need to introduce more
complexity into your emailing, you
can do so quite easily. Adding
attachments, inline images and such
are not much fun using PHP plain mail
function. External libraries (at
least the good ones) have a more
OOPish API. Adding an attachment can be as easy as $message->addAttachment($file); without having to play around with headers, etc.
External libraries better hide the
ugly complexities of tasks such as
adding attachments, character
encodings and inline images.
Using a library now will save you the
hassle of having to learn it in the
future when you do need the
additional complexity/functionality.
External libraries probably (I'm
really not sure which ones, and to
what extent) address certain
vulnerabilities that PHP's mail does
not.
If I can think of anything else, I'll be sure to add it.
This will maybe not really answer all your questions, but it won't hurt either, I guess...
Whatever you want to do, I would not go with mail() : sending a mail is not such an easy task, and using an existing library/framework will always be a good idea : it will solve many problems you probably have not even thought about -- even if you don't need to send lots of mails.
About your specific questions, maybe other answers will say something else and/or get your more informations, but any "good" library created to send mails should deal with those kind of problems... Else, you should probably search for another library ^^
Still, testing a couple of dumb non-addresses will allow you to be 100% sure ;-)
Another solution to be quite sure is to check the source of the library ;-)
In the source of version 2.2.1, you'll find stuff like this :
class.phpmailer.php, function AddAnAddress, line 413, you'll see this :
if (!self::ValidateAddress($address)) {
$this->SetError($this->Lang('invalid_address').': '. $address);
if ($this->exceptions) {
throw new phpmailerException($this->Lang('invalid_address').': '.$address);
}
echo $this->Lang('invalid_address').': '.$address;
return false;
}
And it seems this function is used by the other functions that add an address... So, I suppose there's some kind of email-addresses validation ;-)
That'll answer at least one of your questions ^^
PHPMailer is not the only solution that exists, btw ; there are plenty of others, like, for instance :
Zend_Mail
Rmail for PHP (Formerly known as HTML Mime Mail)
Swift Mailer
As Pascal MARTIN mentioned, sending an email isn't as straight forward and easy as some people just assume it is. To answer your questions directly. Yes PHPMailer does do some validation, but it's not super-advanced, but should be enough for your uses. And PHPMailer will save you some time depending on what custom functions you will need. Some things to consider though:
HTML vs plain text. If the emails are only ever going to you, this probably isn't as big of a deal. But if you're ever sending emails to your users (say a confirmation email) you want to be able to support both HTML and plain text clients. PHPMailer (and Zend_Mail) make this very easy to do.
SMTP. This is another one that is really important if you're sending email to your users, but not so much if it's just an email to your self. Using php's regular mail() function the email will be sent via sendmail, which almost all *nix installs come with out of the box (especially servers). As a result, spam filters aren't very friendly towards it. If you have a regular SMTP server setup with a trusted MX record (or if you have a gmail account) you can send through that using SMTP, which will help reduce the chances of your mail being flagged as spam.
In addition to just PHPMailer Zend_Mail is a good one to check out to (it's part of the Zend Framework). However that may be a bit much for a simple contact form.
PHPMailer is my choice because it allows me to send SMTP e-mails to google without installing any libraries or configuring a mailserver, that way I don't have to worry about spam-related problems.

Categories