在此处输入图像描述我在 jenkins 中调用 python 脚本以使用 win32 发送电子邮件,该脚本在从命令窗口运行时完美运行,但在 jenkins 管道中使用时抛出错误。
import win32com.client as win32
outlook=win32.Dispatch('outlook.application')
mail=outlook.CreateItem(0)
mail.To='[email protected]'
mail.Subject="Test Mail"
mail.HTMLBody="Hiii, This is just a test mail."
mail.Send()
错误:IDispatch = pythoncom.connect(IDispatch) pywintypes.com_error:(-2147221021,'操作不可用',无,无)
import win32com.client as win32
import pandas as pd
import datetime
import time
# Outlook instance
outlook = win32.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
inbox = namespace.GetDefaultFolder(6) # 6 refers to the Inbox folder
# Function to fetch emails from the inbox based on multiple subjects
def fetch_emails(subject_filters=None, category_filter=None):
messages = inbox.Items
messages.Sort("[ReceivedTime]", True) # Sort by received time, descending
filtered_emails = []
for message in messages:
# Check if the email subject matches any of the subjects in the filter list
if subject_filters and not any(subject in message.Subject for subject in subject_filters):
continue
if category_filter and category_filter not in message.Categories:
continue
email_details = {
'Subject': message.Subject,
'ReceivedTime': message.ReceivedTime
}
filtered_emails.append(email_details)
return filtered_emails
# Function to highlight missing data in the DataFrame
def highlight_missing(val):
color = 'red' if pd.isnull(val) or val == '' else ''
return f'background-color: {color}'
# Function to create a DataFrame from the list of emails
def create_dataframe(filtered_emails, expected_emails):
df = pd.DataFrame(filtered_emails)
# Create a list of missing emails
missing_emails = [email for email in expected_emails if email not in [e['Subject'] for e in filtered_emails]]
# Add missing emails to the dataframe as absent
for missing in missing_emails:
df = df.append({'Subject': missing, 'ReceivedTime': 'No email found'}, ignore_index=True)
# Order by received time in ascending order
df['ReceivedTime'] = pd.to_datetime(df['ReceivedTime'], errors='coerce')
df = df.sort_values(by='ReceivedTime', ascending=True)
# Highlight missing rows (if subject or received time is missing)
df_style = df.style.applymap(highlight_missing, subset=['Subject', 'ReceivedTime'])
return df_style
# Function to send the email with DataFrame as content using Outlook's win32 Dispatch
def send_email_with_dataframe(df, to_email):
# Convert dataframe to HTML table (using the pandas 'to_html' function)
html_table = df.render() # Render the styled DataFrame to HTML
# Create the email
mail = outlook.CreateItem(0) # 0 refers to a Mail Item
mail.Subject = "Automated Daily Email Report"
mail.To = to_email # The recipient email address
# Create the email body with the DataFrame HTML
mail.HTMLBody = f"<html><body><h2>Email Report</h2>{html_table}</body></html>"
# Send the email
mail.Sensitivity = 3 # Set sensitivity level (3 is 'Private')
mail.Send() # Send the email
print("Email sent successfully using Outlook.")
# Function to check emails and take actions based on time
def check_emails():
current_time = datetime.datetime.now()
emails = [] # Initialize an empty list to store emails
# Define subject lists for each email type (you can manually update these lists)
subject_type1 = ["Subject 1a", "Subject 1b", "Subject 1c"] # Update these subjects for Type 1 emails
subject_type2 = ["Subject 2a", "Subject 2b"] # Update these subjects for Type 2 emails
subject_type3 = ["Subject 3a", "Subject 3b", "Subject 3c"] # Update these subjects for Type 3 emails
# Check for Type 1 emails (every day at 9:30 AM, 4 PM, 6 PM, 8 PM)
if current_time.hour == 9 and current_time.minute == 30:
emails = fetch_emails(subject_filters=subject_type1)
df = create_dataframe(emails, subject_type1)
send_email_with_dataframe(df, '[email protected]') # Replace with the recipient's email
# Check for Type 2 emails (every Monday at 4 PM)
if current_time.weekday() == 0 and current_time.hour == 16: # Monday
emails = fetch_emails(subject_filters=subject_type2)
df = create_dataframe(emails, subject_type2)
send_email_with_dataframe(df, '[email protected]') # Replace with the recipient's email
# Check for Type 3 emails (every day at 4 PM)
if current_time.hour == 16 and current_time.minute == 0:
emails = fetch_emails(subject_filters=subject_type3)
df = create_dataframe(emails, subject_type3)
send_email_with_dataframe(df, '[email protected]') # Replace with the recipient's email
# Main function to run the scheduled checks
def main():
while True:
check_emails()
time.sleep(60) # Check every minute to see if it's time to run a check
if __name__ == "__main__":
main()
enter code here
Explanation of Changes:
Creating the DataFrame: The create_dataframe function now creates the DataFrame with Subject and ReceivedTime columns, and it handles missing emails.
Missing emails will be added with "No email found" in the ReceivedTime column.
Pandas Styling: We use the style.applymap() function to highlight missing data in the DataFrame, specifically the rows where Subject or ReceivedTime is missing.
Convert to HTML: We use the df.render() method to convert the DataFrame to HTML, which allows you to send the DataFrame directly in the email body.
Sending the Email: The send_email_with_dataframe function sends the DataFrame as HTML in the email body. This avoids manually creating an HTML table, as we are leveraging Pandas' ability to convert the DataFrame to HTML.
Example Output in the Email:
The email will contain a Pandas DataFrame rendered as an HTML table with the following:
Only the Subject and ReceivedTime.
Rows ordered by ReceivedTime in ascending order.
Missing emails will be displayed with "No email found" in the ReceivedTime column, and these rows will be highlighted in red.
Key Points:
The missing emails will be highlighted in red.
The table will be rendered using Pandas DataFrame.
The email body will contain the DataFrame directly as an HTML table.
with html body
import win32com.client as win32
import pandas as pd
import datetime
import time
# Outlook instance
outlook = win32.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
inbox = namespace.GetDefaultFolder(6) # 6 refers to the Inbox folder
# Function to fetch emails from the inbox based on multiple subjects
def fetch_emails(subject_filters=None, category_filter=None):
messages = inbox.Items
messages.Sort("[ReceivedTime]", True) # Sort by received time, descending
filtered_emails = []
for message in messages:
# Check if the email subject matches any of the subjects in the filter list
if subject_filters and not any(subject in message.Subject for subject in subject_filters):
continue
if category_filter and category_filter not in message.Categories:
continue
email_details = {
'Subject': message.Subject,
'ReceivedTime': message.ReceivedTime
}
filtered_emails.append(email_details)
return filtered_emails
# Function to highlight missing data in the DataFrame
def highlight_missing(val):
color = 'red' if pd.isnull(val) or val == '' else ''
return f'background-color: {color}'
# Function to create a DataFrame from the list of emails
def create_dataframe(filtered_emails, expected_emails):
df = pd.DataFrame(filtered_emails)
# Create a list of missing emails
missing_emails = [email for email in expected_emails if email not in [e['Subject'] for e in filtered_emails]]
# Add missing emails to the dataframe as absent
for missing in missing_emails:
df = df.append({'Subject': missing, 'ReceivedTime': 'No email found'}, ignore_index=True)
# Order by received time in ascending order
df['ReceivedTime'] = pd.to_datetime(df['ReceivedTime'], errors='coerce')
df = df.sort_values(by='ReceivedTime', ascending=True)
# Highlight missing rows (if subject or received time is missing)
df_style = df.style.applymap(highlight_missing, subset=['Subject', 'ReceivedTime'])
return df_style
# Function to send the email with DataFrame as content using Outlook's win32 Dispatch
def send_email_with_dataframe(df, to_email):
# Convert dataframe to HTML table
html_table = df.render() # Render the styled DataFrame to HTML
# Create the email
mail = outlook.CreateItem(0) # 0 refers to a Mail Item
mail.Subject = "Automated Daily Email Report"
mail.To = to_email # The recipient email address
# Create the email body with the DataFrame HTML
mail.HTMLBody = f"<html><body><h2>Email Report</h2>{html_table}</body></html>"
# Send the email
mail.Sensitivity = 3 # Set sensitivity level (3 is 'Private')
mail.Send() # Send the email
print("Email sent successfully using Outlook.")
# Function to check emails and take actions based on time
def check_emails():
current_time = datetime.datetime.now()
emails = [] # Initialize an empty list to store emails
# Define subject lists for each email type (you can manually update these lists)
subject_type1 = ["Subject 1a", "Subject 1b", "Subject 1c"] # Update these subjects for Type 1 emails
subject_type2 = ["Subject 2a", "Subject 2b"] # Update these subjects for Type 2 emails
subject_type3 = ["Subject 3a", "Subject 3b", "Subject 3c"] # Update these subjects for Type 3 emails
# Check for Type 1 emails (every day at 9:30 AM, 4 PM, 6 PM, 8 PM)
if current_time.hour == 9 and current_time.minute == 30:
emails = fetch_emails(subject_filters=subject_type1)
df = create_dataframe(emails, subject_type1)
send_email_with_dataframe(df, '[email protected]') # Replace with the recipient's email
# Check for Type 2 emails (every Monday at 4 PM)
if current_time.weekday() == 0 and current_time.hour == 16: # Monday
emails = fetch_emails(subject_filters=subject_type2)
df = create_dataframe(emails, subject_type2)
send_email_with_dataframe(df, '[email protected]') # Replace with the recipient's email
# Check for Type 3 emails (every day at 4 PM)
if current_time.hour == 16 and current_time.minute == 0:
emails = fetch_emails(subject_filters=subject_type3)
df = create_dataframe(emails, subject_type3)
send_email_with_dataframe(df, '[email protected]') # Replace with the recipient's email
# Main function to run the scheduled checks
def main():
while True:
check_emails()
time.sleep(60) # Check every minute to see if it's time to run a check
if __name__ == "__main__":
main()
What Will Be Sent in the Email:
Only the Subject and ReceivedTime will be included in the table.
Rows will be ordered by ReceivedTime in ascending order.
Missing emails (those not found in the inbox) will be displayed with:
Subject: The missing email subject.
ReceivedTime: A message "No email found".
Rows where the Subject or ReceivedTime is missing will be highlighted in red.
Example Output in Email:
Assume you're expecting the following subjects:
Type 1 Expected Subjects: "Subject 1a", "Subject 1b", "Subject 1c"
Type 2 Expected Subjects: "Subject 2a", "Subject 2b"
Type 3 Expected Subjects: "Subject 3a", "Subject 3b", "Subject 3c"
After the check, let's say you found the following:
Found: "Subject 1a", "Subject 3b", "Subject 3c"
Missing: "Subject 1b", "Subject 1c", "Subject 3a", "Subject 2a", "Subject 2b"
<html>
<body>
<h2>Email Report</h2>
<table border="1">
<tr>
<th>Subject</th>
<th>ReceivedTime</th>
</tr>
<tr>
<td>Subject 1a</td>
<td>2025-01-14 09:35:00 AM</td>
</tr>
<tr>
<td>Subject 3b</td>
<td>2025-01-14 04:00:00 PM</td>
</tr>
<tr>
<td>Subject 3c</td>
<td>2025-01-14 04:10:00 PM</td>
</tr>
<tr style="background-color: red;">
<td>Subject 1b</td>
<td>No email found</td>
</tr>
<tr style="background-color: red;">
<td>Subject 1c</td>
<td>No email found</td>
</tr>
<tr style="background-color: red;">
<td>Subject 3a</td>
<td>No email found</td>
</tr>
<tr style="background-color: red;">
<td>Subject 2a</td>
<td>No email found</td>
</tr>
<tr style="background-color: red;">
<td>Subject 2b</td>
<td>No email found</td>
</tr>
</table>
</body>
</html>