使用win32com通过outlook发送电子邮件并添加签名文件

时间:2017-01-31 20:55:51

标签: python email outlook

我正在使用Python 3.5自动化一些电子邮件以进行工作。我们不能使用smtp。必须通过win32com控制outlook来完成。我已经完成了所有工作。我可以创建一个HTML电子邮件。我可以给它一个电子邮件地址,如果它在Outlook配置文件中的活动电子邮件地址打开,它将从该地址发送。我可以添加cc,bcc,主题等。

我的问题是添加存储在outlook中的签名。我已经读过Outlook签名没有公开,因此我不能简单地称它们为SendUsingAccount或mail.CC字段。

我的替代方法是让用户使用tkinter和askopenfilename()指定文件。

大部分都有效。用户指定一次签名文件位置。我将它存储在我的tkinter程序启动时读取的数据文件中。用户生成电子邮件并发送。

问题是我正在从签名文件中读取HTML并将其存储在变量中,然后将其附加到现有的HTMLBody。

有效。但是签名文件HTML中包含的任何图片都不会显示。

我已经尝试编写一个额外的脚本,将html文件中图片的简写地址替换为FULL目录,希望能解决它。不行。

有没有办法确保签名文件中包含的任何图片实际显示在电子邮件中?

这是我的签名文件HTML阅读器/编辑器

def altersigfile(file):
    fullDir = file
    newDir = fullDir.rsplit("\\",1)[0]
    subDir = fullDir.rsplit("\\", 1)[1]
    subDir = subDir.replace(" ", "%20")
    subDir = subDir.strip(".htm")
    subDir += "_files"
    newDir += "/" + subDir
    newDir = newDir.replace("\\", "/")
    newsigfile = ""

    with open(fullDir,"r") as file:
        for line in file:

            if "src=" in line:
                check = ""
                newline = ""
                check = r'src="' + subDir
                newline = re.sub(subDir, newDir, line)
                newsigfile += newline

            else:
                newsigfile += line



    return newsigfile

这是我的电子邮件脚本:

def emailer(sendFrom, sendTo, subject, cc, bcc, body, sigfile=None,     auto=False, useSig=False):
ol = win32.Dispatch('Outlook.Application')
msg = ol.CreateItem(0)

#DO NOT CHANGE: the below script is the only way you were able to get outlook to register what email you give it. 
b=False
for i in range(1,ol.Session.Accounts.Count+1):

    if ol.Session.Accounts.Item(i).SmtpAddress == sendFrom:
        sendFrom = ol.Session.Accounts.Item(i)
        b=True
        break

if b==False:
    messagebox.showinfo("Invalid Address",
                        """The email address you entered ({email}), is not an authorized outlook email address. Please verify the email address you provided and make sure it is authorized in your outlook.""".format(email = sendFrom))
    return

msg._oleobj_.Invoke(*(64209, 0, 8, 0, sendFrom))
#end of DO NOT CHANGE

msg.To = sendTo
msg.Subject = subject

if cc:
    msg.CC = sendFrom

if bcc:
    msg.BCC = ol.Session.Accounts.Item(1).SmtpAddress

msg.HTMLBody = body


#currently this does add the sigfile html file held by outlook. However... the picture doesnt load. :(

if useSig==True:
    signature = altersigfile(sigfile)
    msg.HTMLBody += signature
    print(msg.HTMLBody)

重申一下。除了不会显示签名文件中包含的图片之外,上述内容仍然有效。这是唯一的错误,我似乎无法找到一种方法使它工作。 任何帮助将不胜感激。谢谢。

P.S。抱歉第二批代码中的格式化。对于我的生活,我似乎无法正确格式化。

2 个答案:

答案 0 :(得分:1)

万一有人好奇。这就是我在空闲时的表现:

import win32com.client as win32
import re
ol = win32.Dispatch('Outlook.Application')
msg = ol.CreateItem(0)
msg.GetInspector
bodystart = re.search("<body.*?>", msg.HTMLBody)
msg.HTMLBody = re.sub(bodystart.group(), bodystart.group()+"Hello this is a test body", msg.HTMLBody)

这里的关键部分是正则表达式。 基本上如下一行:

bodystart = re.search("<body.*?>", msg.HTMLBody)

上面的代码行会查找&#34; body&#34;的完整字符串。随后是任何数量的任何字符&#34;。*&#34;但不是贪婪的方式&#34;?&#34;然后以&#34;&gt;&#34;结束 一旦我有了,我只需用匹配的字符串替换匹配的字符串+我想要的电子邮件正文。 G2G。

答案 1 :(得分:0)

其他几种选择。

  1. Redemption通过RDOSession.Signatures集合公开签名,其RDOSignature对象公开ApplyTo方法,将签名(文本,图片,样式)复制到指定的消息。

  2. 如果你想要的只是默认签名,那么让Outlook完成这项工作 - 当Outlook显示消息(MailItem.Display)时,或者当Outlook认为你很快就会通过访问MailItem.GetInspector财产。只要您调用MailItem.DisplayMailItem.GetInspector,只要您尚未使用Body或HTMLBody属性设置邮件正文,邮件正文就会添加签名。您现在要做的就是阅读HTMLBody属性(只有签名),将文本合并到该值中,然后重新设置HTMLBody属性。请注意,您不能简单地连接两个HTML字符串,它们必须合并。