Python - Outlook Response (Accept, Reject, etc.) Date/Time - python

I am working on a project that involves pulling a lot of appointment/meeting data from Outlook from multiple people. One piece of information that I am trying to find is the response for each attendee and, if possible, the date and time that the response happened. For example, if Person X sends me a meeting request on 4/21/2015 12:31:00 PM and I accepted the meeting request at 4/21/2015 1:30:00 PM, how would I get the latter of those two times? I have been browsing the Microsoft docs for this (Link) but have had no luck so far.
Here is a quick summary in Python:
import win32com.client
outlook = win32com.client.Dispatch('Outlook.Application')
namespace = outlook.GetNamespace('MAPI')
recipient = namespace.createRecipient('Other Person')
resolved = recipient.Resolve()
sharedCalendar = namespace.GetSharedDefaultFolder(recipient, 9)
appointments = sharedCalendar.Items
for i in range(0,1):
print appointments[i]
print appointments[i].start
print appointments[i].end
print appointments[i].organizer
print appointments[i].location
print appointments[i].duration
for j in range(0,len(appointments[i].recipients)):
print 'recip, status: ' + str(appointments[i].recipients[j]) + ', ' + str(appointments[i].recipients[j].TrackingStatusTime)

AppointmentItem.ReplyTime and AppointmentItem.ResponseStatus

here is another way
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)
for i, msg in enumerate(messages):
print(msg.MessageClass) # use this in condition
if msg.MessageClass=='IPM.Note':
print('This a Meeting')
elif msg.MessageClass =='IPM.Schedule.Meeting.Request':
print('This is a meeting Meeting')
elif msg.MessageClass =='IPM.Schedule.Meeting.Resp.Pos':
print('Accepted Response , POS = Positive')
elif msg.MessageClass =='IPM.Schedule.Meeting.Resp.Tent':
print('Accepted as Tentative ')
elif msg.MessageClass == 'IPM.Schedule.Meeting.Resp.Neg':
print('Declined Meeting , Neg = Negative')
# Check only first 10 items, change the number as per requirement
if i > 10:
break
https://learn.microsoft.com/en-us/office/vba/outlook/Concepts/Forms/item-types-and-message-classes

Related

Win32com locating time of email after restricting timeframe

I would like to capture the date/time when a message was sent so that I can store the info in dataframe. I have connected to my inbox and can extract the email and I have restricted the time so that I can only get emails from the last 7 days.
Here's my code:
import win32com.client as wc
import pandas as pd
import datetime as dt
last_week = dt.date.today()- dt.timedelta(days = 7)
last_week = last_week.strftime('%m/%d/%Y %H:%M %p')
#Search through my inbox
outlook = wc.Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
root_folder = mapi.Folders['username'].Folders['Inbox'].Folders['folder']
print(root_folder.Name)
#restrict inbox to 7 days
messages = root_folder.Items
messages = messages.Restrict("[ReceivedTime] >= '" + last_week + "'")
messages.Sort("[ReceivedTime]", True)
#grab message and convert to pandas DF. Expected 7 messages
counter = 0
for message in messages:
if message.Subject == 'Message_1':
print(counter, message.Subject)
print(messages.SentOn) ### I Get my Attributes Error here :(
html_str = message.HTMLBody
get_table = pd.read_html(html_str)[0]
counter += 1
When I added the SentOn Method I am getting an AttributeError saying "Restrict.SentOn" I am assuming that this is because I have restricted my time period.
How do I get the actual date/time of the individual message?
I needed to use the individual object as the item to get the .SentOn info from

Adding the SNS topic to python script to send email

I have a python script which in gives the IAM user names in AWS with their last login.I'm getting the expected result. now i have added the SNS topic to send the result via email.
But the response i had received in email is as below
Response:
User not logged into AWS:
u
s
e
r
n
a
m
e
:
i need this in single line as Username: "*****"
PhysicalString =''
for user in resource.users.all():
if user.password_last_used is not None:
delta = (today - user.password_last_used.replace(tzinfo=None)).days
final_result=("username: ", [user.user_name][0]," - ",delta , "days")
physicalString = 'User not logged into AWS: \n\n' + '\n'.join(str(final_result))
response = sns.publish(
TopicArn='*************',
Message= physicalString,
Subject='IAM USER',
)
return final_result
This:
'\n'.join(str(final_result))
is saying "take each character in final_result and put a \n between them.
The problem is that final_result is being converted to a string, so the join is operating on each character rather than each element.
Try:
'\n'.join(final_result)
but you will need to convert delta to str(delta) before storing it in final_result.

