I have a Java webapp that sends out email notifications to client-users in a bunch of different scenarios. The content, schedule, etc. of the mails is determined by the admin-users of the system.
I've pointed the app to a local hMailServer instance in my test environment, now I want to configure this so that all emails it receives are forwarded to a set of email addresses and blocked from being sent to the real recipients.
Since I'm setting this up so that admin-users can test out their emails before we move them into production, it would be good if I could avoid having to rewrite any of the email headers (that way the users can see that the email would have been sent to the right people).
I started by adding a script which changes the subject of the message, this gets called in my first rule.
Sub EditSubject(oMessage)
oMessage.subject = "[TEST MESSAGE - IGNORE] " & oMessage.subject
oMessage.save
End Sub
This makes it easier to write the conditions for rules later, and if an email does get sent it will at least say that it's a test.
Then I set up a Route which targets the actual company mail server (just referenced as SMTPSERVER). I've got this set up to only send to specific addresses, just in case anything gets past the rules.
When I first set this up I just set the route with the domain company.com, but it seems like this was getting triggered before my rules and causing issues. So in the end I just called it bounce.
Next I added the following rules:
Edit and Forward
This has a condition that checks the email subject doesn't contain my [TEST MESSAGE - IGNORE] string, this makes sure we don't trigger this rule on the new forwarded messages.
Then triggers the following actions:
Run function to call the EditSubject script above
Forward email (repeated as many times as you like with each address you want to target),
Delete email
Stop rule processing
These last 2 just stop anything further happening to the original message.
Reroute
This has a condition that checks the email subject DOES contain [TEST MESSAGE - IGNORE], so we only run this rule on the forwarded messages.
It triggers the Send using route action and targets the bounce route.
The end result is that whenever one of my admin-users sets up a new email on the app in test it will be sent to this hMailServer relay.
The mail server edits the subject to include the "test" prefix, creates copies in its queue to forward on to my set recipients, and then drops the original.
The new copies are picked up and passed on (via the route) to the actual company mail server and delivered.
The emails you get out at the end display in Outlook with the To, CC, etc. all showing the original recipients.
Related
User wants to send read receipts with all external emails. I've set up a mailbox rule in Outlook to do the following:
Apply this rule after I send the message
notify me when it is read
except if sent to *Bristol* //Dynamic group for office contacts
or except with #"domainname" in the recipient's address
To stop read receipts on internal emails I've set a rule with ECP via "Mail Flow" > Rules to:
IF
the message type is *Read receipt*
AND
The sender is located *Inside the organization*
AND
The recipient is located *Inside the organization*
THEN
Delete the message without notifying anyone
However it is still requesting read receipts for internal contacts.
Outlook and Exchange 2013
Your rule will only stop the delivery of read recipients not the prompting for which is controlled by a property within the message itself.
You could write a Transport Agent https://msdn.microsoft.com/en-us/library/office/dd877026(v=exchg.150).aspx that could do this by basically processing every message that passes through the Hub (or hubs servers) using the TNEF parser find the PidTagReadReceiptRequested and set it false for those Internal recipients. Probalby the best sample for this type of thing would be http://blogs.msdn.com/b/mstehle/archive/2009/01/13/howto-sample-transport-agent-add-headers-categories-mapi-props-even-uses-a-fork.aspx .
The other way that may work is to Setup a Rule Programatically that using the tagAction http://www.dimastr.com/redemption/rdoruleaction.htm#RDORuleActionTag . In theory you should be able to modify a MAPI Property with this action but there are complexities around this and I've never use it.
Cheers
Glen
I personally can't see a way to do this, but I'm hoping there could be a clever hack to make it work.
We have to send out regular emails to customers, many of who's emails expire and give us a mail delivery failure. To keep the database accurate and clean, I'd like to delete their record from the database when an email fails to be sent to them.
So currently it goes a little something like this:
<cfloop query="rsCustomers">
<cftry>
<cfmail to="rsCustomers.Email" from="us#ourcompany.com" failto="fails#ourcompany.com" subject="Whatever">
[email text here]
</cfmail>
<cfcatch type="any">
<!--- just to skip this record when it fails to send --->
</cfcatch>
</cftry>
</cfloop>
I could run a query within the catch area to delete records when there was an error in the record (e.g. malformed email address). But nothing happens when the mail is undeliverable. I get a failure notice to my inbox but these can be in the hundreds so its difficult to manually go through and delete from the database.
Is there anyway to "catch" the failed to send emails and then feed them back in to a query to delete from the database?
Someone once did a presentation on this at a function I attended. The approach was:
when sending mail, use a special email address in the failto attribute.
write a .cfm file that uses the cfpop tag to read mail sent to this address. (This may have been before the cfexchange tag was available)
add code that reads Delivery Failure Notfications and extracts the email addresses.
do something about those addresses
The presenter ran this file as a scheduled job.
#Dan Bracuk's answer above is the closest thing to a good answer you're probably going to get. Here's why: The CF server isn't delivering the mail, per-se. It's just handing the mailpiece off to a real mail server (even if that server runs on the same machine) for delivery. After it's accepted, CF's job is done. Non-delivery at this stage does not reflect on the quality of the address anyway, but rather the connection between your CF server and the mail server.
From there, it's spooled again, by the mail server. Sometimes a recipient's domain will accept email and ask questions later. The only way to know if an email delivery has failed is to wait for a Non-Delivery Report (email) to be sent to the failto (if used) or from address. This can come from "your" mail server, or a mail server for the recipient's domain. Depending on your mail server delivery retry options and third-party delays, this can take a day or more. If you want to do this yourself, you'll have to write a routine to POP and read the email from the account(s), and analyze them to determine if they are NDRs, and what type. Non-delivery Reports can indicate hard or soft bounces, blocks, delays, or gateway conditions. Obviously, many of these are not "throw it out" situations, so you'll have to parse them for SMTP codes http://www.serversmtp.com/en/smtp-error and keywords to determine if you should drop or mark the email address.
Mandrill has inbound email processing, in which you can setup a catch-all address for which incoming e-mail will be posted to a specified URL.
For example, e-mails to *#sub.domain.com could get posted to http://mydomain.com/process.
Is there a service that will work this way but that allows to "re-route" the e-mails? Say if a post to the URL above returns a specific code, say 403, the e-mail will be swallowed, but when a 200 code is returned, the e-mail gets sent to a specific address, without modification, just as if it was originally sent to that address.
I guess I could code a script that would just re-send the e-mail, but I don't want to run into deliverability issues.
I'm not sure I'm explaining this clearly, so here's a specific example:
E-mail to newsletters#sub.domain.com is received by a Mandrill-like service (the receiver)
That service posts the e-mail to http://mydomain.com/process (let's call this the processor)
The processor either:
Returns a 403, in which case nothing else happens
Returns a 200, and a destination address, and then the receiver delivers that e-mail to the new destination
EDIT: I realize I could just use Mandrill to re-send the e-mail, but wouldn't I run into problems given I won't be the original sender? For example, if I receive an e-mail from support#microsoft.com and then I re-send that e-mail to another address, could I be flagged as a spammer or have other issues with deliverability? So this might not be possible at all?
It seems it is indeed impossible to do what I want, otherwise anybody could spam the world with no problems, however, Mandrill just added this feature, which might come in handy:
http://help.mandrill.com/entries/23374656-Can-I-send-emails-on-behalf-of-my-clients-
This is just an experiment, but I'm going to try and resend mails to my own server instead of forwarding to the original receiver, so then an e-mail client can pull the messages from there.
Given there is a "FAILTO=''" option for cfmail, triggering an email to be sent to that email if the email didn't get delivered...
Is there a way to somehow assign an ID or tracking # to an email, store it in a database with that ID... then update the status of that email if it fails?
I'd like to track bouncebacks... preferably WITHOUT sending the FAILTO to a POP3 or IMAP and then checking it with cfimap...
Is there any alternate way of handling this?
Maybe an event gateway that is triggered upon email failure?
UPDATE: I've decided to take a different approach, utilizing the sendgrid API.
I'm hoping that lends me with a few more tools than CF offers.
The short answer to your question is unfortunately no.
A longer version with a possible solution:
The failTo email address populates the return-path in the email header, this then 'should' be used by mail servers for bounce backs (however see - http://www.bennadel.com/blog/1899-GMail-Seems-To-Ignore-The-Return-Path-Header-Defined-By-The-CFMail-FailTo-Attribute.htm for an example where it doesn't)
So you are going to need to monitor an Imap or pop account to see your mails, however you can set up an event gateway to monitor this, with detailed instructions here - http://www.alagad.com/documentation/imapGateway/ImapWatcher%20Gateway%20Documentation.pdf
What you're left with is needing to identify which mail matches which bounceback, when I've done something similar in the past I used unique id's for the failTo email addresses at a domain I owned. If you set that up and then use your listener cfc to look for the id in the return-path.
So your sending code would work along the lines of:
Generate unique id
Send mail
Add row to database with unique id
Your listener.cfc would then need to inspect the email returned and if it finds the unique id update the row with whatever information that you're after.
Hope that that at least helps even if you'll need to set up some other bits.
You could use a directly watcher on the undelivr folder to log the failed emails, only really a solution if its own server and not a shared server though.
As far as I know once it leave the spool and is off to your SMTP server CF assume it's been sent correctly.
The email will trickle down the chain of SMTP servers/relays and if anything happen the only instruction they have is to bounce it back to the from address or failto address if present. CF isn't listening at this point so it can't respond.
We use an external tool called Glock email processor to handle exceptions. It's not free, but works pretty well. You can find it here: http://www.glocksoft.com/email-processor/
You need to configure it to check the failto address and from there you can take many actions. I got it setup as a three strikes system.
Email address bounce, I increment a counter in my email table, at 3 I deactivate that email from the system.
Nothing you can't do yourself with cfpop though.
I'm sending newsletter using Zend Mail. I have used setReturnPath() to put all undelivered mail notifications in one place.
And what now?
How to get the list of addresses which were unreachable?
How do I read and parse the returned notifications?
How to know whether the mail returned because of non existing email or just quota exceeded?
Which headers do I need to send and check?
Related:
Variable Envelope Return Pathwiki
Handling undelivered emails in web appso
This class may be helpful. Can determine whether the mail is a bounce and return a response code with description:
http://www.phpclasses.org/package/2691-PHP-Parse-bounced-e-mail-message-reports.html
Short Answer:
you can't do that in a simple way and not in your app.
Long Answer:
You should handle that in asynchronous way and outside your php app (at least in part). First of all you must setup the return address to something like sender+recipient=recipientdomain.com#senderdomain.com as in the TimB answer. At this point all the notification sent by receiving smtp server will go to that address.
Then you need to setup the smtp daemon at senderdomain.com mail exchanger to handle that kind of bounce messages and process them in some sort of pipe.
With a pipe you can forward the returned message to an external program which parse the message and extract the needed informations (i.e. the reason why the delivery is failed)
At that point in your program (which can be a cli script in your application) you can mark the address as failing and optionally can record why.
This is a pretty difficult task, which can't be handled in a simple application. Usually I use a dedicated software for large mailing list handling such as sympa which takes care of this task for you.
Otherwise you can use an external delivery service such as Sendgrid which will do the dirty job for you and report the failing addresses with a simple API. As a bonus with this solution, they are in the whitelists for all the major providers, so your email won't be marked as spam as far as you respect some simple rules (i.e. removing bouncing addresses and use an opt-in policy for your newsletter)
Well, the second link and especially the answer by TimB explains very well the procedure.
What may not be clear is that the return path is nothing other than a regular email account, i.e. you will get the email to that address. Zend_Mail is not waiting for a response and hence there is no list of addresses.