Emailing script - reply to message Gmail conversation - python

I have setup an email for my domain to forward emails to a my personal email. I'm writing a simple mailing script to reply to some emails i receive as forwarded email using the domain's email id. I'm using Sendgrid to do that. Whenever i send a response back though, it appears as a new conversation in Gmail inbox. I'm not sure what all params I need to set to make the conversation appear as a single bundle.
here's my sendgrid code:
message = sendgrid.Mail()
message.add_to(email)
message.set_from(my_name + " <" + my_email + ">")
message.set_subject(subject)
message.set_html(body.replace('\n', '<br />'))
message.set_text(body)
status, msg = sg.send(message)
I use the subject as: "Re: " +
and use body from old conversation as:
On Fri, Aug 28, 2015 at 1:00 PM, senders_name <sender's email> wrote:
>
> ...

Thanks to #FSQ suggestion.I was able to make the email conversation attach together. I look up the Message Id from:
Gmail message > right side dropdown > show original
You should see something like:
In-Reply-To: <14f75e5a9b1.3f4.b2d01d#ismtpd-057>
Message-ID: <14f760957fc.5888.11ab5eb#ismtpd-085>
This is your message id. Send this in the header of email as:
message.set_headers({'In-Reply-To': '<14f760957fc.5888.11ab5eb#ismtpd-085>'})
And it works!

Related

I am trying to make a email chatbot but it spams how could i fix this?

I am trying to build a email chatbot but it has this bug where after it sends the first message, and then gets a response it keeps spamming the answered to the response it got until it gets another response which then it repeats again I was thinking to solve this I should use a variable which detects emails and later down the code a condition that responds only if a email is received, does anyone have any idea on how I could fix this? Thanks
def receive_email():
try:
mail = imaplib.IMAP4_SSL("smtp.gmail.com")
mail.login(email_address, email_password)
mail.select('inbox')
#searches inbox
status, data = mail.search(None, 'Recent')
mail_ids = data[0].split()
latest_email_id = mail_ids[-1]
status, data = mail.fetch(latest_email_id, '(RFC822)')
#gets message
for response_part in data:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
sender = msg['from']
subject = msg['subject']
if msg.is_multipart():
for part in msg.get_payload():
if part.get_content_type() == 'text/plain':
return part.get_payload()
message = msg.get_payload()
return message,
except Exception as e:
print("Error: ", e)
print("Could not receive email")
return None, None
This is the usual problem for an email autoresponder, if I understand you correctly, and RFC 3834 offers good advice.
Since answers should be self-contained I offer a summary:
Add the Auto-Submitted: auto-replied header field on your outgoing messages. Any value other than no will prevent well-written autoresponders from replying to your outgoing messages.
Set the \answered flag on the message you reply to, immediately before you send the reply.
Change the search key from recent to unanswered not header "auto-submitted" "". unanswered means that the search won't match the messages on which you set the \answered flag, not header "auto-submitted" "" means that you'll not match messages that contain any auto-submitted header field.
Direct your replies to the address in return-path or sender, not the one in from. This is a matter of convention. Auto-submitted mail will often have a special return-path that points to an address that never sends any autoreply.
You may also extend the search key with more details from RFC 3834. The one I suggest should work, but not header "precedence" "junk" will for example prevent your code from replying to a bit of autogenerated mail. Sendgrid and its friends also add header fields you may want to look for and exclude.
If the incoming message has headers like this (use the "view headers" function of most mail readers to see it):
From: example#example.com
Subject: Weekend
To: srtai22#gmail.com
Message-id: <56451182ae7a62978cd6f6ff06dd21e0#example.com>
Then your reply should have headers like this:
Return-Path: <>
From: srtai22#gmail.com
To: example#example.com
Auto-Submitted: auto-replied
Subject: Auto: Weekend
References: <56451182ae7a62978cd6f6ff06dd21e0#example.com>
There'll be many more fields in both, of course. Your reply's return-path says that nothing should respond automatically, From and To are as expected, auto-submitted specifies what sort of response this is, subject doesn't matter very much but this one's polite and well-behaved, and finally references links to the original message.

using python with Sendgrid on Heroku

