Activate specific URL contained in an email message - Take 2

拜拜、爱过 提交于 2019-12-12 04:50:57

问题


First, thanks to all who have already assisted in the first iteration of this message. After looking around at other sites I found a better method for searching messages for URLs using regular expressions on this page, Open All Hyperlinks in an Outlook Email Message, on slipstick.com.

The my personal tweaking of the code is:

Option Explicit

Public Sub OpenLinksMessage()

 Dim olMail As Outlook.MailItem
 Dim Reg1 As RegExp
 Dim AllMatches As MatchCollection
 Dim M As Match
 Dim strURL As String
 Dim oApp As Object

 Set oApp = CreateObject("InternetExplorer.Application")

 Set olMail = ActiveExplorer.Selection(1)

 Set Reg1 = New RegExp

'Set the Regular Expression to search for any http:// or https:// format URL
'The Global feature says to look through the entire message text being tested
With Reg1
 .Pattern = "(https?[:]//([0-9a-z=\?:/\.&-^!#$;_])*)"
 .Global = True
 .IgnoreCase = True
End With

' If the regular expression test for URLs comes back true
If Reg1.test(olMail.Body) Then

'      Use the RegEx to return all instances that match it to the AllMatches group
       Set AllMatches = Reg1.Execute(olMail.Body)
       For Each M In AllMatches
               strURL = M.SubMatches(0)
'              Don't activate any URLs that are for unsubscribing; skip them
               If InStr(strURL, "unsubscribe") Then GoTo NextURL
'              If the URL ends with a > from being enclosed in darts, strip that > off
               If Right(strURL, 1) = ">" Then strURL = Left(strURL, Len(strURL) - 1)
'              We now have a URL that we want to open in a new tab in IE
               oApp.navigate strURL, CLng(2048)
               oApp.Visible = True

' wait for page to load before passing the web URL
  Do While oApp.Busy
    DoEvents
  Loop

  NextURL:
     Next
End If

Set Reg1 = Nothing

End Sub

Private Sub TestLaunchURL()
    OpenLinksMessage
End Sub

This will be running under Windows 10, and I am wondering if there is some way to substitute the statement:

 Set oApp = CreateObject("InternetExplorer.Application")

with its equivalent but snagging the application that the user has chosen as their default web browser? I'm also not certain of what, if any change, would be necessary to the Clng(2048) to communicate that I'd like the URL to be opened in a new tab of that browser rather than the one that currently has focus.

Would:

Set olMail = ActiveExplorer.Selection(1)

be the correct syntax for the "message I've just received" when this is being triggered by a rule for an incoming message? If not, what is?

Is that DO loop really necessary? I am trying to get a handle on what it does but really don't have it yet.

There should only be a single link in messages received from a specific e-mail address that should be parsed for the link and opened, but the test for that should be in the rule that invokes this subroutine rather than in the VBA code itself. I may have some additional filtering logic, but I think it will be a matter of adding an IF statement or two.

If anyone sees any glaring error in this adapted code please do let me know. It seems to be working on tests on individual messages, as IE opens and every link that's in the message is being opened in its own tab. I'd really like to make it open in the user's default web browser if at all possible.

Thanks in advance for your assistance. It has been invaluable already.


Phase 2: The script is thoroughly tested and works. It has been installed under Outlook 2016, we signed it with a certificate created with selfcert, the Trust Center Macro permissions are still at "Notifications for digitally signed macros, all other macros disabled."

When the the rule that invokes the script is run, and the script is triggered, the following error message box appears:

VBA error message box

Any theories on what went wrong and how to fix it? I have not yet created a second certificate with selfcert and signed this again because I wanted to know if this error message might pop up for other reasons, as sometimes happens.

Also, am I correct in believing that signed, user created macros will run, if signed, regardless of what the macro security is set to unless the setting is "all macros disabled"?


Phase 3.5 (sort of)

It appears the root of the problem is that the script itself is not being run at all when a new message arrives. I set up a testing rule that initially was to play a sound and invoke the script when a message arrives with either of two addresses in the sender's address. The sound would consistently play, but nothing else happened. So, I thought, let's take the sound playing out of the Outlook rule and put it in the script itself, with one sound playing unconditionally at the start of the script. Well, nada. Here is the latest code (some of which is taken directly from prior threads here on stackoverflow):

Option Explicit

Private Declare Function ShellExecute _
  Lib "shell32.dll" Alias "ShellExecuteA" ( _
  ByVal hWnd As Long, _
  ByVal Operation As String, _
  ByVal Filename As String, _
  Optional ByVal Parameters As String, _
  Optional ByVal Directory As String, _
  Optional ByVal WindowStyle As Long = vbMinimizedFocus _
  ) As Long

Private Declare Function sndPlaySound32 _
    Lib "winmm.dll" _
    Alias "sndPlaySoundA" ( _
        ByVal lpszSoundName As String, _
        ByVal uFlags As Long) As Long

Sub PlayTheSound(ByVal WhatSound As String)
    If Dir(WhatSound, vbNormal) = "" Then
        ' WhatSound is not a file. Get the file named by
        ' WhatSound from the Windows\Media directory.
        WhatSound = Environ("SystemRoot") & "\Media\" & WhatSound
        If InStr(1, WhatSound, ".") = 0 Then
            ' if WhatSound does not have a .wav extension,
            ' add one.
            WhatSound = WhatSound & ".wav"
        End If
        If Dir(WhatSound, vbNormal) = vbNullString Then
            Beep            ' Can't find the file. Do a simple Beep.
            Exit Sub
        End If
    Else
        ' WhatSound is a file. Use it.
    End If

    sndPlaySound32 WhatSound, 0&    ' Finally, play the sound.
