Jump to content
Macro Express Forums

Challenge: Automatically copy the sender's address from an email message


Recommended Posts

This morning I realized I spend time almost every day, when using Outlook, copying sender's email addresses and pasting them elsewhere. Copying email addresses is a fiddly, multi-step process.

 

For example, when I manually select the email address from the field that contains the sender's information, the field displays this:

 

sandysmith@mail.com

 

But when I select and copy the line, this is what ends up in the clipboard:

 

Sandy Smith  <sandysmith@mail.com>

 

I don't want the person's name or the braces in the clipboard. Just the email address. And why should I navigate to fields, select text, and copy when a macro can do all three? :)

 

My first attempt to automate the process using Macro Express seemed to work. But then I discovered the script failed with Plain Text messages. Back to the drawing board!

 

I think I now have a solution. Scripting was trickier than I thought it would be. But I can see already this macro is going to be a great time-saver.

 

The challenge: In whatever email application you use, write a Macro Express script to automatically copy the sender's email address from a message, without the need for you to manually navigate to a field, move the cursor, select text, or copy. The macro should do all the heavy lifting.

I'll post a solution for Outlook soon.

Link to comment
Share on other sites

I would create an Outlook rule to print the messages to file using the generic Microsoft ASCII text file printer. Then have a macro activation for folder contents changing that would extract the email address from the text file. This way it could all happen invisibly without the complications of the GUI.

Link to comment
Share on other sites

  • acantor changed the title to Challenge: Automatically copy the sender's address from an email message

Hi Cory,

 

Avoiding keyboard and mouse interactions with the Outlook user interface would be an advantage. I tried to implement your idea, but couldn't figure out how to create a rule to output a message to a text file. Please elaborate!

 

Your idea did give me an idea for a second method to extract the sender's email address, but the method involves sending keystrokes to the user interface! (I was able to use Window Controls for parts of the script, but in the end, I got more consistent results when I sent keystrokes.)

Link to comment
Share on other sites

The method to capture the Sender’s email address will be different for every email program. The method might even vary in different versions of the same program.

 

The following script is for Outlook 2019. Note that this only works for email messages that have already been received, e.g., messages in the Inbox or other folders. The script wasn't designed for messages that you're in the process of writing.

 

Although I found several solutions to extract the Sender’s email address from an email message in Outlook 2019, some solutions worked more reliably and/or faster than others.

 

Here are approaches I abandoned :

 

1.    Forward the message. Tab into the body field. Select the entire message and copy to the clipboard. Close the forwarded message. Assign the clipboard to a text variable. Parse the variable to identify the email address. Assign the email address to the clipboard.

2.    Save the email message to a temporary text-only file. (In Outlook, F12 is the “Save As…” shortcut.) Read the file into a text variable. Delete the temporary file. Parse the variable to identify the email address. Assign the email address to the clipboard.  

3.    Open the "Properties" window for the email message. (In Outlook 2019, use this four-step key sequence: F10, h, o, p.) Navigate to the Internet Headers field. Copy the field to the clipboard. Close the Properties window. Assign the content of the field to a text variable. Parse the variable to identify the email address. Assign the email address to the clipboard.

 

Here's the approach I ended up using:

 

1. Press Shift + Tab repeatedly to navigate backwards between the regions in the message. (This gives focus to every region, and then wraps around to the bottom of the message body.)

2. After each Shift + Tab, capture the control for the region and get its class.

 

3. Test if "ToolbarWindow32" is the control class...

   ...If yes, navigate to the field containing the Sender’s email address by pressing Shift + Tab once.

   ...If no, repeat from Step 1.

 

4. Select field that contains the Sender's email address. Copy, assign to a variable, and parse. Assign to clipboard.

 

5. If we began on the main Outlook UI, press Esc to close the message...

    ...Otherwise, press Shift + Tab 3 times to give focus to the message body. Press Home to go to the top of the message.

 

The macro seems to be mostly reliable, but I’m still tinkering with the length of delays. If you try the macro and the macro fails, try making all of the delays a little longer.

// Extract sender's email address from an Outlook message and assign to the clipboard. How it works:
 
// 0. Note whether the main Outlook UI is open, or if a message is open...
//    ... If this is the main UI, open the focused message by pressing Enter.
// 1. Press Shift + Tab repeatedly to navigate backwards between the regions in the email message.
//    (This method gives focus to every regionl, then wraps around to the bottom of the message body.)
// 2. With each Shift + Tab, capture the control for the region, and get its class. 
// 3. Test if "ToolbarWindow32" is the focused control class...
//    ...If yes, press Shift + Tab to reach the field containing the Sender’s email address.
//    ...If no, repeat from Step 1.
// 4. Select field with Sender's email. Copy, assign to variable, and parse. Assign to clipboard. 
// 5. If we began on the main Outlook UI, press Esc to close the message...
//    ...Otherwise, press Shift + Tab 3x to give focus to the message body, and press Home to go to the top.
 
