I'm having an issue like this one
outlook = win32com.client.Dispatch('outlook.application')
accounts = win32com.client.Dispatch("outlook.Application").Session.Accounts
print(accounts[1])
mail = outlook.CreateItem(0)
mail.SentOnBehalfOfName = accounts[1]
mail.SendUsingAccount = accounts[1]
mail.To = to
mail.Subject = 'Subject TEST'
mail.HTMLBody = emailBody
mail.display()
mail.Send()
if I comment mail.Send() the window that shows up will show everything correctly but if I send it, i'll get reply This message could not be sent. You do not have the permission to send the message on behalf of the specified user. which is obviously not true since if instead of sending directly and choose the exact same email from the dropdown menu in From, and then click SEND, it will send the email with no issues.
So with the help of #Eugene Astafiev and this post I fixed the issue like this:
outlook = win32com.client.Dispatch('outlook.application')
for account in outlook.Session.Accounts:
if account.DisplayName == "marhaba#vodafone.om":
print(account)
mail = outlook.CreateItem(0)
mail._oleobj_.Invoke(*(64209, 0, 8, 0, account))
mail.To = to
mail.Subject = 'Vodafone Support'
mail.HTMLBody = emailBody
#mail.display()
mail.Send()
There is no need to use these both properties at the same time in Outlook:
mail.SentOnBehalfOfName = accounts[1]
mail.SendUsingAccount = accounts[1]
The From field available in the Outlook UI corresponds to the MailItem.SendUsingAccount property which returns or sets an Account object that represents the account under which the MailItem is to be sent. This option is available when you have multiple accounts configured in Outlook.
The MailItem.SentOnBehalfOfName property returns a string, not an Account instance, where a string indicates the display name for the intended sender of the mail message. Be aware, the permission should be given to be able to send on behalf of another person in Exchange.
So, if you have got multiple accounts configured in Outlook you may go with the following line of code:
mail.SendUsingAccount = accounts[1]
Related
I have a code, which sends a new email to the chosen recipients. The email is created based on a received email, which is in the inbox.
For the email sending I use the Win32 python library.
However, since a brand new email is being created, the email from which the new email is created left 'unseen' in the inbox.
How can I set the original email to 'seen' with code?
The code is something like this:
if inbox.Items[i].UnRead == True:
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = mail_list
mail.Subject = sub
mail.HTMLbody = new_body
mail.Send()
print('The email was sent successfully!')
Thank you in advance.
the email from which the new email is created left 'unseen' in the inbox.
You just need to set the MailItem.UnRead property to false on that item. The property returns or sets a boolean value that is true if the Outlook item has not been opened (read).
Try inbox.Items[i].UnRead = False after mail.Send()
Example
import win32com.client
def send_new_email(inbox):
for item in inbox.items:
if item.UnRead:
print(item.Subject)
new_email = outlook.CreateItem(0)
new_email.Display()
item.UnRead = False
if __name__ == "__main__":
outlook = win32com.client.Dispatch("outlook.Application")
olNs = outlook.GetNamespace("MAPI")
inbox = olNs.GetDefaultFolder(6)
send_new_email(inbox)
I already referred this post. Don't mark it as duplicate please.
I wrote the below code to send an email via python
outlook = win32com.client.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
From = outlook.Session.Accounts[1]
mail.To = 'test#org.com'
mail.Subject = 'Test Email'
mail.HTMLBody = '<h3>This is HTML Body</h3>'
mail.Body = "This is the normal body"
mail._oleobj_.Invoke(*(64209, 0, 8, 0, From))
mail.Send() # successfully executed
The above code is successfully executed but still the email is not delivered and its been more than 15 mins. If I do it manually using outlook,am able to send and receive messages.
Can help me what is the issue here?
update - mail.display() looks like below
update - mail.Send() in outbox looks like below
update - error for 2nd mailbox
update - code
mail = outlook.CreateItem(0)
for acc in outlook.Session.Accounts:
if acc.DisplayName == 'user2#org.com':
print("hi")
mail.SendUsingAccount = acc.DisplayName
mail.To = 'user1#org.com'
mail.Subject = 'Test Email'
mail.HTMLBody = '<h3>This is HTML Body</h3>'
mail.Body = "This is the normal body"
mail._oleobj_.Invoke(*(64209, 0, 8, 0, mail.SendUsingAccount))
pythoncom.CoInitialize()
The difference between Outlook and your code is the synchronization with the mail server. Outlook may cache submitted items and send them when the store is synced with the mail server.
The NameSpace.SendAndReceive method initiates immediate delivery of all undelivered messages submitted in the current session, and immediate receipt of mail for all accounts in the current profile. SendAndReceive provides the programmatic equivalent to the Send/Receive All command that is available when you click Tools and then Send/Receive. All accounts defined in the current profile are used in Send/Receive All. If an online connection is required to perform the Send/Receive All, the connection is made according to user preferences.
Read more about that in the How To: Perform Send/Receive in Outlook programmatically article.
Also you may try to run the following code:
mail = outlook.CreateItem(0)
for acc in outlook.Session.Accounts:
if acc.DisplayName == 'user2#org.com':
print("hi")
mail.SendUsingAccount = acc.DisplayName
mail.To = 'user1#org.com'
mail.Subject = 'Test Email'
mail.HTMLBody = '<h3>This is HTML Body</h3>'
mail.Body = "This is the normal body"
mail.Send()
My secondary outlook account does not appear in the list given by iterating
over outlook.application CDispatch Session.Accounts.
So, I'm using 'SentOnBehalfOfName' instead, as suggested by https://stackoverflow.com/a/57324426/6057650 to sent emails. And it works, but not at all or completely as I expected, since sent emails are stored in the primary account outbox and not in the secondary account outbox.
import win32com.client as win32
outlook = win32.Dispatch('outlook.application')
# see available mail accounts (no condition, just as info)
for accounts in outlook.Session.Accounts:
print('Available email accounts: %s'%(accounts))
# Create the email to be sent
mail = outlook.CreateItem(0)
mail.SendUsingAccount='secondary_account#email.com'
mail._oleobj_.Invoke(*(64209, 0, 8, 0, 'secondary_account#email.com'))
mail.SentOnBehalfOfName = 'secondary_account#email.com'
mail.To = 'some_address#email.com'
mail.Subject = 'Report'
mail.Body ='Some stuff'
# getting default folder of used Account
myNamespace = outlook.GetNamespace("MAPI")
myFolder = myNamespace.GetDefaultFolder(6)
myFolder.Display()
# see your prepared email
mail.Display()
# Finally
mail.Send()
What I want (and need) is that sent emails be stored in the secondary account outbox (which is shared with other peers and which can be access by them) and not in the main or primary account outbox (which only I can access).
try the following
import win32com.client
Outlook = win32com.client.Dispatch("Outlook.Application")
for account in Outlook.Session.Accounts:
if account.DisplayName == "secondary_account#email.com":
print(account)
email = Outlook.CreateItem(0)
email._oleobj_.Invoke(*(64209, 0, 8, 0, account))
email.Display()
I am trying to setup a script to send email, and I want to add the Senders Name (depending on who runs the script) to the Email Body.
Emailing works, and I'm setup on Juypter, runing Python 3, emailing from Outlook.
My code is below. The mail.SenderName is the part I want to pull the name from the Outlook account of the user. In VBA this would be equivalent to using Application.UserName
import win32com.client as win32
outlook = win32.Dispatch("outlook.application")
mail = outlook.CreateItem(0)
mail.To = "user#somewhere.com"
mail.Subject = "Report"
#Text for email
mail.HTMLBody = "Dear All,<br><br>" \
"The latest version of the Report is attached in PDF format.<br><br>" \
"Kind Regards <br><br>" \
mail.SenderName
attachment = filename
mail.Attachments.Add(attachment)
mail.Send()
So I would want the email body to be:
Dear All,
The latest version of the Report is attached in PDF format.
Kind Regards
Bob Smith
Any help, much appreciated.
UPDATE
By combining the response from Error - Syntactical Remorse and Eugene Astafiev, with a bit more searching, I managed to resolve the issue. Thank you for the guidance.
Full code is:
outlook = win32.Dispatch("outlook.application")
mail = outlook.CreateItem(0)
mail.To = "user#somewhere.com"
mail.Subject = "Report"
sender = outlook.GetNamespace("MAPI").CurrentUser.Name
#Text for email
mail.HTMLBody = "Dear All,<br><br>" \
"The latest version of the Report is attached in PDF format.<br><br>" \
"Kind Regards <br><br>" \
f"{sender}"
attachment = filename
mail.Attachments.Add(attachment)
mail.Send()
You can:
Use the NameSpace.CurrentUser property which returns the display name of the currently logged-on user as a Recipient object.
Sub DisplayCurrentUser()
Dim myNamespace As Outlook.NameSpace
Set myNameSpace = Application.GetNameSpace("MAPI")
MsgBox myNameSpace.CurrentUser.Name
End Sub
If it is set, you may use the MailItem.SendUsingAccount property which returns an Account object that represents the account under which the MailItem is to be sent.
MailItem.SendUsingAccount.DisplayName
I have the following code and i need to change the from address.
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = 'madanraj.c#xyz.com;madanraj.c#xxxyyy.com'
mail.Subject = 'Daily Backlog'
mail.Body = 'This Mail is Sent by Python'
mail.HTMLBody = '<h2>HTML Message body</h2>' #this field is optional
# To attach a file to the email (optional):
#attachment = "C:\\Users\madanraj.c\Downloads\Report.csv"
#mail.Attachments.Add(attachment)
mail.Send()
print("success")
I have two mail address in my outlook application and i need to send from other one , not by default one.