Macro of the Day: Send Email to [OutlookContact]
Today's macro let's you say things like "Send email to Rob", or "Send email to Rob Chambers", and as long as I'm a contact in your Outlook Contacts, you can send me mail! It also allows you to say "Send email to Rob Chambers about That cool outlook macro", it'll open up Outlook, create a new email, put me as the recipient, and it'll set the subject to "That cool outlook macro". Neat, eh?
Today's macro was inspired by Brad, over in the ms-speech Yahoo! Group, who asked me if WSR Macros could dynamically create rule content last week. Well, Brad, yes it can! Here's an example.
The most interesting part of today's macro, is the ruleScript element that allows you to define a rule programmatically. The key to this script is that it will find content to add to the rule by hooking up to Outlook's object model (using Create Object("Outlook.Application")), and then call the Rule.Items.AddItem method for each email address it finds.
That ruleScript looks like this:
<ruleScript name="OutlookContact" propname="EmailAddr" language="VBScript">
<![CDATA[
Call AddOutlookContactsSub AddOutlookContacts
REM Debug.DebugBreak
Debug.Trace chr(13) & "Adding OutlookContacts..." & chr(13)Const olFolderContacts = 10
Const olMSG = 3Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")Set colContacts = objNamespace.GetDefaultFolder(olFolderContacts).Items
For Each objContact in colContacts
If TypeName(objContact) = "ContactItem" Then
If objContact.FullName <> "" Then
If objContact.Email1Address <> "" Then Rule.Items.AddItem objContact.FullName, objContact.Email1Address, True
If objContact.Email2Address <> "" Then Rule.Items.AddItem objContact.FullName, objContact.Email2Address, True
If objContact.Email3Address <> "" Then Rule.Items.AddItem objContact.FullName, objContact.Email3Address, True
End If
End If
Next
For Each objRuleItem in Rule.Items
Debug.Trace objRuleItem.Phrase & " (" & objRuleItem.Property & ")" & chr(13)
Next
Debug.Trace "--" & chr(13) & "Added " & Rule.Items.Count & " items!" & chr(13)End Sub
]]>
</ruleScript>
There are a couple other interesting things in today's macro:
- I used a Debug.DebugBreak method (currently commented out above), to allow me to debug the macro interactively in Microsoft Visual Studio Express. This is a handy way of single stepping over each and every line in the code. If you have VS installed, when the macro hits that line (if you uncomment it), you'll be asked what debugger to use to debug the macro's script. You pick VS, and then you have F10 single-step control over the macro as it executes. You can do fun things like inspect variables, change flow, etc... All really cool stuff that developers using Microsoft Development tools have grown accustomed to doing.
- I also used Debug.Trace to output to VS what's going on in the macro, so even if I'm not single step debugging it, I can see what contacts got added.
- I used the disambiguate tag to allow the user to disambiguate what email address to use if it's ambiguous. So, for example, if I have 3 people named Rob in my contacts, it'll allow me to pick which one I wanted to send email to. In fact, it'll even show me the email addresses in parenthesis after the person's full name.
Here's the entire macro:
<speechMacros>
<command priority="2">
<listenFor>send email to [OutlookContact]</listenFor>
<listenFor>send email to [OutlookContact] about [subject...]</listenFor>
<disambiguate title="Send email to whom?" prompt="Who would you like to send email to?" timeout="30" propname="OutlookContact"/>
<script language="VBScript">
<![CDATA[
Set outlookApp = CreateObject("Outlook.Application")
olMailItem = 0
Set newMessage = outlookApp.CreateItem(olMailItem)
newMessage.Recipients.Add("{[OutlookContact.EmailAddr]}")
newMessage.Subject = "{[subject...]}"
newMessage.Display
]]>
</script>
</command>
<command priority="1">
<listenFor>send email</listenFor>
<listenFor>send email to *</listenFor>
<listenFor>send email to * about [subject...]</listenFor>
<script language="VBScript">
<![CDATA[
Set contacts = CommandSet.RuleGenerators("OutlookContact")
For Each item in contacts.Rule.Items
ChooseFromList.Items.AddItem item.Phrase, item.Property, True
Next
ChooseFromList.Items.Sort
chose = ChooseFromList.Choose("Send email to whom?", "Who would you like to send email to?")
If chose > 0 Then
Set outlookApp = CreateObject("Outlook.Application")
olMailItem = 0
Set newMessage = outlookApp.CreateItem(olMailItem)
newMessage.Recipients.Add(ChooseFromList.Items(chose).Property)
newMessage.Subject = "{[subject...]}"
newMessage.Display
End If
]]>
</script>
</command>
<command>
<listenFor>Refresh ?Outlook Email Contacts</listenFor>
<listenFor>Refresh Outlook ?Email Contacts</listenFor>
<script language="VBScript">
<![CDATA[
Set contacts = CommandSet.RuleGenerators("OutlookContact")
contacts.Rule.Items.RemoveAll
contacts.Script.AddOutlookContacts
contacts.Rule.Commit
]]>
</script>
</command>
<ruleScript name="OutlookContact" propname="EmailAddr" language="VBScript">
<![CDATA[
Call AddOutlookContacts
Sub AddOutlookContacts
REM Debug.DebugBreak
Debug.Trace chr(13) & "Adding OutlookContacts..." & chr(13)
Const olFolderContacts = 10
Const olMSG = 3
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set colContacts = objNamespace.GetDefaultFolder(olFolderContacts).Items
For Each objContact in colContacts
If TypeName(objContact) = "ContactItem" Then
If objContact.FullName <> "" Then
If objContact.Email1Address <> "" Then Rule.Items.AddItem objContact.FullName, objContact.Email1Address, True
If objContact.Email2Address <> "" Then Rule.Items.AddItem objContact.FullName, objContact.Email2Address, True
If objContact.Email3Address <> "" Then Rule.Items.AddItem objContact.FullName, objContact.Email3Address, True
End If
End If
Next
For Each objRuleItem in Rule.Items
Debug.Trace objRuleItem.Phrase & " (" & objRuleItem.Property & ")" & chr(13)
Next
Debug.Trace "--" & chr(13) & "Added " & Rule.Items.Count & " items!" & chr(13)
End Sub
]]>
</ruleScript>
</speechMacros>
Comments
- Anonymous
June 09, 2008
Another awesome macro! I was trying to do something similar but it wasn't working out. Is there a way you could a part that will read back someone's contact information. For instance, "What is John Smith's business phone number?"