How to attach a calendar invite to SES send_raw_email? - python

I use send_raw_email to send emails with HTML content and file attachments. How do I insert an ical/ics invite to the email?
I use icalendar to generate ics content.
This is what I came up with so far, but it shows in Gmail as a file attachment.
if calendar_reminder_date:
cal = Calendar()
cal.add('prodid', '-//My calendar product//mxm.dk//')
cal.add('version', '2.0')
cal.add('calscale', 'GREGORIAN')
cal.add('method', 'REQUEST')
event = Event()
event['dtstart'] = calendar_reminder_date.strftime("%Y%m%dT%H%M%SZ")
event['dtstamp'] = calendar_reminder_date.strftime("%Y%m%dT%H%M%SZ")
event['summary'] = 'Python meeting about calendaring'
cal.add_component(event)
attachment_part = MIMEText(cal.to_ical())
print repr(cal.to_ical())
del attachment_part['Content-Type']
attachment_part.add_header('Content-Type', 'text/calendar', name='invite.ics')
attachment_part.add_header('Content-Disposition', 'attachment', filename='invite.ics')
msg.attach(attachment_part)

Hard to tell without seeing the actual full MIME message as received on the Google side but there are definitely several things missing here:
a calendar REQUEST must have an ORGANIZER property, as well as at least one ATTENDEE property with a value corresponding to the email address of the gmail user (prefixed with a mailto:).
your content-type is missing a METHOD=REQUEST parameter and you probably do not want to set any content-disposition.
See also Multipart email with text and calendar: Outlook doesn't recognize ics

Related

Sending emails with outlook using Python and HTML

How do I successfully use a sender account with a password that is not already signed in to on the Outlook application on my laptop? I want to send a message from the example account, "from#outlook.com" but it has a password. I have this password. Am I able to enter this into the existing code?
import win32com.client as client
import datetime,time
outlook=client.Dispatch("Outlook.Application")
message=outlook.Createitem(0)
namespace=outlook.GetNameSpace('MAPI')
inbox=namespace.GetDefaultFolder(6)
message=inbox.items.add
message.To="to#outlook.com"
message.CC=""
message.BCC=""
From = "from#outlook.com"
#password = ""
message.Subject="Subject text here"
message.BodyFormat = 2
message.HTMLBody = "<html><h2><span style='color:red'>There is an error with the file </b></span></h2> <body>Please check your submission and try again </body></html>"
message.Save()
message.Display()
time.sleep(5)
message.Send()
Firstly, MailItem object does not expose the From property. It exposes read-only Sender / SenderEmailAddress / SenderName properties, but they obviously cannot be set. You can set the MailItem.Account property to an instance of the Account object retrieved from the Application.Session.Accounts collection, but that requires you to configure the relevant account in Outlook first.
As a general rule, Outlook wont' let you send from an arbitrary one-off account not previously configured in Outlook.

python script that checks column value in excel sheet and sends mail to that particular person in outlook by the name of distribution list(DL)

I want to write a python script that checks a column value in excel sheet and sends mail to that particular person in outlook by the name of distribution list(DL). I am unable to fetch DL with the following code. Please help me on this.
More details:
The sender should be the DL name i.e., DL IQWDL SSDBU NEC Global xyzglobal.abcbu#pqr.com
The receiver should an individual name i.e., rahul.kumar#pqr.com
Code:
import win32com.client as win32
import pandas as pd
#Read the excel file
xl = pd.read_excel('C:\\Users\\rahulk\\Downloads\\corepy\\excel_report.xlsx')
#Select the email addresses from a specific column in the Excel file
email_addresses = xl['Email'].tolist()
#Connect to Outlook and get the distribution list your text
outlook = win32.gencache.EnsureDispatch("Outlook.Application")
dl = outlook.Session.GetDefaultFolder(win32.constants.olFolderContacts).GetDistributionListFromID("xyzglobal.abcbu#pqr.com")
#Loop through the email addresses and send the email your text
for email_address in email_addresses:
email = outlook.CreateItem(win32.constants.olMailItem)
email.To = email_address
email.Subject = "Email Subject"
email.Body = "Email Body"
email.SentOnBehalfOfName = dl.DLName
email.Send()
#Release the Outlook instance
outlook = None
The Outlook object model doesn't provide the GetDistributionListFromID method for the Folder class. To find an item in the folder you need to use the Find/FindNext or Restrict methods of the Items class. Read more about these methods in the articles I wrote for the technical blog:
How To: Retrieve Outlook Contact items using Restrict method
How To: Use Find and FindNext to retrieve Outlook Contact items
Be aware, the To property expects a semicolon-delimited string list of display names for the To recipients for the Outlook item. Otherwise, I'd suggest using the Recipeints.Add method for adding recipients. See How To: Fill TO,CC and BCC fields in Outlook programmatically for more information.

