How do I get all date related info from Outlook (Python, win32) - python

I'm trying to get date related info from messages that Python retrieves from Outlook but for some weird reason I cannot.
It is strange because I can obtain all info about sender, email body, subject, cc, bc, attachment etc. but when it comes to properties like SentOn, CreationTime or LastModificationTime IDLE just restarts (without any warnings, errors and exceptions).
Here is sample code:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case,
# the inbox. You can change that number to reference
# any other folder
messages = inbox.Items
message = messages.GetLast()
rec_time = message.CreationTime
body_content = message.body
subj_line = message.subject
print(rec_time, body_content, subj_line)
Output:
>>>
================= RESTART: C:/Users/XXXXX/Desktop/email.py =================
=============================== RESTART: Shell ===============================
>>>
And here outpoot when CreationTime is commented out:
Hi,
I really think that it is weird that win32 cannot read date info
Your sincerely,
Myself
Andrew
Python ver 3.7, Outlook 2016

Just tried your code and it worked with no issues. Assuming you have taken some general troubleshooting steps, i.e., restart your computer, etc. I would recommend the following steps:
Close all instances of outlook
Run Outlook in safe mode by pressing Windows Key + R and this dialog appears
input outlook /safe just as its shown in the image (above). Attempt to run your script (opening outlook in safe mode ensures no Outlook add-ins/configurations interfere)
If this doesn't work, I would recommend using a debugger (VSCode for example) and running line by line to see where your script is terminating. You shared a sample code, but if you have additional code that you didn't share - only assumptions can be made from my end, but you may have something causing this issue in your script.

Related

How to save created Python win32com msg file without displaying the email in the GUI?

I am using Pywin32 and win32com to programmatically create and save Outlook MSG files. (These are emails that will only ever be saved and never be sent across smtp.) I am able to create and save the emails, but it only works when the display() method is used. This is problematic because it creates and opens the actual Outlook email in the GUI.
When I comment out the display() method, the email message save method just runs forever and yields zero in the debug console and the email is neither created or saved.
The appearance of the Outlook emails in the GUI is not desirable as I will later programmatically create thousands of messages and cannot have them all opening in the GUI. (and having to close them!)
edit: I've done some research here display method and here .net mail class but have not found a way to suppress the GUI display of the email.
How can I create the emails to disk as msg files without them appearing in the Windows GUI as Outlook emails? Code as follows. Thank you.
import sys
import win32com.client as client
MSG_FOLDER_PATH = "d:\\Emails_Msg\\"
html_body = """
<div>
Test email 123
</div><br>
"""
recipient = "johndoe#foo.com"
cc = "janedoe#foo.com"
outlook = client.Dispatch("outlook.application")
message = outlook.CreateItem(0)
message.To = recipient
message.CC = cc
message.Subject = "foo1"
message.HTMLBody = html_body
# message display method
message.Display()
# save the message, only works if message.Display() runs
message_name = MSG_FOLDER_PATH + "foo.msg"
message.SaveAs(message_name)
The problem was that Outlook was not opened in the Windows Server. (The simple things at times!) Once it is opened, the display method is no longer needed and emails are written directly to disk.

Python unable to add message into Thunderbird Mbox

I am using python 2.7 on ubuntu 16.04.
I have been using python to read emails out of mbox files on my pc which were created by thunderbird. I now want to add messages into those mbox files. I shut down thunderbird and then I try to run my python script from the command line. The python script does not give me any error messages at all, but I do not see any new messages being added into the mbox file when I open up thunderbird.
I did look to see if I have a permissions problem. I changed the permissions of the mbox file in linux to: view content=anyone, change content=anyone, execute=anyone.
I run my python script in sudo mode.
Here is my code which I have tried:
mboxfile = "/home/jan/.thunderbird/gkzlvipz.default/ImapMail/mail.jan.info/INBOX"
print("opening: "+mboxfile)
mbox = mailbox.mbox(mboxfile)
mbox.lock()
try:
print("Trying:Begins")
msg = mailbox.mboxMessage()
msg.set_unixfrom('author Sat Feb 7 01:05:34 2020')
msg['From'] = 'info#jan.info'
msg['To'] = 'ljan#gmail.com'
msg['Subject'] = 'JL Python Sample message 1'
msg.set_payload('This is the body.\nFrom (should be escaped).\nThere are 3 lines.\n')
mbox.add(msg)
mbox.flush()
print("Trying:Ends")
except Exception as e:
# Just print(e) is cleaner and more likely what you want,
# but if you insist on printing message specifically whenever possible...
Print("Exception - FAILED")
if hasattr(e, 'message'):
print("Error 1: " + e.message)
else:
print("Error 2: " + e)
finally:
print("Finally")
mbox.unlock()
sys.exit("PYTHON ENDS: TEST EMAIL SEND FINISHED")
The output I get when I run the above script is:
*** PYTESTTHUNDERBIRD BEGINS ***
opening: /home/jan/.thunderbird/gkzlvipz.default/ImapMail/mail.jan.info/INBOX
Trying:Begins
Trying:Ends
Finally
PYTHON ENDS: TEST EMAIL SEND FINISHED
I don't know what I'm doing wrong and why I am not getting any error messages.
I'll be most grateful for any help.
Thanks.
The messages you added to the mbox file aren't showing up in Thunderbird because you didn't update the index (.msf) file for that folder.
In Thunderbird, right-click on the folder name and select "Properties". In the "General Information" tab, read the blurb next to the "[Repair Folder]" button. Then click the folder. This will cause Thunderbird to rebuild the index from scratch — including the messages you've added. (Assuming of course you didn't mess them up in the process.)