I am trying to use Sendgrid to send the email on Heroku, but I get the output that I not seen before. I saw the documentation and it says that the helper library supports few versions of python until 3.8 but mine version is 3.9. Is it this cause me get this error?
**Here is my code: **
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
message = Mail(
from_email='hesheitaliabu#gmail.com',
to_emails='hesheitaliabu#gmail.com',
subject='Sending with Twilio SendGrid is Fun',
html_content='<strong>and easy to do anywhere, even with Python</strong>')
try:
sg = SendGridAPIClient('SG.API_KEY')
response = sg.send(message)
# print(response.status_code)
print(response.body)
print(response.headers)
except Exception as e:
print(e.message)
I get an error:
b''
Server: nginx
Date: Mon, 05 Sep 2022 03:53:19 GMT
Content-Length: 0
Connection: close
X-Message-Id: Y19VjElqRe2byQxJrkJUeg
Access-Control-Allow-Origin: https://sendgrid.api-docs.io
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
Access-Control-Max-Age: 600
X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
Strict-Transport-Security: max-age=600; includeSubDomains
As we've worked out in the comments, the emails are in fact sending successfully. The message you see logged are the response headers from the API because of these lines:
sg = SendGridAPIClient('SG.API_KEY')
response = sg.send(message)
print(response.body)
print(response.headers)
In this case the message is sent and then the program prints out the response body (which is empty for a successfully sent message) and then the response headers, which you are seeing. This is not an error.
Instead, we have worked out that your email is being sent to the spam inbox.
This is a bit harder to fix as it relies on email inbox providers. However I need to point out one thing that's going to make this very difficult to start with.
Your example shows that you are sending the email from your Gmail address to the same Gmail address. Because of this, Gmail knows it did not send the email from that Gmail address and will instantly treat it as suspicious. You are effectively spoofing your own email address. If you have set up single sender verification with SendGrid for that address, all that does is tell SendGrid that you own the email address and aren't trying to spoof just anyone's email address. This is good for testing that you can use the API to send emails.
However, if you want emails to arrive in inboxes and not the spam inbox then your best bet is to send from a domain that you own that you can authenticate with SendGrid. When you authenticate a domain it sets a number of things like SPF and DKIM that show the inboxes you are sending to that you are the rightful owner of the domain and are authenticated to send emails from the domain. This means you are more likely to arrive in the inbox and not spam.
There is much more to pay attention to to ensure your emails stay out of spam, but in this case, I would start with domain authentication.

flask_mail I get TWO different FROM lines mail header

I'm using flask_mail configured to use gmail smtp server. It sends mail fine except all mail looks it is coming from the gmail smtp user name and NOT from what I set in the 'sender' argument of the mail.send_message(...) command. When I look at the source of the generate emails I see 2 different FROM addresses. How can I change this to show my desired 'from'?
mail.send_message(subject='subject line',
sender='my_from_email#gmail.com',
recipients=['my_to_email#gmail.com'],
bcc=['bcc_email#gmail.com'],
reply_to='my_from_email#gmail.com')
snip-it of header looks like...
...
From: my_smtp_user_name#gmail.com
X-Google-Original-From: my_from_email#gmail.com
Content-Type: multipart/mixed; boundary="===============8405132704319078372=="
MIME-Version: 1.0
...
TLDR: gmail smtp server is preventing email spoofing.
see: https://github.com/gophish/gophish/issues/1311
to fix:
log into your my_smtp_user_name#gmail.com account in Gmail and set up sending email as my_from_email#gmail.com there first. Once your account is allowed and authenticated as allowed to send email as your other account your headers should stop being re-writen.
see : https://support.google.com/mail/answer/22370?hl=en

Read outlook 365 email using python and get sender email (exchange or SMTP)

I have a python script to read emails from the inbox folder in outlook, and retrive the email id of the sender.
outlook = win32com.client.Dispatch(
"Outlook.Application").GetNamespace("MAPI")
print("Reading Mails")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
for msg in messages:
print(msg.SenderEmailAddress)
prints '/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBONPDLT)/cn=Recipients/cn=80cf94566sdfhve819ddaede72dc842-Sender Name'
instead of a email ID that the script can work on.
The printed statement is actually a Exchange address. This returned when the email is received from within a company. The best way to handle this is to identify if the SenderEmailType is Exchange.
if (msg.SenderEmailType = "EX"):
print(msg.Sender.GetExchangeUser().PrimarySmtpAddress)
else #email type SMTP
print(msg.SenderEmailAddress)

Can I get the incoming message by using Mailgun?

A use Mailgun to send b a email, after b receive the email and reply to a.If I want to track the email coming from b, How I can get the email?
Here is the code:
1.sendmail.py
from smtplib import SMTP
import requests
login_name = "postmaster#zzb.mailgun.org"
password = "********"
def send_message_via_smtp():
smtp = SMTP("smtp.mailgun.org", 587)
smtp.login(login_name, password)
smtp.sendmail("zebozhuang#163.com","348284770#qq.com", "Subject:mailgun test \n\n just for test.\n\n")
smtp.quit()
if __name__=="__main__":
send_message_via_smtp()
2.create_route.py
import requests
from werkzeug.datastructures import MultiDict
def create_route():
return requests.post(
"https://api.mailgun.net/v2/routes",
auth=("api", "key-9c4-t2q6fouilngjummvtv1rge7t00f2"),
data=MultiDict([("priority", 1),
("description", "Sample route"),
("expression", "match_recipient('.*#qq.com')"),
("action", "forward('qiyazhuang#gmail.com')"),
("action", "stop()")])
)
I create the route and I run the script sendmail.py.After someone who use email 348284770#qq.com reply to the other who use email zebozhuang#163.com, the Gmail
can not receive the message by using the Mailgun method 'forward'.
Could anyone tell me why?
Your messages are likely being delivered. Check the "Logs" tab of the Mailgun Control Panel.
Do you see any entries that look like this:
Routed: .*#qq.com -> qiyazhuang#gmail.com 'SUBJECT HERE'
The "Routed" prefix means that the message triggered a Route. If you're seeing this, and the next log entry is prefixed with "Delivered", the message is likely being delivered to Gmail without issue. Check your Gmail spam folder if you still don't see the messages in the inbox folder.
Disclaimer: I work for Mailgun Support. :)

Categories