在Outlook收件箱及其所有子文件夹中收到电子邮件后运行Python脚本。

huangapple go评论73阅读模式
英文:

Run a Python script on receiving email in the inbox and all it's sub folders in Outlook

问题

抱歉,我无法完成您的要求。

英文:

I have a VBA script in ThisOutlookSession I want to call a Python script when an email arrives in my inbox.

My inbox has rules to move emails from specific senders into sub folders. When an email comes in that has a rule applied, my Python script does not get called.

I have looked at some solutions but they all appear to be hard coded in that the sub folders are directly referenced. I want to use this setup in my organsiation where I will have many users and inboxes with differing sub folder structures, so I am looking for a less hard coded solution.

I also understand that it may not be best to use rules and instead implement their functionality directly into the VBA script. As I wish to expand this to many users whilst retaining their ability to create new rules, I cannot use this method as it will require too much work to maintain when users want new rules.

Private WithEvents olItems As Outlook.Items

Private Sub Application_Startup()

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set olItems = olNS.GetDefaultFolder(olFolderInbox).Items

Debug.Print "Application_Startup triggered " & Now()

End Sub


Private Sub olItems_ItemAdd(ByVal item As Object)

Dim my_olMail As Outlook.MailItem

If TypeName(item) = "MailItem" Then

    Dim obj As Object
    Dim PythonExe As String
    Dim Script As String

    Set obj = VBA.CreateObject("Wscript.Shell")

    PythonExe = """C:\python"""

    Script = Environ("userprofile") & "\Python-Scripts\Outlook-Sound-Lock-Screen\play-sound.py"
    Debug.Print "Script Path: " & Script

    obj.Run "cmd /c cd /d" & PythonExe & "&& " & "python" & " " & Script, 0, True
    
    Set my_olMail = item
        Debug.Print "Sender: "; my_olMail.SenderEmailAddress & " | Subject: " & my_olMail.Subject
    Set my_olMail = Nothing
    
End If

End Sub

答案1

得分: 0

不使用处理仅适用于单个文件夹的ItemAdd事件,而是使用Outlook Application类的NewMailEx事件。该事件对由Microsoft Outlook处理的每个接收到的项目触发一次。该项目可以是多种不同类型的项目,例如MailItemMeetingItemSharingItemEntryIDsCollection字符串包含与该项目对应的Entry ID。使用EntryIDCollection字符串返回的Entry ID调用NameSpace.GetItemFromID方法并处理该项目。

NewMailEx事件在新邮件到达Inbox并在客户端规则处理之前触发。这意味着新邮件在Outlook规则可能将其传输到任何其他文件夹之前由事件处理程序处理。然而,根据客户端计算机的设置,新消息到达收件箱后,诸如垃圾邮件过滤和将新消息从收件箱移动到其他文件夹的客户端规则等处理可能是异步的。您不应假设在这些事件触发后,收件箱中的项目数量总是会增加一个。

此外,您可以考虑在需要处理已添加项目的每个文件夹上设置ItemAdd事件处理程序。


我还注意到以下包含问题的代码片段:

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")

其中olApp对象未正确初始化。在Outlook VBA环境中,请使用可用的Application属性,而不是命名空间:

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")

希望这样说得通。

英文:

Instead of handling the ItemAdd event which is fired for a single folder you need to use the NewMailEx event of the Outlook Application class which is fired once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item. Use the Entry ID returned by the EntryIDCollection string to call the NameSpace.GetItemFromID method and process the item.

The NewMailEx event fires when a new message arrives in the Inbox and before client rule processing occurs. That means the new email is processed by the event handler before an Outlook rule may transfer it to any other folder. However, depending on the setup on the client computer, after a new message arrives in the Inbox, processes like spam filtering and client rules that move the new message from the Inbox to another folder can occur asynchronously. You should not assume that after these events fire, you'll always get a one-item increase in the number of items in the Inbox.

Also you may consider setting up the ItemAdd event handler on every folder where you need to process added items.


I have also noticed the following piece of code which contains an issue:

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")

Where the olApp object is not initialized correctly. Use the Application property available in Outlook VBA environment instead, not a namespace:

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")

Hope that makes sense.

答案2

得分: 0

以下是您要的代码部分的中文翻译:

根据Eugene Astafiev的建议,我已经能够在收件箱和其子文件夹中收到新邮件时触发我的Python脚本。我还解决了Eugene Astafiev提出的与olApp初始化相关的问题。

Private Sub Application_Startup()

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Application
Set olNS = olApp.GetNamespace("MAPI")

Debug.Print "Application_Startup triggered " & Now()

End Sub

Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)

    Dim obj As Object
    Dim PythonExe As String
    Dim Script As String

    Set obj = VBA.CreateObject("Wscript.Shell")

    PythonExe = """C:\python"""

    Script = Environ("userprofile") & "\Python-Scripts\Outlook-Sound-Lock-Screen\play-sound.py"

    obj.Run "cmd /c cd /d" & PythonExe & "&& " & "python" & " " & Script, 0, True

End Sub

希望这对您有所帮助。

英文:

Following Eugene Astafiev's advice to use the NewMailEx() event I have been able to trigger my python script upon receiving a new email in the inbox and it's sub folders. I also fixed the issue related to the initialisation of the olApp raised by Eugene Astafiev.

<!-- language: lang-vb -->

Private Sub Application_Startup()

Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace

Set olApp = Application
Set olNS = olApp.GetNamespace(&quot;MAPI&quot;)

Debug.Print &quot;Application_Startup triggered &quot; &amp; Now()

End Sub

Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)

    Dim obj As Object
    Dim PythonExe As String
    Dim Script As String

    Set obj = VBA.CreateObject(&quot;Wscript.Shell&quot;)

    PythonExe = &quot;&quot;&quot;C:\python&quot;&quot;&quot;

    Script = Environ(&quot;userprofile&quot;) &amp; &quot;\Python-Scripts\Outlook-Sound-Lock-Screen\play-sound.py&quot;

    obj.Run &quot;cmd /c cd /d&quot; &amp; PythonExe &amp; &quot;&amp;&amp; &quot; &amp; &quot;python&quot; &amp; &quot; &quot; &amp; Script, 0, True

End Sub

huangapple
  • 本文由 发表于 2023年2月16日 19:15:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75471468.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定