Copy Outlook 2016 Events to Clipboard (HTML & Rich text)

@JMichaelTX @Tom
Here is the applescript that I changed from reading Oultook email messages to a clipboard to reading Outlook events to the clipboard.

[Moderator: Script Properties below were modified to reflect a change in the script by @charliez1030.]

property ptyScriptName : "Copy MS Outlook 2016 Event To Clipboard"
property ptyScriptVer : "2.2" --  Converted to OL 2016 Events
property ptyScriptDate : "2018-06-02"
property ptyScriptAuthor : "charliez1030" -- based on script by @JMichaelTX

(*  
RETURNS:	Sets Clipboard to Entire Outlook Event, including Header

METHOD:
  • This is a work-in-progress.  It is not complete.  However, it is functionallly complete.
  • At this point is is provided to serve as an example of how to extract data
  from an Outlook 2011/16 event.
  • This is mostly a conversion of the Apple Mail Script by @Tom to work with Outlook 2011.
  • I am not satisfied with the output format, but it does contain all relavent data in the Message.
  • Since Outlook 2011/16 stores the message body a HTML or plain text, the final output
  will be generated as HTML, then converted to RTF using ASObjC.  Both RTF and Plain text are put on the Clipboard.

REQUIRED:
  1.	macOS 10.11.6+
  2.	Mac Applications
  • MS Outlook 2011 or 2016
  
  3.	EXTERNAL OSAX Additions/LIBRARIES/FUNCTIONS
  • Satimage.osax
  (Free D/L & info at http://tinyurl.com/Satimage-Osax-DL )
  
TAGS:	@Lang.AS @SW.OL @CAT.Messages @CAT.Clipboard @Auth.JMichaelTX

REF:  The following were used in some way in the writing of this script.

  1.	2017-04-14, Tom, Keyboard Maestro Discourse
  Copy Mac Mail Message Contents To Clipboard?
  https://forum.keyboardmaestro.com/t/copy-mac-mail-message-contents-to-clipboard/5400/31
  
  2.	2018-05-28, ShaneStanley, Late Night Software Ltd.
  How Do I Set Clipboard (Pasteboard) to Both Rich Text (RTF) and Plain Text?
  http://forum.latenightsw.com/t/how-do-i-set-clipboard-pasteboard-to-both-rich-text-rtf-and-plain-text/1189/5?u=jmichaeltx

*)
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

--- classes, constants, and enums used by the ASObjC Handler htmlToRTFCB() ---
property NSUTF8StringEncoding : a reference to 4
property NSString : a reference to current application's NSString
property NSRTFTextDocumentType : a reference to current application's NSRTFTextDocumentType
property NSPasteboardTypeRTF : a reference to current application's NSPasteboardTypeRTF
property NSPasteboardTypeString : a reference to current application's NSPasteboardTypeString
property NSDictionary : a reference to current application's NSDictionary
property NSAttributedString : a reference to current application's NSAttributedString
property |NSURL| : a reference to current application's |NSURL|


property LF : linefeed
property BRLF : "<BR>" & linefeed


tell application "Microsoft Outlook"
	# Get the first selected event
	set selEvent to the selection
	try
		set theEvent to first item of selEvent
	on error
		display alert "Probably No Event Selected!"
		error number -129
	end try
	
	# Get the desired header elements
	# Elements containing only one item
	
	# Sender
	set theOrganizer to the organizer of theEvent
	
	
	# Subject
	set theSubject to subject of theEvent
	# Start Time
	set theStartTime to time string of (get start time of theEvent)
	# End Time
	set theEndTime to time string of (get end time of theEvent)
	# Date
	set theEventDate to date string of (get start time of theEvent)
	#Concantonate Date and Time
	set theDateAndTime to (theEventDate & " " & theStartTime & " " & theEndTime)
	
	
	# Elements containing multiple items (required attendees)
	
	# Normal (“To”) Required Attendees
	set theRequiredAttendee to {}
	repeat with i in required attendee of theEvent
		set oEMail to email address of i
		set end of theRequiredAttendee to my convertEmailToStr(oEMail)
	end repeat
	
	# Optional Attendees
	set theOptionalAttendees to {}
	repeat with i in optional attendees of theEvent
		set oEMail to email address of i
		set end of theOptionalAttendees to my convertEmailToStr(oEMail)
	end repeat
	
	# Resource Attendee
	set theResourceAttendee to {}
	repeat with i in resource attendee of theEvent
		set oEMail to email address of i
		set end of theResourceAttendee to my convertEmailToStr(oEMail)
	end repeat
	
	if (has html of theEvent) then
		set msgBodyHtml to content of theEvent -- is already HTML for Outlook
	else
		set msgBodyHtml to my convertToHtml(theSubject, content of theEvent)
	end if
	
	
end tell -- Outlook

-----------------------------------
--	FORMAT HTML OUTPUT --
----------------------------------

# Format the recipients 
# Save current text item delimiters
set saveTID to AppleScript's text item delimiters
# Set the desired delimiters for the representation, e.g. {", "}, {"; "}, {" – "}, {" | "}
set AppleScript's text item delimiters to {"; "}
# Format the recipients lists as delimited text
set toRequiredAddresses to theRequiredAttendee as text
set toOptionalAddresses to theOptionalAttendees as text
set toResourceAddresses to theResourceAttendee as text
# Restore text item delimiters
set AppleScript's text item delimiters to saveTID

# CC and BCC are optional. So let’s precompose the variables to display these two strings, in function of if there are any CC/BCC recipients
if toOptionalAddresses is not "" then
	set toOptionalAddressesDisplay to "Optional: " & toOptionalAddresses & linefeed
else
	set toOptionalAddressesDisplay to ""
end if
if toResourceAddresses is not "" then
	set toResourceAddressesDisplay to "Resource: " & toResourceAddresses & linefeed
else
	set toResourceAddressesDisplay to ""
end if

# Compose the header
set TRTD to "<tr><td>" & LF
set TDTR to "</td></tr>" & LF

set headerHtml to "<table width=\"100%\" style=\"font-family: calibri; font-size: 14px;\">" & my addrow({"<B>Subject: </B>", theSubject}) & my addrow({"<B>Event:</B>", theEventDate & " " & theStartTime & "  " & theEndTime}) & my addrow({"<B>From:</B>", theOrganizer}) & my addrow({"<B>To:</B>", toRequiredAddresses & BRLF & ¬
	toOptionalAddressesDisplay & toResourceAddressesDisplay}) & ¬
	"</table>"

--- Put Header in HTML Table ---

set headerHtml to "
<div><BR>
<table width=\"110%\"><tr>
<td style=\"border-bottom: 1px solid black; border-top: 1px solid black; font-family: calibri; font-size: 14px;\">
" & headerHtml & " 
</td>
</tr>
</table><BR>
</div>
"

--- Insert Header AFTER Content <body> Tag ---

set regexFind to "(<body.+)"
set regexReplace to "\\1" & linefeed & headerHtml & linefeed
set finalMsg to change regexFind into regexReplace in msgBodyHtml syntax "PERL" with regexp

--- CONVERT HTML to RTF, and PUT ON CLIPBOARD ---

my htmlToRTFCB(finalMsg)

------------------------------------------
--	OPTIONAL:  Create Note in Evernote --		#JMTX ADD
------------------------------------------
-- This produces better result than a Paste of the clipboard in a new note
-- Remove comment block to use
(*
tell application "Evernote"
  set oNote to create note with html finalMsg title theSubject
end tell
*)

--~~~~~~~~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~

on htmlToRTFCB(pHtmlStr)
	(*
REF:  

  1.	2018-05-28, ShaneStanley, Late Night Software Ltd.
  How Do I Set Clipboard (Pasteboard) to Both Rich Text (RTF) and Plain Text?
  http://forum.latenightsw.com/t/how-do-i-set-clipboard-pasteboard-to-both-rich-text-rtf-and-plain-text/1189/5
*)
	
	-- convert to data
	set htmlString to NSString's stringWithString:pHtmlStr
	set htmlData to htmlString's dataUsingEncoding:NSUTF8StringEncoding
	-- make attributed string
	set attString to NSAttributedString's alloc()'s initWithHTML:htmlData documentAttributes:(missing value)
	-- need it in RTF data form for clipboard
	set rtfData to attString's RTFFromRange:{0, attString's |length|()} documentAttributes:{DocumentType:NSRTFTextDocumentType}
	set pb to current application's NSPasteboard's generalPasteboard() -- get pasteboard
	pb's clearContents()
	-- set both types for the first object on the clipboard
	pb's setData:rtfData forType:NSPasteboardTypeRTF
	