// Is this the main Outlook UI? If yes open the message and set a Boolean flag.
If Window " - Outlook" is focused
  Text Type (Simulate Keystrokes): <ENTER>
  Delay: 100 milliseconds
  If Not Window "- Message (" is focused // Ensure a message is open. If not, signal an error and quit.
    MessageBox: Cannot capture Sender's address
    Macro Stop
  End If
  Variable Set Bool %IsMainOutlookUI% to "True"
End If
 
// Is this NOT a message that has already been received? If yes, Quit.
If Not Window "- Message (" is focused
  MessageBox: Cannot capture Sender's address
  Macro Stop
End If
 
// Otherwise, proceed as though this is a valid message,  with "- Message (" in the titlebar.
Variable Set String %Class% to "Nothing"
 
// Cycle backwards through interface regions by pressing Shift + Tab. Continue until we reach the toolbar.
Repeat Until %Class% Equals "ToolbarWindow32"
  Text Type (Simulate Keystrokes): <SHIFT><TAB>
  Capture Control from Focused Control into %OutlookControl%
  Delay: 20 milliseconds // (May need to adjust several delays to improve reliability)
  Get Control Class from %OutlookControl% into %Class%
  Delay: 5 milliseconds
End Repeat
 
// Navigate backwards one more region. This is the field containing the Sender's email. Select and copy it.
Text Type (Simulate Keystrokes): <SHIFT><TAB>
Delay: 20 milliseconds
Text Type (Simulate Keystrokes): <HOME><SHIFT><END> // Select the field
Delay: 100 milliseconds // (50 ms occasionally fails)
Clipboard Copy
 
Variable Set String %Clip% from the clipboard contents
 
// Parse content of field. If it contains a "<" then assume email address is between "<" and ">".
If Variable %Clip% Does not Contain "<"
  Variable Set String %EmailAddress% to "%Clip%"
Else
  Variable Set Integer %StartPos% to the position of "<" in %Clip%
  Variable Modify String: Delete part of text from %Clip% starting at 1 and %StartPos% characters long
  Variable Set Integer %EndPos% to the position of ">" in %Clip%
  Variable Modify Integer: %EndPos% = %EndPos% - 1
  Variable Modify String: Copy part of text in %Clip% starting at 1 and %EndPos% characters long to %EmailAddress%
End If
 
Variable Modify String: Save %EmailAddress% to the clipboard
 
// If we began in main Outlook UI, press Esc to return. Else, give focus to the body, and go to the top.
If Variable %IsMainOutlookUI% Equals "True"
  Text Type (Simulate Keystrokes): <ESC>
Else
  Repeat Start (Repeat 3 times)
    Text Type (Simulate Keystrokes): <SHIFT><TAB>
    Delay: 200 milliseconds
  End Repeat
  Text Type (Simulate Keystrokes): <HOME>
End If
 
// Briefly display the captured email address
Text Box Display: Extracted Email Address
Delay: 1000 milliseconds
Text Box Close: Extracted Email Address