Outlook Check Message Type

I’m using a python package called win32com to directly access and scrape the inboxes from Outlook. As the Outlook application is setup to have multiple email accounts, I’ve had to adapt my code to read messages from multiple email accounts. However, the messages contains calendar invites and I just want email messages to be scraped. Is there a way to filter the messages based on type?
Outlook = client.Dispatch(“Outlook.Application”).GetNameSpace(“MAPI”)
Messages = outlook.Folders(“test#test.com).Folders(“Inbox”)
For msg in messages:
#Do Something
Yes, you need to check if the object is of type OlObjectClass.olMail, which is represented by value 43. You can check all enumerations here.
Outlook = client.Dispatch(“Outlook.Application”).GetNameSpace(“MAPI”)
Messages = outlook.Folders(“test#test.com).Folders(“Inbox”)
for msg in messages:
if msg.Class == 43: # OlObjectClass.olMail
#Do Something

receiving emails with python api O365

I am just starting out in Python and I am trying to accomplish a manual task I have heard is on the simpler side to accomplish with python. My company uses Office 365 for their emails and I want to retrieve an email attachment and store it locally so I can save time . So far have established how to send a simple email, call the names of the folders in my account but I cannot figure out how to read any specific email .
my idea goes a little like this ,
from O365 import Account, message,mailbox
credentials = ('username', 'given password')
account = Account(credentials)
mailbox = account.mailbox()
mail_folder = mailbox.inbox_folder()
mail_folder = mailbox.get_folder(folder_name='Inbox')
print(mail_folder)
#_init__(*,parent= Inbox, con=None,**kwargs)
Message_body = message.body()
message.get_subject('email subject here!')
print(Message.body)
right now I am lost and trying anything within the O365 documentation page but the message module does not have the attribute subject according to how I am using it . Any guidance would be much appreciated
From your example - it's not clear if you are authenticated or not...
If you are then you will be able to list the mailbox folders. In the case below - you can access the inbox and then list the sub-folders:
from O365 import Account, Connection, MSGraphProtocol, Message, MailBox, oauth_authentication_flow
scopes=['basic', 'message_all']
credentials=(<secret>, <another secret>)
account = Account(credentials = credentials)
if not account.is_authenticated: # will check if there is a token and has not expired
account.authenticate(scopes=scopes)
account.connection.refresh_token()mailbox = account.mailbox()
inbox = mailbox.get_folder(folder_name='Inbox')
child_folders = inbox.get_folders(25)
for folder in child_folders:
print(folder.name, folder.parent_id)
This part will allow you to list folders (and also messages).
If I look at your code - it looks as though you are trying to do both?
Try doing something like the following to get the hang of paging through your inbox:
for message in inbox.get_messages(5):
if message.subject == 'test':
print(message.body)
Note that I'm looping through the first 5 messages in the inbox looking for a message with subject 'test'. If it finds the message - then it prints the body.
Hopefully this will shed a little light.

Adding metadata to MIME multipart message

I'm sending emails using python. Currently my technique is this:
msg = email.mime.Multipart.MIMEMultipart()
msg["From"] = username
msg["To"] = recipient
msg["Subject"] = subject
mimeText = email.mime.Text.MIMEText(body, "html")
msg.attach(mimeText)
stringMsg = msg.as_string()
I would like to also add some metadata to the message - specifically, a unique identifier of the task the email is achieving, so that when it is checked later (possibly by a different service), I can avoid sending a duplicate email.
This metadata doesn't need to be completely secret or secure, just something that standard email clients don't render. Obviously there are the options of including a bogus BCC email address containing the id, or adding a hidden html node to the body.
<div style="display:none;">123456789</div>
But both of those seem quite "hacky". Is there anything like this that will get persisted and sent as part of the email, that I can check using imaplib later?
msg["secretMetadata"] = "123456789"
User defined fields are permitted and explained in RFC822. Basically you can prefix your custom field with X- and this will not conflict with any existing fields nor extension fields.
So, something like msg["X-secretMetadata"] = "123456789" should suffice.
It sounds like you might want to use X-headers. Information in the X-headers of an email message is usually used for application-specific purposes, and this information is usually not displayed by mail clients.

Categories

Resources