Copying .rtf text into the body of an email with AppleScript - applescript

I have an AppleScript application which creates an email (in Mail.app) with attachments from the options I choose through dialogs. The text templates are stored in .rtf format so non-programers can alter the text templates to their wishes.
I am able to create an email from a .txt plain text file, but when I import an .rtf text file it imports the formatting commands, which I don’t want in the mail.
Here is an example of a .rtf import into an email:
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs24 \cf0 technology mail for english speakers\
Here is part of my script:
-- Import the .rtf file and store content in the mycontent variable
set mycontent to (read "/Users/kiara/Desktop/mailer/technology/tech-en-content.rtf")
…
…
-- create mail from values stored in variables
tell application "Mail"
set theMessage to make new outgoing message with properties {visible:true, subject:mysubject, content:mycontent}
tell content of theMessage
make new attachment with properties {file name:this_file} at after last paragraph
end tell
end tell
Is it possible to import formatted text from .rtf files into a new mail without the formatting codes (I choose rtf because mostly bold and color are used to format text)?

Here is another approach:
set the clipboard to (read "/Users/kiara/Desktop/mailer/technology/tech-en-content.rtf" as «class RTF »)
tell application "Mail"
activate
set theMessage to make new outgoing message with properties {visible:true, subject:"mysubject"}
end tell
tell application "System Events"
tell process "Mail"
repeat until focused of UI element 1 of scroll area 4 of window 1
keystroke tab
end repeat
keystroke "v" using command down
end tell
end tell

I think Mail sends an email as either plain text or html, not rtf. So you would need to send your email as html not rtf. Note there's a trick to sending a html email with Mail via applescript. For some reason you can't set the visible property of the new message to true. It won't work if you do.
Here's how this can help you. You can use the command line tool textutil to convert the rtf to html and then send it as an email. Notice I use "tidy" in the command to make sure the html code is clean.
So all you need to do is put the receiver's email address and a subject in this script and run it...
set emailAddress to "someone#somewhere.com"
set theSubject to "My converted rtf to html"
set rtfFile to choose file with prompt "Choose the RTF file to email as HTML:" without invisibles
set theHTML to do shell script "/usr/bin/textutil " & " -stdout -format rtf -convert html " & quoted form of POSIX path of rtfFile & " | /usr/bin/tidy -b -utf8"
tell application "Mail"
set newMessage to make new outgoing message at end of outgoing messages with properties {visible:false}
tell newMessage
make new to recipient at end of to recipients with properties {address:emailAddress}
set subject to theSubject
set html content to theHTML
send
end tell
end tell

adayzdone answer works for me - more or less.
under Mac os X 10.15.6 , Mail 13.4 the scroll area is at another position / index.
And instead of using keystroke tab to get the content-Area an alternative way is to
set value of attribute "AXFocused" of UI element of scroll area 1 of window 1 to true
if you need to find the scroll area or identify other UI elements - you might want to use
on FindScrollAreas()
set Indices to {}
set the clipboard to "hello World"
tell application "System Events"
tell process "Mail"
activate
set i to 1
repeat with UIElement in UI elements of front window
-- button, text field, scroll area, static text
if class of UIElement is scroll area then
set end of Indices to i
end if
set i to i + 1
end repeat
end tell
end tell
return Indices
end FindScrollAreas
and there is also the fantastic approach in using Automator watch me do to get the menu items:
see this post
(you have to copy-paste the Events from Automator to some text-Editor to get some corresponding applescript)
and there is Xcode -> Xcode(menu) -> Open Developer Tool -> Accessibility Inspector - but i find it hard to transfer info to applescript
hope that helps, best -tom

Related

AppleScript: encoding arbitrary query-string values in URLs passed to Firefox

