0

I am trying to automate some python code that will automatically save some attachments from certain emails with a specific title.

Below is what I currently have:

import win32com.client as client

outlook = client.Dispatch('Outlook.Application')
namespace = outlook.GetNameSpace('MAPI')
inbox = namespace.GetDefaultFolder(6)
target_subject = 'Testing attachment'
mail_items = [item for item in inbox.Items if item.Class == 43]
filtered = [item for item in mail_items if item.Subject == target_subject]


if len(filtered) != 0:
    target_email = filtered[0]
    

if target_email.Attachments.Count > 0:
    attachments = target_email.Attachments    
    

save_path = 'C:'

for file in attachments:
    file.SaveAsFile(save_path.format(file.FileName))  

However I seem to be getting an error with permissions?

com_error: (-2147352567, 'Exception occurred.', (4096, 'Microsoft Outlook', "Cannot save the attachment. You don't have appropriate permission to perform this operation.", None, 0, -2147024891), None)

Not sure how to work around this, I am the Admin etc.

I am also wondering what would be the changes required to actually deploy this online and have it running, i.e. I am not passing any credentials as it's local, if operating stand alone I would like it to access my inbox every 7 days or so and download this specific attachments from this specific email.

Any help will be greatly appreciated.

Thanks!

Nairda123
  • 137
  • 2
  • 14

2 Answers2

1

Choose another drive or folder, for example, My Documents doesn't require admin privileges for writing. Otherwise, you will have to run Outlook with admin privileges if you want to write anything to the system drive (C:).

Also I've noticed the following lines of code:

mail_items = [item for item in inbox.Items if item.Class == 43]
filtered = [item for item in mail_items if item.Subject == target_subject]

Iterating over all items in the folder is not really a good idea, moreover, you are doing that twice!

I'd recommend using the Find/FindNextorRestrict` methods of the Items class that allow getting only items that correspond to the specified condition. Read more about these methods in the following articles:

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
0

Users by default do not have write access to the root drive (C:). Change it to something like 'c:\temp\'

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
  • The code (most likely) doesn't attempt to write to the root directory. It attempts to write to `C:some_file` (note the missing backslash). That's valid, though [unusual syntax](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#fully-qualified-vs-relative-paths) for: Write to `some_file` in the current working directory of drive `C`. That's still either unintended or wrong. – IInspectable May 25 '21 at 11:57
  • `C:some_file` **is** in the root folder of the C:\ drive. And you cannot do that without elevation. – Dmitry Streblechenko May 25 '21 at 15:59
  • No, it isn't. This specific syntax involves the *current working directory*. `C:\some_file`, on the other hand, is in the root. – IInspectable May 25 '21 at 16:00
  • `'C:'.Format(someValue)` will produce `'C:' ` in Python, would it not? save_path should be something like` 'c:\SomeExistingFolder\{0}'` – Dmitry Streblechenko May 25 '21 at 17:25
  • Not sure, what you were trying to say. The markup certainly can get in the way. – IInspectable May 25 '21 at 20:43
  • I am saying the code (as written) is equivalent to `file.SaveAsFile('C:')` – Dmitry Streblechenko May 25 '21 at 21:14
  • No, it isn't. The code clearly appends to `C:`. – IInspectable May 26 '21 at 00:25
  • It does not. It calls Format on a string that contains no placeholder: https://www.w3schools.com/python/ref_string_format.asp – Dmitry Streblechenko May 26 '21 at 00:31
  • Oh, I see, you changed your reasoning half way through the comments. Sure, that is correct, `'C:'.format('whatever')` produces the string `'C:'`. That names a volume, though, not a drive. – IInspectable May 26 '21 at 07:44