Use AppleScript and Mail for remote control and file access

May 03, '06 07:30:00AM

Contributed by: mwncimelyn

I am unable to connect to my home Mac from work using VNC or SSH because of the company firewall, and I frequently wish I could access files or perform other tasks on my home Mac while still in work.

So I wrote an Applescript and set up an Mail rule which allows me to send an email to my home computer, and, depending on the action requested in the subject, get a file sent to me, launch an application, perform a shell script, save an attachment to a certain location, or get the computer at home to speak (not much use, just fun).

First of all, you need to copy the AppleScript below to Script Editor and save it somewhere safe.

You then need to decide on an identifier that you will include in the subject line of your action emails so that Mail performs the rule on only those emails; we will use [*PERFORM*] for this example.

Now, create a new rule in Mail. The first condition will need to be Subject - Begins With - [*PERFORM*]. It is also a good idea to include another condition that will only perform the action on emails from your email addresses for security reasons.

Under "Perform the following actions", choose Run AppleScript and point it to the AppleScript that you downloaded. (I also have my rule set up to move the email to another mailbox folder to file it away).

Everything should now be set up to run the AppleScript when the properly tagged email message comes in, but you also need to tell it what you want it to do. You can do this by adding another tag in the subject line of your emails. Below I will explain what each tag does and how to format the instructions.

<launch>
Example:
Subject: [*PERFORM*] <launch>
Body: FolderShare
This tag tells the script to launch an application. The application name should be on the first line of the message body with no other characters on the same line. The full path to the application should not be required.
<send>
Subject: [*PERFORM*] <send>
Body: Macintosh HD:Users:joebloggs:Desktop:readme.txt
This tag will reply to the sender of the email, sending the file specified in the message body as an attachment. The full path to the file does not need to be specified in the old classic OS way of specifying paths (with colons and starting with the name of the disk). The path needs to be on the first line of the body. If this fails an email message will be sent to inform the sender.
<put>
Subject: [*PERFORM*] <put>
Body: Macintosh HD:Users:joebloggs:Desktop:
Attachment: readme2.txt
This tag will save the attached file into the location specified on the first line of the body. Again, this needs to be a classic OS path and end in a colon. If this fails an email message will be sent to inform the sender.
<do>
Subject: [*PERFORM*] <do>
Body: defaults write com.apple.loginwindow showInputMenu TRUE
This tag performs the shell script specified on the first line of the message body. Care should be taken with this, especially with quotes.
<script>
Subject: [*PERFORM*] <script>
Body: Set Volume Output Volume 100
This tag runs the AppleScript specified on the first line of the message body.
<say>
Subject: [*PERFORM*] <say>
Body: Hello. Is anyone there?
This tag causes the computer to speak the text on the first line of the body. (I've yet to find a use for this one)

Here is the AppleScript:

using terms from application "Mail"
	on perform mail action with messages actionMail for rule actionRule
		tell application "Mail"
			repeat with i from 1 to count of actionMail
				
				set thisMail to item i of actionMail
				set theSubject to the subject of thisMail
				set theBody to (the content of thisMail) as text
				set theBody to my getFirstLine(theBody)
				
				set theSender to the sender of thisMail
				
				try
					if theSubject contains "<launch>" then
						my launchApp(theBody)
						
					else if theSubject contains "<say>" then
						my sayThis(theBody)
						
					else if theSubject contains "<do>" then
						my doShell(theBody)
						
					else if theSubject contains "<send>" then
						my sendThis(theBody, theSender)
						
					else if theSubject contains "<put>" then
						set attachName to the name of the first mail attachment of thisMail
						try
							save first mail attachment of thisMail in theBody & attachName
						on error
							set newMessage to (make new outgoing message at end of outgoing messages)
							tell newMessage
								set visible to true
								make new to recipient at end of to recipients with properties {address:theSender}
								set subject to "I was not able to put the file you sent in the requested place"
								send
							end tell
						end try
						
					else if theSubject contains "<script>" then
						do shell script "osascript -e '" & theBody & "'"
					end if
					
					
				end try
				
			end repeat
			
		end tell
	end perform mail action with messages
end using terms from


on launchApp(theApp)
	tell application theApp to activate
end launchApp

on sayThis(theText)
	say theText
end sayThis

on doShell(theShell)
	do shell script theShell
end doShell

on sendThis(theFile, theSender)
	try
		set theFile to theFile as alias
		tell application "Mail"
			set newMessage to (make new outgoing message at end of outgoing messages)
			tell newMessage
				set visible to true
				make new to recipient at end of to recipients with properties {address:theSender}
				set subject to "Please find attached the file you requested"
				make new attachment with properties {file name:theFile} at before the last paragraph
				send
			end tell
		end tell
	on error
		tell application "Mail"
			set newMessage to (make new outgoing message at end of outgoing messages)
			tell newMessage
				set visible to true
				make new to recipient at end of to recipients with properties {address:theSender}
				set subject to "I was not able to send you the file you requested"
				send
			end tell
		end tell
	end try
end sendThis

on getFirstLine(theBody)
	set oldTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "
"
	set firstLine to text item 1 of theBody
	set AppleScript's text item delimiters to oldTID
	
	return firstLine
end getFirstLine

Comments (26)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20060420065151134