I use firefox for a long time as my only browser on Pc or Mac.
In a few words my problem: I want to create a service on mac with automator and
Applescript for quite instant translation using translate.google.com.
What works great with Safari or Chrome (below the 4 or 5 lines of script)
On run {input, parameters}
Tell application "Safari"
activate
try
Open location "https://translate.google.com/#auto/en/" & (the clipboard)
end try
end tell
end run
The same thing (script) does not work at all with Firefox, I try by different ways
To circumvent the impossible problem
On run {input, parameters}
Set theProcess to "Firefox"
Set info to {}
Set y to 0
Set x to 0
Set n to 0
Tell application "Applications / Firefox.app"
activate
Open location "http://translate.google.com/#auto/en/"
end tell
Tell application "System events"
Repeat with theProcess in (process "Firefox")
try
Set info to info & (value of (first attribute whose name is "AXWindows") of theProcess)
end try
end repeats
Set n to count of info
info
end tell
Tell application "System Events" to tell process "Firefox"
Set x to "1"
Set frontmost to true
try
Click menu item "Paste" of menu "Edit" of menu bar 1
end try
Repeat while x is "1" -
If x is "1" then
Keystroke "V" using command down
Set x to "0"
end if
end repeat
end tell
end run
By copying and pasting, the actions take place before the complete loading of the page, even by slowing down the Copy and Paste procedure.
After many observations there is a problem of formatting the text contained in the clipboard with the association of the URL, I improved this but it is not perfect yet.
tell application "Applications/Firefox.app" to activate
tell application "System Events" to tell process "Firefox"
set frontmost to true
set sentence to text of (the clipboard)
set thesentences to paragraphs of sentence
set thenewsentences to thesentences as string
set the clipboard to thenewsentences
keystroke "t" using command down
keystroke "https://translate.google.com/#auto/fr/" & (the clipboard) & return
end tell
Anyway if it works with Safari without modifying anything, the problem is at the Firefox entry, so if you can look at this problem, that would be very useful to us all.
Thank you for your attention.
Thank you for your answers.
Safari and Chrome perform the necessary encoding of reserved characters in the URL for you, but Firefox doesn't.
Therefore, you need to perform the encoding of the query-string value (the text to embed in the URL) explicitly.
The easiest (though not obvious) approach is to use perl, via a shell command, gratefully adapted from here:
# Example input that contains chars. that have special meaning in a URL ('&' and '?')
set the clipboard to "Non, Je ne regrette rien & rien ne va plus?"
# Get text from the clipboard and URL-encode it.
set encodedText to do shell script ¬
"perl -MURI::Escape -lne 'print uri_escape($_)' <<<" & quoted form of (the clipboard)
# Now it's safe to append the encoded text to the URL template.
tell application "Firefox"
activate
open location "https://translate.google.com/#auto/en/" & encodedText
end tell
The above approach works with all three browsers mentioned: Firefox, Safari, and Google Chrome.
Note:
As of (at least) Firefox v50, Firefox opens the URL in in a new tab in the current front window by default.
You can make Firefox open the URL in a new window instead, by unchecking Open new windows in a new tab instead on the General tab of Firefox's preferences.
Note, however, that this is a persistent setting that affects all URLs opened from outside of Firefox.
For an ad-hoc solution for opening in a new window that doesn't rely on changing the setting, see this answer of mine.
Hello below the service Automator with some version it is possible to encounter problems, I modified the script so that it works almost everywhere.
A frequent system error is the permission to applications to control your computer that is handled by the system preferences tab Security and Privacy, the system asks if you allow Firefox, TexEdit and others using this service for its keyboard shortcuts.
Also in Automator create service (to be General (and appear in all applications) no entry (up to Yosemite since El Capitan I saw that with Firefox for example all the services are usable), choose Execute a script Applescript paste the script below divided into 2 script or 1 script only.
on run
set Sn to ""
tell application "System Events"
set Sn to the short name of first process whose frontmost is true --here we look for and find which application to launch the service
tell process Sn
set frontmost to true
try
click menu item "Copy" of menu "Edit" of menu bar 1 -- there is used the Copier of the menu Editing of the application
end try
end tell
end tell
return the clipboard
end run
In the script following the entry is done with the contents of the Clipboard
On run {input}
on run {input}
set input to (the clipboard) -- Here we paste the contents of the Clipboard into a variable
try
set input to do shell script "Perl -MURI :: Escape -lne 'print uri_escape ($ _)' <<< " & quoted form of input --To format the text to make it usable with Firefox and the url of translate.google.com
tell application id "org.mozilla.firefox"
activate
open location "https://translate.google.com/#auto/en/" & input --here since version 50 of Firefox you must open a tab and not a new url window of translate.google.com, with option #auto automatic detection by google of the language, and fr to translate into French (these options are modifiable at will)
end tell
end try
end run -- end of the operation you have a tab open on translate, a text to translate and a translated text

AppleScript / Automator : use selected text as variable

I can't manage to find how to use the selected text as a variable for AppleScript and Automator.
Any ideas?
For Applescript, it works with other applications. To get the selected text of the front window in an app, Applescript has to use the language/syntax that this app understands/responds to. For very scriptable, text document based apps, there is much similarity, looking something like:
tell app "xyz" to get selection of document 1
However, there really is no standard. Many apps don't have a 'text selection' object in their scriptable dictionary, so you have to do all kinds of workarounds. See these examples:
tell application "Safari" to set selectedText to (do JavaScript "(''+getSelection())" in document 1)
tell application "System Events" to tell application process "TextEdit" to tell attribute "AXSelectedText" of text area 1 of scroll area 1 of window 1 to set selectedText to its value
tell application "Microsoft Word" to set selectedText to content of text object of selection
You can also script "System Events" to simulate the keystroke of command-c in order to copy text.
tell application "System Events" to keystroke "c" using {command down}
delay 1
set selectedText to the clipboard
If you need more specific help, post your code and indicate what app you are working with. If it is not a scriptable app, then you'll have to use the last method, calling System Events. Or, it's possible you can use an OS X Service, which you also asked about.
When you create a Service in Automator, you create a new Workflow of the type Service. Then, simply make sure that at the top of the window it says:
"Service receives selected text".
You can then use Automator actions to interact with the selected text that gets passed to the actions that follow.
Not all programs are compatible with Services, unfortunately.
To see how it works, try this very simple Automator service:
Create a Service in Automator and choose Text and Every application as input.
The first workflow step is Execute Applescript.
The Applescript's input parameter contains the selected text.
Set the Applescript to
on run {input, parameters}
display dialog (input as text)
return input
end run
After saving, you will have this action available in the context menu whenever you have selected text.
Maybe the naming is different, I don't know the English descriptions. But I hope this is a good starting point for you.
Have fun, Michael / Hamburg

Change the color of text by using applescript

I am writing some text in to word file i want to change the color of that text any one can help on that one plz.
I want to print the 'message' from following script in red color.
Here is the Script:
set message to "mostly these windows are popup in application"
on ResultCreationFuction(message)
try
set text_to_save to message as text
tell application "System Events"
tell application "Finder"
set sortedList to sort (get files of folder "SofTestAutomationResult" of desktop) by modification date
set FileCount to get count of sortedList
set theFile to (item FileCount of sortedList) as alias
end tell
set file_ref to open for access theFile with write permission
write (text_to_save & return) to the file_ref starting at eof
close access file_ref
delay 2
end tell
end try
end ResultCreationFuction
Some Details:
The file is word which is all ready present on above location having name "10.012.2014_17_4_20.doc" (the name of .doc file is not fix)
What you are attempting is the wrong way to do it.
To manipulate content like that, including formatted text (not plain
text), you need to work within, ideally, a well-scriptable app, like
Pages (or Word, perhaps, but I don't have that on the machine I'm
writing this from).
Don't use System Events if you don't need to. Use the apps with the appropriate AppleEvents/dictionary, etc. If you don't know what I'm talking about, you need to take advantage of the infinite resource known as the web.
"Fuction" is just bad form.
I would suggest doing a lot more reading up on how AppleScript works (or scripting in general), but to start you out, here is a script I just wrote in pages which sets the color of a specific word of the open document after putting text in there:
tell application "Pages"
set body text of document 1 to "hello there mister fancy pants"
set color of word 3 of body text of page 1 of document 1 to {64614, 0, 111}
end tell
If you have Pages, try this by starting with a blank page and running this script. Obviously, you could get rid of "word 3 of" in the 2nd line, and the whole body text will be red.
I hope this makes sense and is of help.
[edit]
I should mention that even TextEdit is scriptable and can open Word documents. Here's an example using TextEdit:
tell application "TextEdit"
set text of document 1 to "hello mister fancy pants"
set color of words 2 thru 3 of text of document 1 to {65535, 0, 0}
end tell
There is a little danger of non-Word apps losing formatting of Word files. But it just seems you are attempting something very simple, and I'm not sure if Word is really necessary here.
You can't add color using the write to eof. You should open the document in Word and then insert the line and add the color. Here's a script that should demonstrate how:
set text_to_add to "mostly these windows are popup in application"
set theFile to ((path to desktop folder) & "10.012.2014_17_4_20.doc") as string
tell application "Microsoft Word"
set theFile to theFile as string -- assuming theFile is an alias or :: path
open file theFile
tell active document
set endOfDoc to end of content of text object -- insert the text to end of document
set theRange to create range start (endOfDoc - 1) end endOfDoc
insert text text_to_add at theRange
set myRange to create range start endOfDoc end (endOfDoc + (length of text_to_add))
set color index of font object of myRange to red
save
end tell
end tell

Applescript to Paste clipboard text into Messages and send to email

The title says it all really.
Im new to applescripts and I'm hoping someone will be able to explain how to
Paste the clipboard text into Messages and send to a user using a applescript.
Also if you know how to send an image attachment instead of the clipboard text that would be amazing, and I would really appreciate it
set clipContent to (the clipboard as text)
tell application "Mail"
set myMessage to make new outgoing message at the beginning of outgoing messages with properties {subject:"Clipboard Content"}
tell myMessage to make new to recipient at beginning of to recipients with properties {address:"first#email.com, second#email.com"}
set myMessage's content to clipContent
set myMessage's visible to true
activate
-- Uncomment the line below to send the message
--send myMessage
end tell

Get message in compose window from Mail.app

I am trying to make a script that will get the contents of an email message that I'm composing in Mail, do something with the data, and then send the message. I know how to make and send a new message from scratch with AppleScript, but I can't find a way to get a message that I'm already writing. I don't care what language is used, and I would be open to trying a different email client. Thanks for your help!
Mail has huge limitations with regards to Applescript and dealing with its content area is a major one. The best bet is to use GUI scripting to tab to the content area, type cmd-C, and then work off the data in the clipboard.
Sadly from what I can see Applescript has not been improved at all in Lion.
It's actually pretty easy to do what you need.
If you want to run some kind of an inline processing (assigned to, say, a hotkey (in Mail, e.g. Cmd+D is not occupied), or "just" listed in the Services menu, accessible after selecting something), you can simply use Automator. A demo Automator script reading the current selection, making some changes (here, converting some ASCII char+number combinations to some accented characters) and, finally, returning the modified text is as follows:
on run {input, parameters}
set myText to replaceText("a1", "á", (input as text))
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
return myText
end run
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
Make sure you enable the "Replaces selected text", should you want to overwrite the original content with the returned one.
if you want to write an external script not invoked from the local Services menu (or via a hotkey), you'll also need to add clipboard handling. A solution similar to the above with additional clipboard copy/paste:
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Select All" of menu "Edit" of menu bar 1
click menu item "Copy" of menu "Edit" of menu bar 1
end tell
end tell
end tell
tell application "Mail"
set textclip to (the clipboard)
end tell
set myText to replaceText("a1", "á", textclip)
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
set the clipboard to myText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Paste" of menu "Edit" of menu bar 1
end tell
end tell
end tell
Note that the latter script selects (and, then, overwrites) the entire window contents. It should be easy to work on the current selection only.
It's possible, but painful. Painful enough that I'm still trying to work out exactly how to do something similar but in Safari. I've gotten to the point where I can find the textarea, but the documentation I've found for getting the content isn't working. (Unfortunately, that's pretty much par for the course for AppleScript; every program does stuff just a little bit differently from the next program.)
EDIT: ok, have some horrible evil which hopefully can be adapted to work with Mail: http://www.ece.cmu.edu/~allbery/edit_textarea.script
This is striaghtforward if we make two reasonably weak assumptions: that the message you're working on is frontmost, and that the subject of all draft messages is unique. Then, before running the script, save the message you're working on; this will place it in the drafts mailbox. Then, since the subject of the message is the name of the window, we can easily access it; and since we can easily access the drafts mailbox, we can combine the two. This gives us:
tell application "Mail"
set msgs to messages of drafts mailbox ¬
whose subject is (name of window 1 as string)
if (count of msgs) = 1 then
-- Do whatever
else
-- Error, disambiguate, whatever
end if
end tell
It's probably possible to make the script save the frontmost window, and it wouldn't surprise me if a freshly-saved message is always the first item of the drafts mailbox, but these are left as an exercise for the reader :-)
So I came across this in 2020 and with this Apple Script it is (now?) possible (whenever its still a bit hacky since I have to use the clipboard for this):
activate application "Mail"
tell application "System Events"
tell process "Mail"
set initialClipboardContent to (the clipboard as text)
set composeWindow to (first window whose title does not contain "Inbox")
set value of attribute "AXFocused" of UI element 1 of scroll area 1 of composeWindow to true
delay 0.05
# CMD + A
key code 0 using command down
delay 0.1
# CMD + C
key code 8 using command down
delay 0.1
set message to (the clipboard as text) as string
log message
set the clipboard to initialClipboardContent
end tell
end tell
Here a proof of concept:

Resources