Powershell : How to Listen to your Outlook Emails like a Voicemail


I’m a big fan of Tony Stark ( Iron Man 😉 ) and his personal assistant Jarvis, which is a program that interacts with Tony and provides him variety of information.

Well, here we’re not even close to Jarvis, but nothing wrong with an attempt in making a program that enable you to listen to your emails just like you listen to your voice mails over phone. Just think if you’re a heavy outlook user and you read tons of emails everyday, how easy it would be if you can relax in your chair and listen to your emails.

Microsoft had already covered half of the path for us and Provided us the Speech API, We’ve to just cover the other half.

The Speech Application Programming Interface or SAPI is an API developed by Microsoft to allow the use of speech recognition and speech synthesis within Windows applications and we would be using this API to give voice to our script.

Enough of talking now, now lets get to business now.Our script is structured over below action items

STEPS INVOLVED: 

1. Use outlook API to get Access to outlook information
2. Create Speech API objects.
3. Data mine outlook for Information/ Emails you are expecting.
4. [OPTIONAL] Customize SAPI to clean the message body or to greet you as per your local time.
5. Feed the extracted information to SAPI objects to give them voice.

1. Use outlook API to get Access to outlook information :

You have all your emails structured under your outlook in folders and sub-folders which could be accessed using the Micrososft office API. So first of use COM object to create outlook object.

# Invoking Outlook API and creating Objects
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Outlook")| Out-Null
$outlook = new-object -ComObject 'Outlook.Application'

You can then access the namespace – MAPI (Messaging API) , to dig the Outlook Stores and Folder available to you, like in below fashion :

((($outlook.getnamespace(“MAPI”)).Folders).FolderPath)

Which will give you output like below, depending upon your configurations.

SAPI

Once you have outlook namespace, you can access inbox which is default folder number  ‘6‘ , and Retrieve the Unread emails count from Inbox folder.

# Getting available namesapces, to navigate to Inbox 
$ns = $outlook.getnamespace("MAPI")
$inbox = $ns.GetDefaultFolder(6)
$unreadcount =$inbox.unreaditemcount

 2. Create SAPI objects :

Now you should create you Speech API object so that you can feed these objects the data you’ve retrieved.
Here, We can alter the rate of speech of the SAPI voice using the .Rate property.

~ $Siri is the name of variable and is inspired from iOS voice assistant Siri 😉 

# Creating object of Speech Application Programming Interface
$Siri = (New-Object -ComObject SAPI.SPVoice)
$Siri.Rate = -2  #Used to define the rate of speech

3. Data mine outlook :

$Inbox is object of your inbox folder, you can use .Folder property to access all its sub folders.

# Traversing each and every Sub-folder of your outlook and speaking you the unread email counts per folder
$inbox.folders | ?{$_.unreaditemcount -ne 0}|foreach{ $Siri.Speak("$($_.name) Sub folder has $($_.unreaditemcount) unread emails") | Out-Null}

You can also target a special folder like your Manager sub folder highlighted below under Inbox or Inbox itself.

# Targeting a special folder where you want SAPI to read each unread mail for you
$TargetFolder = $inbox.folders| ?{$_.name -like '*manager*'} #Could be your Manager's folder

And retrieve all unread emails form this folder.

# Within the target folder Data mine the unread emails sent to you
$emails = $TargetFolder.items | select -Last 100 | ?{$_.unread -eq $true -and $_.to -like 'Prateek*'} | sort receivedtime -Descending

4. [OPTIONAL] Customize SAPI to clean the message body or to greet you : 

If you want to your scripts to greet you depending upon the time of the day, or remove any special characters from the email body to refine the speech of SAPI voice. You can add below two functions to top of the script.

# This function Greets you Depending upon the Time of the day
function get-Greeting()
{
$Hour = (Get-Date).TimeOfDay.Hours
if($Hour -ge 0 -and $Hour -lt 12)
{
 $greet = "Good Morning"
}
elseif($Hour -ge 12 -and $Hour -lt 16)
{
 $greet = "Good After noon"
}
else
{
 $greet = "Good Evening"
}
return $greet
}
# This function removes and unwanted special character that make the Speech difficult to understand
function Clean-String($Str)
{
$Ht = @{
'#' = ' '
'<' = ' ' '>' = ' '
'*' = ' '
}
$SpecialChar = "[$(-join $ht.Keys)]"
$FinalStr = [regex]::Replace($Str,$SpecialChar,{$ht[$args[0].value]})
Return $FinalStr
}

5. Feed the information to SAPI objects to give them voice :

Now once you have Extracted email messages and Structured them in format that SAPI can read properly and fluently, you can feed them to SAPI Speak() function like below to give them voice like below.

if($emails.Count -eq 0)
{
$siri.Speak("No Unread Emails to you found, sent from Manager")
}
else
{
$Siri.Speak("Total of $($emails.count) unread emails found, loading each email one by one")
$i=1
foreach($e in $emails)
{
$subject = $e.subject
$subject = Clean-String $subject # Removing special characters
$body = $e.body
$body = Clean-String $body # Removing special characters
# Creating message format for SAPI
$q = "Subject : " + $subject + "`n" + "Message : " + (($body) -split "From:")[0] # Splits the message and outputs only the top email not the trailing ones
$q.tolower() #Convert the message format to lowercase as SAPI reads Capital Alphabets differently
$siri.Speak("Message $i . $q") | Out-Null
$i++
}
}

Once you run the Complete Script, it will Greet you depending upon the time and provide you Unread email count information of your inbox and each of its sub folder. Moreover it will read each an every unread email on a custom folder you specify just like your voice mail.

COMPLETE SCRIPT :

Click on below link to auto-download the complete script and start rolling
Outlook_Using_SAPI

NOTE :  Please run the script and outlook on same permission level, i.e If you Outlook is running as Administrator, run the script as Administrator as well.

This is how you must Listen to your emails like a Pro, in Iron Man style 😀 😉

Hope this was useful and you enjoyed reading it. Please comment below if you think of some addition to the script.

Happy Reading Folks 🙂

Advertisements

4 thoughts on “Powershell : How to Listen to your Outlook Emails like a Voicemail

  1. Does this matter what version of Outlook client your using? I’m using 2013, it can read the unread email count but nothing else. I would like for it to read the emails in my inbox, as its the only folder i use for email but can’t get it to work. Any ideas?

    Like

  2. @Robert,
    I don’t think outlook Client ver will make any difference, because we are instantiating outlook application and will make an object irrespective of outlook version.

    Please make sure you have unread emails in your inbox, and you have tweak the script to read emails from inbox, because script was written to read unread emails in a specific folder.

    # Invoking Outlook API and creating Objects
    [Reflection.Assembly]::LoadWithPartialName(“Microsoft.Office.Interop.Outlook”)| Out-Null
    $outlook = new-object -ComObject ‘Outlook.Application’

    Like

  3. I get an error for 2013 client.. see below:

    PS C:\WINDOWS\system32> new-object -ComObject ‘Outlook.Application’
    new-object : Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
    At line:1 char:1
    + new-object -ComObject ‘Outlook.Application’
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
    + FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand

    Like

  4. Make sure that Outlook and Powershell are either both running as a standard user (not elevated) or that they are both running elevated as Administrator. They need to be running at the same integrity level to avoid that error.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s