Getting the original sender when forwarding emails - mailgun

How can I get the address of the original sender, when an email has been forwarded to Mailgun?
The chain of events looks like this:
originalSender sends message to someUser
someUser forwards message to Mailgun
Mailgun POSTs a parsed message to my server
Put in another way:
orignalSender (send)-> someUser (forward)-> mailgun (POST)-> myserver
The best I could get is doing a regex on the "body-plain" property.
The problem is that email clients do send this differently. Here are two examples.
Forwarding from GMail (I added the ...):
body-plain: "---------- Forwarded message ----------\r\nFrom: Kalle Kalleson <kalle.kalleson#mail.com>\r\nDate: 2014-02-13\r\n ..."
Forwarding from Apple's Mail (I added the ...):
body-plain: "(...)Begin forwarded message:\r\n\r\n> From: Kalle Kalleson <kalle.kalleson#mail.com>\r\n> Subject: New color printer\r\n> Date: 11 February, 2014 15:47:19 GMT+1\r\n>
There must be a better way of doing this, right?
Thanks in advance!

I've just been in contact with Mailgun support and they could not offer a different strategy.
That is, parsing the body myself, taking in account the differences between email clients.
Lame I would say, :-(
Here you can vote up the feature request.
http://mailgun.uservoice.com/forums/156243-general/suggestions/5528656-extract-the-original-sender-of-a-forwarded-email
Has anyone come up with a better answer?

Perhaps I am missing what you are looking for, but when Mailgun POSTs to your server, you should be able to pull the From field from the POST data. I'm using a node.js app to parse my messages, however, in PHP it would look something like:
<?php
$from = $_POST["From"];
echo "This message is from: ".$from;
?>
I apologize if I'm missing what you're asking.

Using a regular expression should do the trick in either case.
Try:
/(From:.*>)/g

Not possible to take original sender of an email throw any mail services.
So, we implemented regex and take the first occurence of the match from mail html body.
Regex.Match only returns first match so used this with below regex.
From:\s(.*?)>
https://regex101.com/r/1pUpPU/1

Related

How are text messages added to html messages

I'm using cURL to send Mailgun messages. One of the cURL arguments is -F template='mytemplate' \, which uses a template set-up on Mailgun. How do I add a text version of the message?
According to the MailGun API docs, you can request a text-only version by including the parameter -F t:text='yes' as part of your cURL request.
This will change the MIME Content-Type from text/html to multipart/alternative which most mail clients will render first as HTML, falling back to text if there's a problem. It's worth noting however, that this leaves the text interpretation up to MailGun meaning that you don't get any say in how the text is composed.
I've tested this a few times and ran into minimal issues, but if you want to ensure that your text comes through as intended, you're better off composing your own multipart/alternative MIME message and passing that to MailGun using the /messages.mime API endpoint.

How to parse multipart/form-data forwarded by Mailgun API on AWS Lambda?

Here is what I am trying to achieve: Users will be able to email me at test#myDomain.com which is integrated with the Mailgun service. Based off a rule I'll have set Mailgun will forward this email as a POST request to https:url-to-my-lambda-function.amazonaws.com/email. I then receive this POST request in Lambda, parse it, then grab and use the html from the email for further work.
The issue I am running into is that Mailgun sends their POSTs not as JSON but as a multipart/form-data. I have not been able to find a way to parse this content type and grab the email html. Here is a sample forwarded email from Mailgun (note that technically mailgun sends along attachments too, but all I care about is the stripped-html field).
Also note that I am working with the Serverless framework and need to write this function in either Python or Node.js.
Things I have tried to do to parse the POST request:
Tried using the parse-multipart npm library, but was unable to get it to work I think because I couldn't find the boundary string. This might still be a tenable solution.
Tried let body = new String(decodeURIComponent(event.body)); , to put the data into a string and decode it because it seemed to be coming in URL encoded. Then I was using regex to find and pull out the stripped-html that I wanted. However, I think the URL decoding wasn't properly working because it was converting spaces into pluses. See the block below as an example of what I got:
<td+align="center"+valign="top"+id="m_-6910385412628668961m_-3845437051063103019m_-3682438291175620773bodyCell"+style="padding-bottom:40px;height:100%;margin:0;padding:0;width:100%;border-top:0">\n++++++++++++++++++++++++\n++++++++++++++++++++++++<table+border="0"+cellpadding="0"+cellspacing="0"+width="100%"+style="border-collapse:collapse">\n++++++++++++++++++++++++++++<tbody><tr>\n++++++++++++++++++++++++++++++++<td+align="center"+valign="top">\n++++++++++++++++++++++++++++++++++++\n++++++++++++++++++++++++++++++++++++<table+border="0"+cellpadding="0"+cellspacing="0"+width="100%"+id="m_-6910385412628668961m_-3845437051063103019m_-3682438291175620773templatePreheader"+style="border-collapse:collapse;background-color:#eaeaea;border-top:0;border-bottom:1px+solid+#d0d0d0">\n++++++++++++++++++++++++++++++++++++++++<tbody><tr>\n++++++++++++++++++++++++++++++++++++++++\t<td+align="center"+valign="top">\n++++++++++++++++++++++++++++++++++++++++++++++++<table+border="0"+cellpadding="0"+cellspacing="0"+width="600"+style="border-collapse:collapse">
I have also tried using libraries like busboy to decode the multipart/form-data but have had issues with getting them working in Lambda because they work off of requests.
How can I parse this POST request? Is this even possible?
You should probably consider using a module designed to parse multipart form data such as https://www.npmjs.com/package/parse-formdata.

Postfix header_check for multiple recipients

I have some development and test servers, that are only used for internal testing and development, but they often use setup from live solutions, including email addresses of customers and customers customers.
I would like to avoid the dev-solutions sending emails to customers, but allow them to send emails to developers, so that they can test the email part of the solution. I have tried a header_checks rule like this:
/^To:.*#(myowndomaion.com|myotherdomain.com|athirddomain.net)/ DUNNO
/^To:.*#/ REDIRECT mytestemail#myowndomain.com
And this works fine. If I send an email to test#gmail.com it will be forwarded to mytestemail#myowndomain.com and not be sent to test#gmail.com. But if I however send an email to myuser#myowndomain.comit will be send straight to the correct user. That is all fine.
The problem arises if I send emails to several email addresses!
So, if I send an email to test#gmail.com and myuser#myowndomain.com in the same email, they will both get the email (which they should not). The order does not matter, both will get emails in both cases.
So, does anyone have a better regex or some other better way to solve this?
Note: We use Postfix on Debian. (pretty standard Debian 6 and Debian 8)

Django Email backend (keeps sending email from incorrect "sender")

I have several instances in my project where I attempt to send an email within a Django view.
I want to be able to hardcode the email sender within the view. When I try to do so, though, it continues to send the emails from the default account specified in my settings file.
Here is an example:
if testform.is_valid():
beta=testform.save()
subject="Hi Beta Tester"
sender="correct#email.com"
recipient=[testform.cleaned_data['email']]
text=loader.get_template('registration/beta_email.txt')
html=loader.get_template('registration/beta_email.html')
site_name='mysite'
d=Context({'site_name':site_name})
text_content=text.render(d)
html_content=html.render(d)
#This sends two mail versions, plain text and html
msg=EmailMultiAlternatives(subject, text_content, sender, recipient)
msg.attach_alternative(html_content, "text/html")
msg.send()
return HttpResponseRedirect('/splash/')
I thought that I could send specify the sender argument explicitly here. And, yet, when I test it, the email is being sent from the address listed in my settings file, configured as the following:
EMAIL_USE_TLS=True
EMAIL_HOST='smtp.gmail.com'
EMAIL_HOST_USER='wrong#email.com'
EMAIL_HOST_PASSWORD='private'
DEFAULT_FROM_EMAIL='wrong#email.com'
Do I just have to remove the DEFAULT_FROM_EMAIL constant to make it work? I tried doing so and it seems to be working but I'm confused. In the Django documentation, it suggests that setting sender in the view should override the DEFAULT.
I've finally figured out the issue here. Unfortunately, gmail rewrites the from and the
envelope on authenticated smtp.
If you want to get around that, you have to use a third party mail server (which doesn't act like such a prissy) and then send mail to gmail users.
For the sender e-mail try putting it in < > and you can add a name:
sender = "Formal Name <correct#email.com>"
that is exactly the syntax I have in my e-mail sending view and it works.
There really shouldn't be a reason that adding the name to it would change how it's sending, but it may be worth trying and perhaps you want an easily readable name anyway.

CFMail with catchall email addresses

I can't believe I've never noticed this before, but it seems that CFMail won't send to an email address that isn't explicitly set up on the destination mailserver.
This means that if I'm using 'info#somedomainorother.com' and have that set up to catch all email on the domain, CFMail won't send to 'test#somedomainorother.com'.
This causes a massive amount of problems for me, as I'm using CFMail to send out order confirmations, member activations and all manner of other bits and pieces.
Whatever your views on using catchall addresses, it can't be denied that people do use them So, in any case that a user enters a made-up address into one of my sites, they won't receive their email.
There must, simply MUST be a way around this - can anyone help?
For refernece, the message that appears in the logs when sending to a catchall address is 'Invalid Addresses'.
EDIT: Here's the CFMail syntax I'm using -
<cfmail to="#Arguments.sEmailAddress#" from="#Application.sAppEmailAddress#" subject="Stock reminder confirmation: #Local.qGetProductDetails.sProductName# - #Application.sCompanyName#" type="HTML" server="#Application.sAppEmailServer#" username="#Application.sAppEmailAddress#" password="#Application.sAppEmailPassword#">
Translates into:
<cfmail to="thisisatest#somedomainorother.com" from="application#mydomainname.com" subject="Stock reminder confirmation: Some product - My Company" type="HTML" server="mail.mydomainname.com" username="application#mydomainname.com" password="XXXXXX">
All works fine for info#somedomainorother.com but not for randombunchofcharacters#somedomainorother.com.
Important to note of course, that the catch-all is working correctly in all other respects, test emails from mail clients work perfectly.
Its not ColdFusion that cares about email validity, its the SMTP server. CF only cares about well formed email addresses.
If you initiated a telnet session to your mail server and tried to use the same address, I'm sure it would have the same result.
Debugging tips for SMTP Connectivity:
http://www.talkingtree.com/blog/index.cfm/2004/11/22/debug-smtp
Can I see your CFMAIL tag setup? CFMAIL doesn't care as long as the email address is properly formatted.
Urgh!
Turns out it was an issue with the server. For some reason, catchall email accounts serverwide had stopped working properly. After an email to my hosting provider, it's all working fine with no code changes.
They're somewhat cagey as to what caused the issue, and I was still able to use an email client to send mail out to the addresses...
Thanks for the help in any case. ;)