end htmlToRTFCB

on convertEmailToStr(poEmail)
	tell application "Microsoft Outlook"
		set emailStr to (name of poEmail & " &lt;" & address of poEmail & "&gt;")
	end tell
	return emailStr
end convertEmailToStr


on addrow(pColList)
	set rowHtml to "<tr>"
	repeat with oCol in pColList
		set rowHtml to rowHtml & "<td>" & (contents of oCol) & "</td>"
	end repeat
	set rowHtml to rowHtml & "</tr>" & LF
	return rowHtml
end addrow


on convertToHtml(pTitleStr, pBodyStr)
	
	set regexFind to "((\\r\\n)|\\n|\\r)"
	set regexReplace to "<BR>\\n"
	set pBodyStr to change regexFind into regexReplace in pBodyStr syntax "PERL" with regexp
	
	set htmlStr to "
<!DOCTYPE html>
<html>
<head>
  <title>" & pTitleStr & "</title>
</head>
<body style=\"font-family: calibri; font-size: 11px;\">
<div>
" & pBodyStr & " 
</div>
</body>
</html>
"
	
	return htmlStr
end convertToHtml

@JMichaelTX,

I had to get over a couple hurdles but was finally successful last night!

One thing i'm trying to do is to have each attendee on its own line as I have to quickly mark off whether they attended or not. I tried to change, as an example:
Was:
set oEMail to email address of i
To
set oEMail to email address of (i & return)

No change in results. I also tried to make a similar change in the formatting section but no luck either.

I don't mind doing the legwork as it helps me learn but I can't seem to find anything online that helps me figure out what I'm doing wrong. Any thoughts?

Thanks,
Charlie

That's great! Please update the AppleScript properties at the top of the script to reflect your version of the script.

BTW, for those interested in Outlook, this script developed for Outlook 2016 also runs in Outlook 2011.

The output of the script is HTML converted to rich text. Generally, CRs and LFs have no effect on rendering HTML. So, instead of using "return" you need to use "<BR>" when you want a new line shown.

But the change you need to make is in a different place:

-- REPLACE THIS:
--set AppleScript's text item delimiters to {"; "}

-- WITH THIS:
set AppleScript's text item delimiters to {BRLF}

-- just above this line:
# Format the recipients lists as delimited text

This will put a "<BR>" at the end of every recipient, thus making the next recipient on a new line.
Note the AppleScript "BRLF" is a property set at the top of the script.

The LF is not required, but I like to use it in my HTML to help viewing of the HTML code.

Questions?