End Sub

Public Sub OpenLinksMessage(olMail As Outlook.MailItem)

Dim Reg1 As RegExp
Dim AllMatches As MatchCollection
Dim M As Match
Dim strURL As String
Dim RetCode As Long

Set Reg1 = New RegExp

With Reg1
.Pattern = "(https?[:]//([0-9a-z=\?:/\.&-^!#$;_])*)"
.Global = True
.IgnoreCase = True
End With

PlayTheSound "chimes.wav"

' If the regular expression test for URLs in the message body finds one or more
If Reg1.test(olMail.Body) Then

'      Use the RegEx to return all instances that match it to the AllMatches group
       Set AllMatches = Reg1.Execute(olMail.Body)
       For Each M In AllMatches
               strURL = M.SubMatches(0)
'              Don't activate any URLs that are for unsubscribing; skip them
               If InStr(1, strURL, "unsubscribe") Then GoTo NextURL
'              If the URL ends with a > from being enclosed in darts, strip that > off
               If Right(strURL, 1) = ">" Then strURL = Left(strURL, Len(strURL) - 1)
'              The URL to activate to accept must contain both of the substrings in the IF statement
               If InStr(1, strURL, ".com") Then
                     PlayTheSound "TrainWhistle.wav"
'                    Activate that link to accept the job
                     RetCode = ShellExecute(0, "Open", "http://nytimes.com")
                     Set Reg1 = Nothing
                     Exit Sub
               End If

NextURL:
   Next

End If

Set Reg1 = Nothing

End Sub

Private Sub TestLaunchURL()
    Dim currItem As MailItem
    Set currItem = ActiveExplorer.Selection(1)
    OpenLinksMessage currItem
End Sub

If I trigger the above code either by using the TestLaunch subroutine via the debugger, or create a rule and at the end say "Run on messages already in the inbox," it functions perfectly.

The only thing I can't do right now is get this to be triggered using the "run script" feature of an Outlook Rule when a new message arrives.

Any theories or assistance regarding how to get over this last hurdle would be very much appreciated.


回答1:


This activates the specific URL. The part that plays the sound is not necessary.

Option Explicit

Private Declare Function ShellExecute _
  Lib "shell32.dll" Alias "ShellExecuteA" ( _
  ByVal hWnd As Long, _
  ByVal Operation As String, _
  ByVal Filename As String, _
  Optional ByVal Parameters As String, _
  Optional ByVal Directory As String, _
  Optional ByVal WindowStyle As Long = vbMinimizedFocus _
  ) As Long

Private Declare Function sndPlaySound32 _
    Lib "winmm.dll" _
    Alias "sndPlaySoundA" ( _
        ByVal lpszSoundName As String, _
        ByVal uFlags As Long) As Long

Sub PlayTheSound(ByVal WhatSound As String)
    If Dir(WhatSound, vbNormal) = "" Then
        ' WhatSound is not a file. Get the file named by
        ' WhatSound from the Windows\Media directory.
        WhatSound = Environ("SystemRoot") & "\Media\" & WhatSound
        If InStr(1, WhatSound, ".") = 0 Then
            ' if WhatSound does not have a .wav extension,
            ' add one.
            WhatSound = WhatSound & ".wav"
        End If
        If Dir(WhatSound, vbNormal) = vbNullString Then
            Beep            ' Can't find the file. Do a simple Beep.
            Exit Sub
        End If
    Else
        ' WhatSound is a file. Use it.
    End If

    sndPlaySound32 WhatSound, 0&    ' Finally, play the sound.
End Sub

Public Sub OpenLinksMessage(olMail As Outlook.MailItem)

Dim Reg1 As RegExp
Dim AllMatches As MatchCollection
Dim M As Match
Dim strURL As String
Dim RetCode As Long

Set Reg1 = New RegExp

With Reg1
.Pattern = "(https?[:]//([0-9a-z=\?:/\.&-^!#$;_])*)"
.Global = True
.IgnoreCase = True
End With

PlayTheSound "chimes.wav"

' If the regular expression test for URLs in the message body finds one or more
If Reg1.test(olMail.Body) Then

'      Use the RegEx to return all instances that match it to the AllMatches group
       Set AllMatches = Reg1.Execute(olMail.Body)
       For Each M In AllMatches
               strURL = M.SubMatches(0)
'              Don't activate any URLs that are for unsubscribing; skip them
               If InStr(1, strURL, "unsubscribe") Then GoTo NextURL
'              If the URL ends with a > from being enclosed in darts, strip that > off
               If Right(strURL, 1) = ">" Then strURL = Left(strURL, Len(strURL) - 1)
'              The URL to activate to accept must contain both of the substrings in the IF statement
               If InStr(1, strURL, ".com") Then
                     PlayTheSound "TrainWhistle.wav"
'                    Activate that link to accept the job
                     RetCode = ShellExecute(0, "Open", "http://nytimes.com")
                     Set Reg1 = Nothing
                     Exit Sub
               End If

NextURL:
   Next

End If

Set Reg1 = Nothing

End Sub

Private Sub TestLaunchURL()
    Dim currItem As MailItem
    Set currItem = ActiveExplorer.Selection(1)
    OpenLinksMessage currItem
End Sub

"If I trigger the above code either by using the TestLaunch subroutine via the debugger, or create a rule and at the end say "Run on messages already in the inbox," it functions perfectly." britechguy




回答2:


The answer to this question, including the code for same, has been answered by me on a follow up question I'd asked: Why does this regular expression test give different results for what should be the same body text?

Please refer to the answer on that thread for the solution.



来源:https://stackoverflow.com/questions/45535614/activate-specific-url-contained-in-an-email-message-take-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!