<COMMENT Value="Extract sender's email address from an Outlook message and assign to the clipboard. How it works:" _BACK="0080FFFF"/>
<COMMENT/>
<COMMENT Value="0. Note whether the main Outlook UI is open, or if a message is open..." _BACK="0080FFFF"/>
<COMMENT Value="   ... If this is the main UI, open the focused message by pressing Enter." _BACK="0080FFFF"/>
<COMMENT Value="1. Press Shift + Tab repeatedly to navigate backwards between the regions in the email message." _BACK="0080FFFF"/>
<COMMENT Value="   (This method gives focus to every regionl, then wraps around to the bottom of the message body.)" _BACK="0080FFFF"/>
<COMMENT Value="2. With each Shift + Tab, capture the control for the region, and get its class. " _BACK="0080FFFF"/>
<COMMENT Value="3. Test if \"ToolbarWindow32\" is the focused control class..." _BACK="0080FFFF"/>
<COMMENT Value="   ...If yes, press Shift + Tab to reach the field containing the Senders email address." _BACK="0080FFFF"/>
<COMMENT Value="   ...If no, repeat from Step 1." _BACK="0080FFFF"/>
<COMMENT Value="4. Select field with Sender's email. Copy, assign to variable, and parse. Assign to clipboard. " _BACK="0080FFFF"/>
<COMMENT Value="5. If we began on the main Outlook UI, press Esc to close the message..." _BACK="0080FFFF"/>
<COMMENT Value="   ...Otherwise, press Shift + Tab 3x to give focus to the message body, and press Home to go to the top." _BACK="0080FFFF"/>
<COMMENT/>
<COMMENT Value="Is this the main Outlook UI? If yes open the message and set a Boolean flag." _BACK="0080FFFF"/>
<IF WINDOW Option="\x00" Title=" - Outlook" Partial="TRUE" Wildcards="FALSE"/>
<TEXT TYPE Action="0" Text="<ENTER>"/>
<DELAY Flags="\x02" Time="100"/>
<IF NOT WINDOW Option="\x00" Title="- Message (" Partial="TRUE" Wildcards="FALSE" _COMMENT="Ensure a message is open. If not, signal an error and quit."/>
<MESSAGEBOX Caption="Cannot capture Sender's address" Message="This script captures the address from already received emails." Icon="4"/>
<MACRO STOP/>
<END IF/>
<VARIABLE SET BOOL Destination="%IsMainOutlookUI%" Command="263" Value="TRUE"/>
<END IF/>
<COMMENT/>
<COMMENT Value="Is this NOT a message that has already been received? If yes, Quit." _BACK="0080FFFF"/>
<IF NOT WINDOW Option="\x00" Title="- Message (" Partial="TRUE" Wildcards="FALSE"/>
<MESSAGEBOX Caption="Cannot capture Sender's address" Message="This script captures the address from already received emails." Icon="4"/>
<MACRO STOP/>
<END IF/>
<COMMENT/>
<COMMENT Value="Otherwise, proceed as though this is a valid message,  with \"- Message (\" in the titlebar." _BACK="0080FFFF"/>
<VARIABLE SET STRING Option="\x00" Destination="%Class%" Value="Nothing" NoEmbeddedVars="FALSE"/>
<COMMENT/>
<COMMENT Value="Cycle backwards through interface regions by pressing Shift + Tab. Continue until we reach the toolbar." _BACK="0080FFFF"/>
<REPEAT UNTIL Variable="%Class%" Condition="\x00" Value="ToolbarWindow32"/>
<TEXT TYPE Action="0" Text="<SHIFT><TAB>"/>
<CAPTURE CONTROL Option="\x01" Control="%OutlookControl%" UseText="FALSE"/>
<DELAY Flags="\x02" Time="20" _COMMENT="(May need to adjust several delays to improve reliability)"/>
<GET CONTROL CLASS TextVar="%Class%" ControlVar="%OutlookControl%"/>
<DELAY Flags="\x02" Time="5" _ENABLED="FALSE"/>
<END REPEAT/>
<COMMENT/>
<COMMENT Value="Navigate backwards one more region. This is the field containing the Sender's email. Select and copy it." _BACK="0080FFFF"/>
<TEXT TYPE Action="0" Text="<SHIFT><TAB>"/>
<DELAY Flags="\x02" Time="20"/>
<TEXT TYPE Action="0" Text="<HOME><SHIFT><END>" _COMMENT="Select the field"/>
<DELAY Flags="\x02" Time="100" _COMMENT="(50 ms occasionally fails)"/>
<CLIPBOARD COPY/>
<COMMENT/>
<VARIABLE SET STRING Option="\x02" Destination="%Clip%" NoEmbeddedVars="FALSE"/>
<COMMENT/>
<COMMENT Value="Parse content of field. If it contains a \"<\" then assume email address is between \"<\" and \">\"." _BACK="0080FFFF"/>
<IF VARIABLE Variable="%Clip%" Condition="\x07" Value="<" IgnoreCase="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%EmailAddress%" Value="%Clip%" NoEmbeddedVars="FALSE"/>
<ELSE/>
<VARIABLE SET INTEGER Option="\x0E" Destination="%StartPos%" Text_Variable="%Clip%" Text="<" Ignore_Case="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0A" Destination="%Clip%" Start="1" Count="%StartPos%"/>
<VARIABLE SET INTEGER Option="\x0E" Destination="%EndPos%" Text_Variable="%Clip%" Text=">" Ignore_Case="FALSE"/>
<VARIABLE MODIFY INTEGER Option="\x01" Destination="%EndPos%" Value1="%EndPos%" Value2="1"/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%EmailAddress%" Variable="%Clip%" Start="1" Count="%EndPos%" NoEmbeddedVars="FALSE"/>
<END IF/>
<COMMENT/>
<VARIABLE MODIFY STRING Option="\x10" Destination="%EmailAddress%" NoEmbeddedVars="FALSE"/>
<COMMENT/>
<COMMENT Value="If we began in main Outlook UI, press Esc to return. Else, give focus to the body, and go to the top." _BACK="0080FFFF"/>
<IF VARIABLE Variable="%IsMainOutlookUI%" Condition="\x00" Value="True" IgnoreCase="FALSE"/>
<TEXT TYPE Action="0" Text="<ESC>"/>
<ELSE/>
<REPEAT START Start="1" Step="1" Count="3" Save="FALSE"/>
<TEXT TYPE Action="0" Text="<SHIFT><TAB>"/>
<DELAY Flags="\x02" Time="200"/>
<END REPEAT/>
<TEXT TYPE Action="0" Text="<HOME>"/>
<END IF/>
<COMMENT/>
<COMMENT Value="Briefly display the captured email address" _BACK="0080FFFF"/>
<TEXT BOX DISPLAY Title="Extracted Email Address" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\lang4105\\f0\\fs40 [%EmailAddress%]\\lang1033\\f1\\fs14 \r\n\\par }\r\n" Left="239" Top="116" Width="1577" Height="233" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x02" Delay="3"/>
<DELAY Flags="\x02" Time="1000"/>
<TEXT BOX CLOSE Header="Extracted Email Address"/>

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...