update categories in emails using python

I am trying to update categories of emails available in one of the data frame using below code.
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
i = 0
for message in messages:
try:
message.Categories = output.iat[i,2]
except:
message.Categories = 'No Category'
i = i + 1
Below script used to move updated emails from inbox to another folder and then remove to inbox
donebox = outlook.GetDefaultFolder(6).Folders[20]
def delay(time):
for j in range(time):
j=j+1
i = 0
while (messages.Count > 0):
print(i,messages.Count)
message = messages.GetLast()
message.Move(donebox)
delay(1000000)
i = i + 1
messages = donebox.Items
i = 0
while (messages.Count > 0):
print(i,messages.Count)
message = messages.GetLast()
message.Move(inbox)
delay(1000000)
i = i + 1
In outlook updated Categories from output dataframe for emails are able visible only once email selected. Is there any option which can refresh outlook and categories will be updated automatically. Please advice.
For everyone who cant save changing of non-selected mail Categories property by Python:
mail.Categories='Red category'
mail.Save()
It worked for me!
import win32com.client
from win32com.client import Dispatch
outlook=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
folder = outlook.Folders.Item("Inbox")
messages = folder.Items
for i in range(messages.Count):
messages[i].GetInspector()
messages[i].Categories = 'Purple Category'
messages[i].Save()
If only one category needs to be assigned to each email, dmitrii.kotenko has provided the solution.
If you need to append more than one category, pass the categories as a string separated by commas
mail.Categories = "category1, category2, category3"
mail.Save()

Writing email reply bot using poplib and random emails keep showing up in me re.findall(...) call

I'm using poplib to connect to a gmail account and I want it to reply to emails that are sent to it.
However sometimes my regular expression's statement grabs random emails that aren't the one I wanted to reply to.
For example:
5952f967.8543630a.1c70d.283f#mx.google.com
Code below:
def checkEmail():
mail = poplib.POP3_SSL('pop.gmail.com')
mail.user(USER)
mail.pass_(PASS)
numEmails = len(mail.list()[1])
count = 0
if(numEmails>=1):
for i in range(numEmails):
for msg in mail.retr(i+1)[1]:
sender = re.findall(r'[\w\.-]+#[\w\.-]+',msg)
for s in sender:
if s and count == 0:
count += 1
replySender(s)
print s
message = email.message_from_string(msg)
count = 0
mail.quit()

Send an email only if # isn't in csv

I have two CSV files, one with IOC hits and a second that is a watchfile. The watchfile adds an # to the file along with the IOC domain and last seen date. I'm trying to send one email when an IOC hit for that day, but I can't seem to get my loop right. Currently it emails every time, even though the # is present in the watchfile.csv. I've printed the values for val and emailed and they show up in the correct format, but it still emails every time the script is ran.
finIOChit.csv
last: 2017-01-17 query: rabbitons.pw,
watchfile.csv
last: 2017-01-17 query: # rabbitons.pw,
import smtplib
import csv
import os
import re
from datetime import *
today = date.today()
today = datetime.combine(today, datetime.min.time())
# Setup email alerting
sender = 'server#company.com'
receivers = ['user#company.com']
patn = re.compile('20\d{2}-\d{2}-\d{2}')
watchfile = open('watchfile.csv', 'r+w')
alreadyemailed = re.compile('#')
with open('finalIOChit.csv') as finalhit:
for hit in finalhit:
for line in watchfile:
emailed = alreadyemailed.findall(line)
for match in patn.findall(hit):
val = datetime.strptime(match, '%Y-%m-%d')
if val == today and emailed != '#':
hit = re.sub('query: ','query: # ',hit)
watchfile.write(hit)
message = """From:server <server#comapny.com>
To: user <user#company.com>
Subject: Passive DNS hit
"""
subject = ' ' + str(hit)
messagefull = message + subject
try:
smtpObj = smtplib.SMTP('emailserver')
smtpObj.sendmail(sender, receivers, messagefull)
except SMTPException:
print "Error: unable to send email"

Categories