Refresh outlook inbox via python script

I'm trying to read emails from the outlook by means of win32com.
It's working well only if the email are displayed in outlook desktop application. But it could de something in the server, which could not been seen without manual outlook inbox refreshing. Is this any chance to update the outlook via command and get the latest emails from the server?
Currient code:
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
accounts= win32com.client.Dispatch("Outlook.Application").Session.Accounts;
inbox = outlook.Folders(accounts[0].DeliveryStore.DisplayName).Folders('Inbox')
Use Namespace.SendAndReceive - keep in mind that it is asynchronous, so you won't see the changes immediately.

Exim filter pipe script only working on last email - not current

This little combination is processing the second to most recent email coming in - not the most recent.
Here's the filter:
# Exim filter
save /srv/domain.com/bin/mail 660
pipe "/srv/domain.com/bin/sendToMailChimp.py"
It works - i.e. I can see it saving to the mail file and it does call the script.. so great! So far so good..
Here's the script:
#!/usr/bin/python
MAILBOX_DIR = '/srv/domain.com/mailboxes/enqace/mail'
import mailbox
import logging
import time
time.sleep(10)
logging.basicConfig(filename='/srv/domain.com/mailboxes/enqace/logging.log',level=logging.DEBUG)
inbox = mailbox.mbox(MAILBOX_DIR)
logging.info('Script called')
for key in inbox.iterkeys():
logging.info(key)
message = inbox[key]
subject = message['subject']
logging.info(subject)
logging.info('===FINISH====')
(Prints 0-6 along with subject lines of each)
I can tail the log. It runs on getting an email - but seems to parse the mail mbox and completes before getting to the most recent email (i.e. the last one). It then hits the last one (the most recent) the next time an email comes in. So if there were 6 mails already in the mail file the new one - the 7th - subject line doesn't come up in the log entry. Only when an 8th comes in..
Is the script in effect running to quickly - like before exim has had a chance to send to the mail file? If so whats the work around? Adding a sleep(10) doesn't seem to do anything as seen above..
UPDATE:
By pulling up a python prompt I can see that python does get the correct amount of keys (i.e. message num) when called outside of the pipe
MAILBOX_DIR = 'mail'
import mailbox
inbox = mailbox.mbox(MAILBOX_DIR)
for key in inbox.iterkeys():
print key
(Prints 0-7)

Outlook / Python : Open specific message at screen

I want to do a "simple" task in Outlook, with a Python script, but I'm usually in PHP and it's a little bit difficult for me.
Here is the task:
Open Outlook (it's ok for that)
Check a specific account, example: test#test.com
Open the last mail
I want to open the "real" message windows at screen, not just to access to the content.
Is it possible?
For your second requirement, could the account be a shared inbox?
Here is the code for the rest:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
message = messages.GetLast()
message.display()
Here is another example with exchangelib in python:
https://medium.com/#theamazingexposure/accessing-shared-mailbox-using-exchangelib-python-f020e71a96ab
Here is the snippet to get the last email. I did it using a combination of order by and picking the first one or the last one depending on how you order by:
from exchangelib import Credentials, Account, FileAttachment
credentials = Credentials('FirstName.LastName#Some_Domain.com', 'Your_Password_Here')
account = Account('FirstName.LastName#Some_Domain.com', credentials=credentials, autodiscover=True)
filtered_items = account.inbox.filter(subject__contains='Your Search String Here')
print("Getting latest email for given search string...")
for item in account.inbox.filter(subject__contains='Your Search String Here').order_by('-datetime_received')[:1]: #here is the order by clause:: you may use order_by('datetime_received')[:-1]
print(item.subject, item.text_body.encode('UTF-8'), item.sender, item.datetime_received) #item.text_body.encode('UTF-8') gives you the content of email
while trying to open the real message might be a bit of a challenge but I will update this section once I have a solution. If I may ask:: are you looking at a python only solution ?

Categories