Timo
Timo

Reputation: 21

Change sender account using exchangelib

I have two accounts on outlook 'user1@example.com' and 'user2@example.com'. I have a number of drafts in the user1 draft folder and want to update each email to the user2 address before sending them so that user2 is the sender of the emails and appears in the from field for the mail items.

using exchangelib I managed to change the 'sender' and 'account' address from user1 to user2 (and even print(item.sender, item.account)to verify the change) but the update does not reflect on the emails' from field on the outlook draft folder when it's done.

import getpass
from exchangelib import Configuration
from exchangelib import Credentials, Account
from exchangelib import FileAttachment, HTMLBody
from exchangelib.properties import DistinguishedFolderId


def authenticate():
    """
    Authenticate into mail.example.com
    """
    email = "user1@example.com"
    passwd = getpass.getpass(prompt="Enter your password: ")
    user_credentials = Credentials(email, passwd)
    config = Configuration(server="mail.example.com",
                           credentials=user_credentials)
    account = Account(primary_smtp_address=email, config=config,
                           credentials=user_credentials, autodiscover=False)
    return account

def main():
    """
     Change sender account to user2@example.com
    """
    user_account = authenticate()
    drafts = DistinguishedFolderId('drafts')
    for item in user_account.drafts.all().order_by('subject'):
        item.sender = 'user2@example.com'
        item.account = 'user2@example.com'
        user_account.drafts.save(update_fields=['sender', 'account'])
        exit("Done")

if __name__ == "__main__":
    main()

Upvotes: 2

Views: 1401

Answers (2)

Erik Cederstrand
Erik Cederstrand

Reputation: 10245

You need to call .save() on the item, not the folder. Folder.save() is for changing properties on the folder itself, e.g. the folder name.

Printing the item as suggested in the other answer will only tell you that your local copy of the item was changed, not the actual item on the server. You need to call item.refresh() to see what was actually updated (although that should always match when you have called item.save()).

Finally, item.account is a reference to the Account object. Don't change that. The two fields that contain sender information are item.sender and item.author, but item.sender is set automatically by the server and cannot be changed. item.author can be changed, but only while the message is still a draft. Here's a link to the definition of Message-specific fields in exchangelib: https://github.com/ecederstrand/exchangelib/blob/3158c076a1e30a18e0b68e99a54fb14b3a6f7cd4/exchangelib/items/message.py#L18.

Here's an example:

    for item in user_account.drafts.all().order_by('subject'):
        item.author = 'user2@example.com'
        item.save()
        item.refresh()  # This gets a fresh copy of the item on the server
        print(item)  # Now you see whatever the server has

Upvotes: 1

Biorez
Biorez

Reputation: 59

Not a real solution but something you can look for:

You can do:

for item in user_account.drafts.all().order_by('subject'):
    print(item) #Copy Text into Notepad++ and search for user1/ user1@example.com
    item.sender = 'user2@example.com'
    item.account = 'user2@example.com'
    user_account.drafts.save(update_fields=['sender', 'account'])
    print(item) #Copy Text in another Notepad++ tab to see if every user1 entry has been replaced
    exit("Done")

You should be able to compare the .txts and find the missing item (if there is one) WARNING: depending on how much mails there are there will be a huge wall of text

Upvotes: 0

Related Questions