param( [Parameter(Mandatory=$true)] [ValidateSet("unread_count","latest","send_clipboard","summarize_inbox")] [string]$Action, [string]$Recipient = "", [string]$Body = "", [int]$Limit = 5 ) $ErrorActionPreference = 'Stop' $OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 # Output protocol (parsed by Lua scripts): # First line: "OK" or "ERR:" or "ERR::" # Subsequent lines depend on Action: # unread_count -> "" # latest -> "FROM\t" / "SUBJECT\t" / "PREVIEW\t" # send_clipboard -> "TO\t" / "ADDR\t" / "SUBJECT\t" # summarize_inbox -> repeated "FROM\t\tSUBJECT\t" # # All multiline strings get newlines collapsed to spaces before printing. function Clean-Line([string]$s) { if (-not $s) { return "" } $s = $s -replace "`r", " " -replace "`n", " " -replace "`t", " " return ($s -replace '\s+', ' ').Trim() } function Fail($code, $msg = "") { if ($msg) { Write-Output ("ERR:{0}:{1}" -f $code, (Clean-Line $msg)) } else { Write-Output ("ERR:{0}" -f $code) } exit 0 } function Get-OutlookSession { try { $ol = New-Object -ComObject Outlook.Application $ns = $ol.GetNamespace("MAPI") return @{ App = $ol; Ns = $ns } } catch { Fail "outlook_unavailable" $_.Exception.Message } } function Strip-Html([string]$s) { if (-not $s) { return "" } $s = [regex]::Replace($s, '<[^>]+>', ' ') $s = $s -replace ' ', ' ' -replace '&', '&' -replace '<', '<' -replace '>', '>' -replace '"', '"' -replace "'", "'" return Clean-Line $s } function Resolve-Recipient([object]$ns, [string]$query) { if ([string]::IsNullOrWhiteSpace($query)) { return $null } try { $r = $ns.CreateRecipient($query) $null = $r.Resolve() if ($r.Resolved) { $addr = $null try { $addr = $r.AddressEntry.GetExchangeUser().PrimarySmtpAddress } catch { } if (-not $addr) { try { $addr = $r.AddressEntry.Address } catch { } } if (-not $addr) { $addr = $r.Name } return @{ Name = $r.Name; Address = $addr } } } catch { } return $null } switch ($Action) { "unread_count" { $s = Get-OutlookSession try { $inbox = $s.Ns.GetDefaultFolder(6) $count = 0 try { $count = [int]$inbox.UnReadItemCount } catch { } if (-not $count) { $count = ($inbox.Items | Where-Object { $_.UnRead -eq $true }).Count } Write-Output "OK" Write-Output ([int]$count).ToString() } catch { Fail "inbox_failed" $_.Exception.Message } } "latest" { $s = Get-OutlookSession try { $inbox = $s.Ns.GetDefaultFolder(6) $items = $inbox.Items $items.Sort("[ReceivedTime]", $true) $latest = $null foreach ($it in $items) { if ($it.Class -eq 43) { $latest = $it; break } # olMail = 43 } if (-not $latest) { Fail "empty_inbox" } $fromName = "" try { $fromName = $latest.SenderName } catch { } if (-not $fromName) { try { $fromName = $latest.SenderEmailAddress } catch { } } $subject = "" try { $subject = $latest.Subject } catch { } $body = "" try { $body = $latest.Body } catch { } if (-not $body) { try { $body = Strip-Html $latest.HTMLBody } catch { } } else { $body = Clean-Line $body } if ($body.Length -gt 200) { $body = $body.Substring(0, 200) + "..." } Write-Output "OK" Write-Output ("FROM`t{0}" -f (Clean-Line $fromName)) Write-Output ("SUBJECT`t{0}" -f (Clean-Line $subject)) Write-Output ("PREVIEW`t{0}" -f $body) } catch { Fail "latest_failed" $_.Exception.Message } } "send_clipboard" { if ([string]::IsNullOrWhiteSpace($Recipient)) { Fail "no_recipient" } $s = Get-OutlookSession try { $resolved = Resolve-Recipient $s.Ns $Recipient if (-not $resolved) { Fail "unresolved" $Recipient } $bodyText = if ($Body) { $Body } else { "" } $subject = "" if ($bodyText) { $firstLine = ($bodyText -split "`r?`n", 2)[0].Trim() if ($firstLine.Length -gt 60) { $subject = $firstLine.Substring(0, 60).Trim() } else { $subject = $firstLine } } if ([string]::IsNullOrWhiteSpace($subject)) { $subject = "From J.A.R.V.I.S." } $mail = $s.App.CreateItem(0) $mail.To = $resolved.Address $mail.Subject = $subject $mail.Body = $bodyText $mail.Send() Write-Output "OK" Write-Output ("TO`t{0}" -f (Clean-Line $resolved.Name)) Write-Output ("ADDR`t{0}" -f (Clean-Line $resolved.Address)) Write-Output ("SUBJECT`t{0}" -f (Clean-Line $subject)) } catch { Fail "send_failed" $_.Exception.Message } } "summarize_inbox" { $s = Get-OutlookSession try { $inbox = $s.Ns.GetDefaultFolder(6) $items = $inbox.Items $items.Sort("[ReceivedTime]", $true) $taken = 0 $lines = @() foreach ($it in $items) { if ($taken -ge $Limit) { break } if ($it.Class -ne 43) { continue } $unread = $false try { $unread = [bool]$it.UnRead } catch { } if (-not $unread) { continue } $fromName = "" try { $fromName = $it.SenderName } catch { } $subj = "" try { $subj = $it.Subject } catch { } $lines += ("FROM`t{0}`tSUBJECT`t{1}" -f (Clean-Line $fromName), (Clean-Line $subj)) $taken += 1 } Write-Output "OK" foreach ($l in $lines) { Write-Output $l } } catch { Fail "summary_failed" $_.Exception.Message } } }