I have created a simple ASP.NET Web API app that receives parsed emails from SendGrid. Works well on my machine using a secure tunnel with ngrok. The parsed content of emails is posted to the locally hosted app.
However, when I deploy this app to Azure it does not work. I tried to use both HTTP and HTTPS for the callback URL in SendGrid, but emails are not processed. In the Activity page in SendGrid there is no entry for a Parsed email. And I get back a delivery failure email, for the email that should have been handled by SendGrid.
The response was: 550 no mailbox by that name is currently available
I know the app is reachable because I can do successful HTTP requests to other resources, from the browser or other tools.
Is there something that I might have missed? Some additional configuration, either for the app or in SendGrid?
The short answer is this:
If you use CloudFlare for your DNS, it is highly likely that CloudFlare is stopping the inbound parse posts from SendGrid.
Review your Firewall Event Log in CloudFlare (under the Firewall Tab) and see if your Web API "Host" is appearing there.
If so, what you'll need to do is whitelist the IP Address range that SendGrid uses to send posts for the inbound parse.
Their current IP range for the inbound parse as of today is 167.89.117.0/24 (basically of the IP address from 167.89.117.0 to 167.89.117.255).
Hope this helps you or someone else with this same issue/root cause.
Related
I have running Azure function App(in python language), for business requirements need to send emails from function app.
for that, I wrote a python function
from email.message import EmailMessage
import smtplib
def send_mail():
# message to be sent
msg = EmailMessage()
msg.set_content('Test content')
msg['Subject'] = 'Test'
msg['From'] = "test#hotmail.com"
msg['To'] = ["test#hotmail.com"]
# creates SMTP session
s = smtplib.SMTP('smtp-mail.outlook.com', 587)
s.ehlo()
# start TLS for security
s.starttls()
# Authentication
s.login("test#hotmail.com", "password-to-login")
# sending the mail
s.send_message(msg)
# terminating the session
s.quit()
return
Above block of code working fine in local machine. if I move the same code to Azure Function App it's not working.
How do I make it work on the Azure function app?
How do I send email from Gmail in Azure Function App?
Sending outbound e-mail to external domains (such as outlook.com, gmail.com, etc) directly from an e-mail server hosted in Azure compute services is not supported due to the elastic nature of public cloud service IPs and the potential for abuse. As such, the Azure compute IP address blocks are added to public block lists (such as the Spamhaus PBL). There are no exceptions to this policy.
Since we do not support running and smtp server from our platform this should not affect us.
The only way to use EMAIL functionality as of now on Azure Web App is via an SMTP relay. A third party service such as SendGrid provides these type of services.
In the Azure Web Apps architecture the actual Web Apps sit behind common Front-Ends which are shared by all the sites hosted on that Data Centre.
There is a possibility that one of the site hosted on that datacenter is sending SPAM emails and this could have the IP address to be blacklisted by the MAIL Servers. So the e-mails sent from that address will be rejected or considered as SPAM by mail servers.
This limitation exists in case of VM or Cloud Services too. Azure uses a pool of IP Address, and these addresses are reused. That means you could get an IP Address which has already been blacklisted, as someone was sending SPAM from that address before and hence your emails would be rejected or considered as SPAM by mail servers.
This is a common scenario in Cloud and it is typically recommended to use an external Mail Service provider like SendGrid for messaging.
SendGrid related articles:
How to Send Email Using SendGrid with Azure: https://azure.microsoft.com/en-in/documentation/articles/sendgrid-dotnet-how-to-send-email/
I would suggest you to use some 3rd party email service such as SendGrid/Twillio
You can add SendGrid output binding to you Python Azure Function. The binding in function.json would look something like here
Here is an example
Below is the actual procedure for getting sendgrid working manually with python for azure functions. This is not the optimal way since azure has it's own in house solution that may be superior to this, but this is a quick and dirty way to get it working.
run pip install sendgrid on your local machine.
In your code include:
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
Sending The Email: (keep in mind this is NOT SECURE since the API Key is Exposed, but this is quick way to get something working.)
message = Mail(
from_email='yourfromemail#gmail.com',
to_emails='toemail#gmail.com',
subject='Email Subject Line Here',
html_content='<strong>HTML CONTENT HERE</strong>')
try:
sg = SendGridAPIClient('YOUR API KEY HERE')
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
except Exception as e:
raise Exception(str(e) + ' -> Error Reported')
The last step is if you want this to work on the actual azure function server you need to add this to requirements.txt
sendgrid
Note that sendgrid is free up to 25,000 emails so it works perfect for most situations. You just need to setup your API key on there website, just follow their instructions, it was simple for me to do and took about 5 minutes to create a 'user' and an API key associated with it.
Also note that I was able to send from my GMAIL account when I did this with sendgrid. HOWEVER, also note that it will go to your spam folder constantly because google can never truly verify it was you who sent from your gmail, so just keep this flaw in mind. In my case since I'm doing just testing work this doesn't matter, but it may be a problem for production work.
There is a hack that I'm about to implement. In my case I don't really care about the subject, attachments etc. It's an information email.
Add a log message in your code with email body in a parsable form.
Create a log based alert rule matching the log.
When Azure Monitor sees this log, it'll send an alert to the email address(es) configured in the alert. Email can include contents of log message.
As mentioned this is very restrictive:
can't fully control subject line
can't control the recipients programatically (easily at least)
can't attach files
I am using the SendGrid for receiving the emails from my domain (example.com). I have configured all the steps from the mentioned link Sendgrid Inbound Parse Webhook.
I have added all the name records(MX records and CNAMES) in the GoDaddy DNS records against my domain.
The issue is when I send an email to hello#example.com. When an email is sent to this email-id there is no mail delivery failure report. There is no any statistics for the SendGird console about the webhook got triggered.
I am not able to figure out what went wrong in this process. As emails in the sendgrid webhook are not received.
I think they are lost in between.
I found the documentation to be insufficient in this area. You need to send to the subdomain, listed in your MX record, which redirects mail to sendgrid.
For example, if you add a MX record for email.example.com, you need to send the email to user#email.example.com.
One of the best ways to test if a 3rd party Web API post is being triggered or not is by using a tool that receives posts and provides visibility to the data sent along with the post (e.g. Headers, parameters, and the related data in json, text, etc).
One of the tools that I have used to test if a post is being triggered or not is offered by: https://requestbin.fullcontact.com/. Take these steps to set-up your testing environment:
(note: I am not associated with the requestbin.fullcontact.com resource - I am just an enthusiastic fan of this very useful service).
Go to requestbin and "Create a RequestBin". This will create your own unique requestbin URL. (e.g. https://requestbin.fullcontact.com/xxxxx)
Copy this URL, and paste it into your SendGrid Inbound Parse "Destination URL".
Keep your testing environment simple initially by NOT checking the "Additional Options" (Check incoming emails for spam & Post the raw...).
Be sure you do not enter a 'Subdomain' in the SendGrid Inbound Parse "Receiving Domain" unless you are expecting users to use the subdomain as part of your email address.
Re: #3, same applies to your DNS at GoDaddy. Your email should also not reflect a 'subdomain' as part of your MX record (e.g. you should not use mail.example.com).
Click "Add".
Now, send an email to your domain (e.g. info#example.com).
Check your requestbin to see if a post was made by using your unique requestbin URL, appended with "?inspect" (e.g. https://requestbin.fullcontact.com/xxxxx?inspect).
Result: You should see post information when viewing your 'inspect' URL.
Using this first step of a diagnostic process to test your usage of SendGrid's Inbound Parse should help expose potential problems in your configuration (e.g. DNS set up would be the next area to look at if no post data is being received in the requestbin inspect URL). Good luck.
I created application and using e-signature using Docusign.
I want to get Envelop status updates using Docusign Webhook through eventNotification.
I hosted my website into public accessible environment also enabled ssl here is
my webhook url - https://103.231.46.2:10167/api/webhook
As per the Docusign feature, when Envelop status gets changed then webhook try to post some data into webhook url but it's getting failed and I can see that failed post request at Docusign -> connect -> failure tab. here is screen shot enter image description here
I have check with with my network team, No firewall is blocking. and also tried to post some data using fiddler from other network it is working fine. then I am wondering, why Docusign webhook is unable to post data into my webhook url.
I am unable to access the URL https://103.231.46.2:10167/api/webhook
Looks like it is not publicly accessible.
Use a tool like GeoPeeker and make sure your URL is indeed publicly accessible.
As CodingDawg suggested, it should either be publicly accessible or becasue of security concern you don't want it to be publicly accessible then you have to work with your Network/Firewall team to whitelist DocuSign IPs. You can find DocuSign IPs at
https://trust.docusign.com/en-us/trust-certifications/whitelist/
I would like to parse inbound emails in a Node.js app hosted on Digital Ocean. I want to create an email address for my app's domain that can post to a webhook. How do I create an email address like name#example.com (or name#subdomain.example.com)? I am trying to avoid creating one through a third party because I just need to quickly parse the incoming content, and don't need all the functionality of regular email.
For parsing, I am using Mailin.io, and following Mailin's documentation I have changed my Domain records on Digital Ocean as follows:
MX 10 subdomain.example.com
A subdomain [ip address of my droplet]
I have the webhook set up at http://www.example.com/webhook, and if I post using curl, I get the expected response, but I can't figure out how to post to the webhook via email.
Am I going about this the right way?
How do I go about receiving emails in SendGrid parsing them and sending the output to Azure. Some specific questions I have:
what is the hostname I should specify on the SendGrid Inbound Parse screen?
does it have to do anything about the server domain I receive emails from? Do I specify the Azure hostname here?
Which URL should I specify? is it the Azure URL I want to forward the email contents to?
Any help is appreciated