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.
Related
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.
I've tried with no conclusions to resend emails with Python.
Once I've logged in SMTP and IMAP with TLS, this is what I have written:
status, data = self._imapserver.fetch(id, "(RFC822)")
email_data = data[0][1]
# create a Message instance from the email data
message = email.message_from_string(email_data)
# replace headers (could do other processing here)
message.replace_header("From", 'blablabla#bliblibli.com')
message.replace_header("To", 'blobloblo#blublublu.com')
self._smtpserver.sendmail('blablabla#bliblibli.com', 'blobloblo#blublublu.com', message.as_string())
But the problem is that the variable data doesn't catch the information from the email, even if the ID is the one I need.
It tells me:
b'The specified message set is invalid.'
How can I transfer an email with Python?
Like the error message says, whatever you have in id is invalid. We don't know what you put there, so all we can tell you is what's already in the error message.
(Also, probably don't use id as a variable name, as you will shadow the built-in function with the same name.)
There are additional bugs further on in your code; you need to use message_from_bytes if you want to parse it, though there is really no need to replace the headers just to resend it.
status, data = self._imapserver.fetch(correct_id, "(RFC822)")
self._smtpserver.sendmail('blablabla#bliblibli.com', 'blobloblo#blublublu.com', data[0][1])
If you want to parse the message, you should perhaps add a policy argument; this selects the modern EmailMessage API which was introduced in Python 3.6.
from email.policy import default
...
message = email.message_from_bytes(data[0][1], policy=default)
message["From"] = "blablabla#bliblibli.com"
message["To"] = "blobloblo#blublublu.com"
self._smtpserver.send_message(message)
The send_message method is an addition to the new API. If the message could contain other recipient headers like Cc:, Bcc: etc, perhaps using the good old sendmail method would be better, as it ignores the message's headers entirely.
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)
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/
I want to save the MessageID of a sent email, so I can later use it in a References: header to facilitate threading.
I see in root/django/trunk/django/core/mail.py (line ~55) where the MessageID is created.
I'm trying to think of the best way to collect this value, other than just copy/pasting into a new backend module and returning it. Maybe that is the best way?
Ok, I see I was browsing tragically old code. I should be able to call django.core.mail.message.make_msgid() and populate the header myself before calling send.
Not all backends actually support asserting a message id (for e.g. SES sets it's own message ID and returns it in it's send response). You can actually pull out the returned/generated/set message id if you use the newer (circa 1.1?) EmailMessage class you can extract the returned message ID from the instance once you call .send(), e.g.:
e=EmailMessage(
subject,
content,
from_email,
recipient_list,
headers = headers,
)
e.send()
message_id = e.extra_headers.get('Message-Id',None)