django sending email (delivery report) - python

I'm a beginner who is trying to use "Django" to send mail to multiple recipients.
How could I get a delivery report that tells me that: "the mail delivered to recipients a,b,c and d".
"The delivery failed to recipient (e) because his mail box is full".
The delivery failed to recipient (f) because your message considered as spam".

The return value of send_mail() is a boolean that tells whether or not the message was successfully sent.
You can write a function that iterates through the list of recipients, calls send_mail(), appends the successful deliveries to one list, and appends the unsuccessful recipients to another. Then you can write messages using that information. Something like this:
recipients = [ ... ] # list of people you're sending the email to
successful_recipients = []
unsuccessful_recipients = []
for recipient in recipients:
if send_mail( ... ):
successful_recipients.append(recipient)
else:
unsuccessful_recipients.append(recipient)
It may be difficult/impossible to get the cause of failure, because Django isn't providing you with that information.
https://docs.djangoproject.com/en/1.11/topics/email/

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.

Get list of emails (Sender's Email, Subject and Body) between given dates through Gmail API in Python

I am working on a project that requires a JSON file response through Gmail API which contains a list of all the emails (Sender's Info, Subject, and Body) between given dates. Then that JSON file will be processed as needed.
I'm not sure how to generate a request that could provide me with the required JSON file using Gmail API through Python.
I'm a beginner, Please help me.
Assuming that you have gone through OAuth and built the service (if not, check the quickstart), you have to do the following:
Call users.messages.list, using the parameter q to filter your messages by date. This q uses the same syntax as in Gmail UI: see Search operators you can use with Gmail. For example, if you wanted to retrieve your messages from the first 9 months in 2020, you would do this:
user_id = "me"
searchFilter = "after:2020/01/01 before:2020/10/01"
messages = service.users().messages().list(userId=user_id, q=searchFilter).execute()
When listing messages, only the id and the threadId are populated. In order to get the full message resource for all these messages, you should loop through them and call users.messages.get for each message, using its id:
for message in messages["messages"]:
messageId = message["id"]
message = service.users().messages().get(userId=user_id, id=messageId).execute()
For each of these retrieved messages, you want to get the subject, body and sender's email. Subject and sender's email can be found on the message headers. You should loop through the headers and look for one named Subject and another one named From. See these answers for more info: Python: how to get the subject of an email from gmail API, Get sender email from gmail-api. Regarding the body, it is to be found at ["payload"]["body"]. See this answer: How to retrieve the whole message body using Gmail API (python).
Reference:
Searching for Messages
REST Resource: users.messages
list(userId=*, labelIds=None, q=None, pageToken=None, maxResults=None, includeSpamTrash=None)
get(userId=, id=, format=None, metadataHeaders=None)

How do I know if a envelope have reach the recipient email?

I am sending envelopes from a template to some recipients, and getting the envelope id like this:
while i < len(excel_signers):
signers = {"signer_name": excel_signers[i][2], "signer_email": excel_signers[i][3], "cc_email": "emailcc#gmail.com", "cc_name": "Responsable prueba"}
# to the template
signer = TemplateRole(email=signers["signer_email"], name=signers["signer_name"], role_name="signer")
# Create a cc template role.
cc = TemplateRole(email=signers["cc_email"], name=signers["cc_name"], role_name="cc")
envelope_definition = EnvelopeDefinition(template_id=args["template_id"], template_roles=[signer, cc])
envelope_definition.status = args["status"]
results = envelope_api.create_envelope(args['account_id'], envelope_definition=envelope_definition)
envelope_id = results.envelope_id
excel_signers[i] = np.append(excel_signers[i], [envelope_id]).tolist()
i += 1
but then I want to know if the envelope was correctly delivered, I tried using list_status_change but it shows me "sent" in all of them which is the status I set when I send the envelope. but in the docusign's dashboard it shows "failure", how can I know when an email is not delivered?
To check the status of the recipients in your envelope use the GetRecipientStatus endpoint of the eSignature API
Since you're using Python, you can use the Python SDK's method list_recipients()
It retrieves a lot of data about the recipients in your envelope, including their status.
https://developers.docusign.com/esign-rest-api/guides/concepts/recipients
delivered status means that the email to that recipient was delivered.

How to get message-id of email reply exchangelib

I need to get the message id of the email sent with exchangelib. I can't find documentation on how to get it.
item = account.inbox.filter(message_id__in=[message_id]).only( 'subject',
'id',
'message_id',
'sender',
'cc_recipients',
'to_recipients',
'references')[0]
item.reply(subject='Re: '+ item.subject,
to_recipients=[item.sender.email_address],
body='I agree',)
If I get the references item.references I get as a result None
Sent messages are not stored on the Exchange server unless you send it to a recipient located on the same Exchange server or you explicitly choose to save it to e.g. your sent folder.
To get the message ID, you need to get hold of the Message that was sent. Then you can access the message_id on that item.

How to receive mail using python

I would like to receive email using python. So far I have been able to get the subject but not the body. Here is the code I have been using:
import poplib
from email import parser
pop_conn = poplib.POP3_SSL('pop.gmail.com')
pop_conn.user('myusername')
pop_conn.pass_('mypassword')
#Get messages from server:
messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
# Concat message pieces:
messages = ["\n".join(mssg[1]) for mssg in messages]
#Parse message intom an email object:
messages = [parser.Parser().parsestr(mssg) for mssg in messages]
for message in messages:
print message['subject']
print message['body']
pop_conn.quit()
My issue is that when I run this code it properly returns the Subject but not the body. So if I send an email with the subject "Tester" and the body "This is a test message" it looks like this in IDLE.
>>>>Tester >>>>None
So it appears to be accurately assessing the subject but not the body, I think it is in the parsing method right? The issue is that I don't know enough about these libraries to figure out how to change it so that it returns both a subject and a body.
The object message does not have a body, you will need to parse the multiple parts, like this:
for part in message.walk():
if part.get_content_type():
body = part.get_payload(decode=True)
The walk() function iterates depth-first through the parts of the email, and you are looking for the parts that have a content-type. The content types can be either text/plain or text/html, and sometimes one e-mail can contain both (if the message content_type is set to multipart/alternative).
The email parser returns an email.message.Message object, which does not contain a body key, as you'll see if you run
print message.keys()
What you want is the get_payload() method:
for message in messages:
print message['subject']
print message.get_payload()
pop_conn.quit()
But this gets complicated when it comes to multi-part messages; get_payload() returns a list of parts, each of which is a Message object. You can get a particular part of the multipart message by using get_payload(i), which returns the ith part, raises an IndexError if i is out of range, or raises a TypeError if the message is not multipart.
As Gustavo Costa De Oliveir points out, you can use the walk() method to get the parts in order -- it does a depth-first traversal of the parts and subparts of the message.
There's more about the email.parser module at http://docs.python.org/library/email.message.html#email.message.Message.
it also good return data in correct encoding in message contains some multilingual content
charset = part.get_content_charset()
content = part.get_payload(decode=True)
content = content.decode(charset).encode('utf-8')
Here is how I solved the problem using python 3 new capabilities:
import imaplib
import email
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login(username, password)
mail.select(readonly=True) # refresh inbox
status, message_ids = mail.search(None, 'ALL') # get all emails
for message_id in message_ids[0].split(): # returns all message ids
# for every id get the actual email
status, message_data = mail.fetch(message_id, '(RFC822)')
actual_message = email.message_from_bytes(message_data[0][1])
# extract the needed fields
email_date = actual_message["Date"]
subject = actual_message["Subject"]
message_body = get_message_body(actual_message)
Now get_message_body is actually pretty tricky due to MIME format. I used the function suggested in this answer.
This particular example works with Gmail, but IMAP is a standard protocol, so it should work for other email providers as well, possibly with minor changes.
if u want to use IMAP4. Use outlook python library, download here : https://github.com/awangga/outlook
to retrieve unread email from your inbox :
import outlook
mail = outlook.Outlook()
mail.login('emailaccount#live.com','yourpassword')
mail.inbox()
print mail.unread()
to retrive email element :
print mail.mailbody()
print mail.mailsubject()
print mail.mailfrom()
print mail.mailto()

Categories