Add vcard to Contacts with Mail rules and Applescript - applescript

I receive a lot of customer vcards to a specific email address. I want to automatically add the vcards to my contacts through the Mail rules and an AppleScript.
I searched a lot and found something. I modified it a bit. And the opening and adding process works fine. But only when I choose a file. I can't get the file into a variable from the mail message. I tried it but it won't work.
Here is my code so far:
tell application "Mail"
set att to attachment
end tell
set thefile to att
tell application "Contacts"
activate
open thefile
end tell
tell application "System Events" to keystroke return
If I delete line 1, 2 and 3 and write in line 4 "set thefile to choose file" then it will work - if I choose a file.
But the first three lines I tried something out, but without any success.
So my question is, how can I get the file from the message?
Thank you
Yours sincerely,
Chris
Solution:
set Dest to ((path to desktop folder) as string)
tell application "Finder" to make new folder in Dest with properties {name:"TempFiles"} -- create TempFiles folder
Set Dest to Dest & "TempFiles:"
tell application "Mail"
activate -- not sure is mandatory, but I prefer to see selected mails !!
set ListMessage to selection -- get all selected messages
repeat with aMessage in ListMessage -- loop through each message selected
set AList to every mail attachment of aMessage -- get all attachements
repeat with aFile in AList -- for each attachement
if (downloaded of aFile) then
set Filepath to Dest & (name of aFile)
do shell script "touch " & (quoted form of (POSIX path of Filepath)) -- required because "Save" only works with existing file !
save aFile in (Filepath as alias) as native format
end if
end repeat -- next file
end repeat -- next message
end tell
tell application "Finder" to set CardList to every file of folder Dest whose name extension is {"vcf"}
tell application "Contacts"
activate
repeat with aCard in CardList
open aCard
delay 1
tell application "System Events" to keystroke return
end repeat
end tell
delay 2
-- tell application "Finder" to delete folder Dest

The file attached from email respond to the 'save" command, but not to 'open'. Then, you must first save the attached files, and later, move them to next application (add in 'Contacts' in your case).
The attachement is a member of a list of 'mail attachement' of a message : keep in mind that there could be many files attached.
Also, you can only save the attached file if its 'downloaded' attribute is true.
Last, but not least, it seems that the "save" instruction which was working nice in Snow Leopard, does not work the same in El Capitain : the file where to save must exist before the "save"...this is why I added the "touch" command to create it first (just create the entry in the tempFiles folder).
I also add at bottom of script the open vCard with the enter key to validate in Contact. You may have to add a delay to leave sometime for your computer to process the card.
if the keys broke does not work in your case, please check System Preferences accessibility settings to allow your computer to let your script control your Mac.
I added as much comments as possible to make it clear...may be too much !
set Dest to ((path to desktop folder) as string)
tell application "Finder" to make new folder in Dest with properties {name:"TempFiles"} -- create TempFiles folder
Set Dest to Dest & "TempFiles:"
tell application "Mail"
activate -- not sure is mandatory, but I prefer to see selected mails !!
set ListMessage to selection -- get all selected messages
repeat with aMessage in ListMessage -- loop through each message selected
set AList to every mail attachment of aMessage -- get all attachements
repeat with aFile in AList -- for each attachement
if (downloaded of aFile) then
set Filepath to Dest & (name of aFile)
do shell script "touch " & (quoted form of (POSIX path of Filepath)) -- required because "Save" only works with existing file !
save aFile in (Filepath as alias) as native format
end if
end repeat -- next file
end repeat -- next message
end tell
tell application "Finder" to set CardList to every file of folder Dest whose name extension is {"vcf"}
tell application "Contacts"
activate
repeat with aCard in CardList
open aCard
tell application "System Events" to keystroke return
end repeat
end tell
-- tell application "Finder" to delete folder Dest
As you can see, I filter the content of the temp folder with only files with extension 'vcd'...just in case your selected emails contain also other type of file which Contact can't handled.
At end of the script, I delete the temp folder. however, until you test it, I set this last row as a comment only (more safe !)

Related

Batch Convert *.numbers to *.csv AppleScript

I was looking for a script that would batch convert all *.numbers files in a given folder to *.csv files.
I found the following on GitHub and added an additional line as suggested in the comments suggestion. When I run the script, Numbers launches and opens the test file from the folder specified - but the file is not exported. Numbers just stays open and terminal errors out with:
/Users/Shared/Untitled.scpt: execution error: Numbers got an error: Invalid key form. (-10002)
The script (located in /Users/Shared) has the following permissions:
-rwxr-xr-x
#!/usr/bin/osascript
on run argv
set theFilePath to POSIX file (item 1 of argv)
set theFolder to theFilePath as alias
tell application "Finder" to set theDocs to theFolder's items
-- Avoid export privilege problem
set privilegeFile to (theFolder as text) & ".permission"
close access (open for access privilegeFile)
repeat with aDoc in theDocs
set docName to aDoc's name as text
if docName ends with ".numbers" then
set exportName to (theFolder as text) & docName
set exportName to exportName's text 1 thru -9
set exportName to (exportName & "csv")
tell application "Numbers"
open aDoc
delay 5 -- may need to adjust this higher
tell front document
export to file exportName as CSV
close
end tell
end tell
end if
end repeat
end run
Any suggestions?
Here is what I did and works for me in macOS High Sierra:
In Terminal:
touch numb2csv; open -e numb2csv; chmod +x numb2csv
• This creates an empty ASCII Text file named numb2csv.
• Opens, by default, numb2csv in TextEdit.
• Makes the numb2csv file executable.
Copy and paste the example AppleScript code, shown further below, into the opened numb2csv file.
Save and close the numb2csv file.
In Terminal executed the numb2csv executable file, e.g.:
./numb2csv "$HOME/Documents"
This created a CSV file of the same name as each Numbers document in my Documents folder, not traversing any nested folders.
Example AppleScript code:
#!/usr/bin/osascript
on run argv
set theFilePath to POSIX file (item 1 of argv)
set theFolder to theFilePath as alias
tell application "System Events" to set theDocs to theFolder's items whose name extension = "numbers"
repeat with aDoc in theDocs
set docName to aDoc's name as text
set exportName to (theFolder as text) & docName
set exportName to exportName's text 1 thru -8
set exportName to (exportName & "csv")
tell application "Numbers"
launch
open aDoc
repeat until exists document 1
delay 3
end repeat
tell front document
export to file exportName as CSV
close
end tell
end tell
end repeat
tell application "Numbers" to quit
end run
NOTE: As coded, this will overwrite an existing CSV file of the same name as each Numbers file processed, if they already exist. Additional coding required if wanting to not overwrite existing files
If you receive the Script Error:
Numbers got an error: The document “name” could not be exported as “name”. You don’t have permission.
It is my experience that the Numbers document was not fully opened prior to being exported and that increasing the value of the delay command resolves this issue. This is of course assuming that one actually has write permissions in the folder the target Numbers documents exists.
Or one can introduce an error handler within the tell front document block which, if my theory is right about the target document not being fully loaded before the export, will give additional time, e.g.:
Change:
tell front document
export to file exportName as CSV
close
end tell
To:
tell front document
try
export to file exportName as CSV
close
on error
delay 3
export to file exportName as CSV
close
end try
end tell
Note: The primary example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. See included example directly above.
I was looking for that, unfortunately, that doesn’t work anymore.
This line
tell application "System Events" to set theDocs to theFolder's items whose name extension = "numbers"
Gets the following error:
execution error: Can’t make file "file.numbers" of application "System Events" into the expected type. (-1700)
macOs Big Sur Versio 11.01
automator version 2.10
Numbers version 10.3.5
Inspired by this thread and those articles Exporting Numbers Documents and Get full directory contents with AppleScript
The following code works:
#!/usr/bin/osascript
log "Start"
property exportFileExtension : "csv"
tell application "Finder"
activate
set sourceFolder to choose folder with prompt "Please select directory."
set fileList to name of every file of sourceFolder
end tell
set the defaultDestinationFolder to sourceFolder
repeat with documentName in fileList
log "documentName: " & documentName
set fullPath to (sourceFolder as text) & documentName
log "fullPath: " & fullPath
if documentName ends with ".numbers" then
set documentName to text 1 thru -9 of documentName
tell application "Finder"
set newExportItemName to documentName & "." & exportFileExtension
set incrementIndex to 1
repeat until not (exists document file newExportItemName of defaultDestinationFolder)
set newExportItemName to ¬
documentName & "-" & (incrementIndex as string) & "." & exportFileExtension
set incrementIndex to incrementIndex + 1
end repeat
end tell
set the targetFileHFSPath to ¬
(defaultDestinationFolder as string) & newExportItemName
tell application "Numbers"
launch
open fullPath
with timeout of 1200 seconds
export front document to file targetFileHFSPath as CSV
end timeout
close
end tell
end if
end repeat
user3439894's answer works with a few change:
exists document 1 => number of documents > 0

Apple script to export images from "Photos" application

I have albums and nested albums and folders in Photos application. I want my applescript to export images maintaining the Album or Folder structure that I have the in the application.
I tried scripts available online :
tell application "Finder"
set location_1 to (choose folder with prompt "Choose a folder to export into") as text
end tell
tell application "Photos"
set x to name of every folder
choose from list x with prompt "Choose a project to export"
set theP to item 1 of result
tell application "Finder" to make new folder at alias location_1 with properties {name:theP}
tell folder theP
set initflist to every folder
set initalist to every album
if initflist is equal to {} then
log "process albums"
processAlbums(initalist, location_1 & theP) of me
else
if initalist is not equal to {} then
log "process albums"
processAlbums(initalist, location_1 & theP) of me
end if
log "process sub folders "
processSfolders(initflist, (location_1 & theP)) of me
end if
end tell
end tell
on processAlbums(alist, apath)
tell application "Photos"
repeat with a in alist
tell a
set theimages to get media items of album a
set thename to name of a
tell application "Finder"
if not (exists folder thename in alias apath) then
make new folder at alias apath with properties {name:thename}
end if
set destination to apath & ":" & thename & ":"
end tell
with timeout of 6000 seconds
tell a
set settings to "JPEG - Original Size"
export theimages to alias destination
end tell
end timeout
end tell
end repeat
end tell
end processAlbums
on processSfolders(flist, fpath)
tell application "Photos"
repeat with a in flist
try
set thename to name of a
tell application "Finder"
if not (exists folder thename in alias fpath) then
make new folder at alias fpath with properties {name:thename}
end if
end tell
tell a
set sAlist to every album
set sflist to every folder
if sflist is equal to {} then
processAlbums(sAlist, fpath & ":" & thename) of me
else
if sAlist is not equal to {} then
processAlbums(sAlist, fpath & ":" & thename) of me
end if
processSfolders(sflist, fpath & ":" & thename) of me
end if
end tell
on error errMsg
log "error"
end try
end repeat
end tell
end processSfolders
The issue is that it gets names of only child albums and not top level albums. I have to maintain the entire structure of album or folder.
I do not know AppleScript and I tried tweaking this one but no luck so far. can I get a direction please?
You can get the name of the folders, and the albums contained in the folder, which will enable you to create the top level and child directories. Albums can only contain media items, not albums. Top level albums are classified as folders or containers. In the Applescript dictionary for Photos, it gives the definitions for these items.
tell application "Finder"
set location_1 to (choose folder with prompt "Choose a folder to export into") as text
end tell
tell application "Photos"
activate
set fds to folders
repeat with fd in fds
set fdName to name of fd
set abNames to every album of fd
if parent of fd is missing value then
my createFolders(fdName, abNames, location_1, fd)
end if
end repeat
end tell
on createFolders(fName, aAlbums, fPath, fd)
tell application "Finder"
if not (exists folder fName in alias fPath) then
make new folder with properties {name:fName} at fPath
end if
repeat with a in aAlbums
set aName to name of a
set aPath to ((fPath as alias) as text) & fName
if not (exists folder aName in alias aPath) then
make new folder with properties {name:aName} at aPath
end if
set exPath to ((aPath as alias) as text) & aName
my exportImages(a, exPath)
end repeat
end tell
tell application "Photos"
set rcFolders to every folder of fd
repeat with rcFd in rcFolders
set rcAlbums to every album of rcFd
set rcName to name of rcFd
set rcPath to ((fPath as alias) as text) & fName
my createFolders(rcName, rcAlbums, rcPath, rcFd)
end repeat
end tell
end createFolders
on exportImages(photoAlbum, destination)
tell application "Photos"
set theimages to get media items of photoAlbum
with timeout of 6000 seconds
tell photoAlbum
set settings to "JPEG - Original Size"
export theimages to alias destination
end tell
end timeout
end tell
end exportImages
EDIT - Error Handling
To handle errors, locate the command that is causing the error and wrap it in a try block. Solution could be to quit the application, so that the process will end, and maybe add a short delay and then continue with the script.
try
export theimages to alias destination
on error
-- statements to execute in case of error
error "The exporting of images failed to complete"
quit
end try
From the developer reference - When a command fails to complete in the allotted time (whether the default of two minutes, or a time set by a with timeout statement), AppleScript stops running the script and returns the error "event timed out". AppleScript does not cancel the operation—it merely stops execution of the script. If you want the script to continue, you can wrap the statements in a try statement. However, whether your script can send a command to cancel an offending lengthy operation after a timeout is dependent on the application that is performing the command. Further info regarding try statements.

applescript help naming .plist and removing extention

i am creating an applescript to create a file with property list elements but without the .plist extension!
my issue is if i use a dialog to get the name of the file eg.
tell application "SystemUIServer"
display dialog "Enter filename :- " buttons {"Generate file"} default answer "Generate Keyfile"
set fileName to text returned of result
and create the file on the desktop like so
set text_file to (path to desktop)'s POSIX path & "" & quoted form of fileName & ".NEWextention"
finally i add elements to the .plist
tell application "System Events"
tell (make new property list file with properties {name:text_file})
make new property list item at end with properties {kind:string, name:"regName", value:"FOO"}
make new property list item at end with properties {kind:string, name:"regNumber", value:"BAR" as text}
end tell
end tell
end tell
however the file that is created is has '' when quoted from fileName and still has the .plist extention.
eg input :- myfile
output:- 'myfile'.NEWextention.plist
when i want
myfile.NEWextention
how can i achieve this in applescript?
any help would be greatly appreciated!
many thanks in advance.
below is the fixed code thanks to #McUsr
without his help i would have been at the same point for over 6 months of trial and error
tell application "SystemUIServer"
display dialog "Enter FileName :- " buttons {"Generate file"} default answer "Generate file"
set FileName to text returned of result
set text_file to (path to desktop folder as text) & FileName & ".plist"
set dateStamp to do shell script "date"
tell application "System Events"
tell (make new property list file with properties {name:text_file})
make new property list item at end with properties {kind:string, name:"Name", value:FileName}
make new property list item at end with properties {kind:string, name:"Date", value:dateStamp}
end tell
end tell
end tell
tell application "Finder"
set name extension of file text_file to "newExt"
end tell
You can make it happen afterwards you are done processing it with System Events, by Finder, (set name extension of file "Hfs:path:to:file:with:name.ext" to "new-ext").
But I am not sure if you can expect System Events to regard the file as a property list file, containing property list items afterwards. It is still worth a try though. :)
This is how you must change the name extension, as this don't work with System Events (name extension is a read only property).
tell application "Finder"
set mf to (path to desktop folder as text) & "labels.txt"
set name extension of file mf to "text"
end tell
Use the HFS path of the file, aka: Macintosh Hd:Users:You:path:file.ext, and not the posix path. And don't use quoted form of det path.

Applescript CS5 and CS6 export with save for web will not work

I am at my wit's end. I have tried all variations to get this script to work. The error I get is Adobe Photoshop CS6 got an error: Can’t get current document. and the highlighted script error is my "export in file newFileName.." block. I've tried putting alias in different positions, using file, not using file. Also I get this error message, but the actual script seems to stop working right after "set docName to name of docRef"
And basically I just copied this code from another script that was working fine and just changed a save this file... to a export this file...
-- set the folders that you want to use
set inputFolder to choose folder with prompt "Choose the folder of images to downsize."
set pathToDesktop to (path to desktop folder as string)
set outputFolder to pathToDesktop & "PhotoshopRetina:"
tell application "Finder"
set filesList to files in folder inputFolder
if not (exists folder outputFolder) then
make new folder at desktop with properties {name:"PhotoshopRetina"}
end if
end tell
with timeout of 86400 seconds
tell application "Adobe Photoshop CS6"
set display dialogs to never
close every document saving no
end tell
repeat with aFile in filesList
tell application "Finder"
-- The step below is important because the 'aFile' reference as returned by
-- Finder associates the file with Finder and not Photoshop. By converting
-- the reference below 'as alias', the reference used by 'open' will be
-- correctly handled by Photoshop rather than Finder.
set theFile to aFile as string
set theFileName to name of aFile
set theFileInfo to info for alias theFile
if kind of theFileInfo is "Adobe Photoshop JPEG file" then
my retinaDisplay(theFile)
end if
end tell
end repeat
end timeout
end
on retinaDisplay(theFile)
tell application "Adobe Photoshop CS6"
open alias theFile
set docRef to the current document
-- Convert the document to a document mode that supports saving as jpeg
if (mode of docRef is not RGB) then
change mode docRef to RGB
end if
tell docRef
set color profile kind to none
end tell
set infoRef to get info of docRef
set docName to name of docRef
set docBaseName to getBaseName(docName) of me
set newFileName to (my outputFolder as string) & docBaseName & ".jpg"
tell current document
export in file newFileName as save for web with options {class:save for web export options, web format:JPEG, embed color profile:false, quality:45} with copying
end tell
close current document without saving
end tell
end retinaDisplay
-- Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
exit repeat
end if
end repeat
return baseName
end getBaseName
end
If I open an image in photoshop I can run this code with no errors.
set f to (path to desktop as text) & "test.jpg"
tell application "Adobe Photoshop CS6"
tell current document
export in file f as save for web
end tell
end tell
However, if I additionally add your "with options" code then I get your error. I don't even know what the "with copying" part is. I don't think that means anything to photoshop. So the problem is not with the "current document". The problem is with your options. You must be doing that part wrong.
Good luck.

Create new folder from files name and move files

(This is a new edit from a previous question of mine which achieved -3 votes. Hope this new one has a better qualification)
I need to create an Automator service to organize a high amount of files into folders. I work with illustrator and from each .ai file I create 3 more formats: [name.pdf], [name BAJA.jpg] and [name.jpg], thats 4 files in total
My problem is that during the week I repeat this process to more than 90 different .ai files. So 90 files * 4 is 360 independent files all into the some project folder.
I want to grab all 4 related files into one folder, and set the folder name as the same as the .ai file.
Since all the file names are identical (except one), I thought of telling the finder to grab all the files with the same name, copy the name, create a folder and put this files inside, but I have a file name variant [name LOW.jpg] Maybe I can tell the script to strip that work as an exception.
That way I will all 4 the files unified into one folder.
Thank you in advance
Update: This problem was originally posted back in 2013, now I have a solution. People help me assembled this script to fit my needs.
I added this as a service and assigned a keyboard shurtcut on MacOs.
This is the code:
on run {input, parameters} -- create folders from file names and move
set output to {} -- this will be a list of the moved files
repeat with anItem in the input -- step through each item in the input
set {theContainer, theName, theExtension} to (getTheNames from anItem)
try
# check for a suffix and strip it off for the folder name
if theName ends with " BAJA" then
set destination to (makeNewFolder for (text 1 thru -6 of theName) at theContainer)
else
set destination to (makeNewFolder for theName at theContainer)
end if
tell application "Finder"
move anItem to destination
set the end of the output to the result as alias -- success
end tell
on error errorMessage -- duplicate name, permissions, etc
log errorMessage
# handle errors if desired - just skip for now
end try
end repeat
return the output -- pass on the results to following actions
end run
to getTheNames from someItem -- get a container, name, and extension from a file item
tell application "System Events" to tell disk item (someItem as text)
set theContainer to the path of the container
set {theName, theExtension} to {name, name extension}
end tell
if theExtension is not "" then
set theName to text 1 thru -((count theExtension) + 2) of theName -- just the name part
set theExtension to "." & theExtension
end if
return {theContainer, theName, theExtension}
end getTheNames
to makeNewFolder for theChild at theParent -- make a new child folder at the parent location if it doesn't already exist
set theParent to theParent as text
if theParent begins with "/" then set theParent to theParent as POSIX file as text
try
return (theParent & theChild) as alias
on error errorMessage -- no folder
log errorMessage
tell application "Finder" to make new folder at theParent with properties {name:theChild}
return the result as alias
end try
end makeNewFolder
Hope this helps.
It's a pity you get downvoted as I, personally, enjoy answering these sorts of questions, as it helps me practise and improve my own skills.
Thanks for posting your solution. I think it's a great gesture and others will find it useful.
This script is a bit shorter than and uses "System Events" instead of "Finder", so will be quicker for large numbers of files:
set IllustratorOutputFolder to "/Users/CK/Desktop/example"
tell application "System Events" to ¬
set ai_files to every file in folder IllustratorOutputFolder ¬
whose name extension is "ai"
set Output to {}
repeat with ai_file in ai_files
set AppleScript's text item delimiters to "."
get name of ai_file
get text items of result
set basename to reverse of rest of reverse of result as text
tell application "System Events"
get (every file in folder IllustratorOutputFolder ¬
whose name begins with basename)
move result to (make new folder ¬
in folder IllustratorOutputFolder ¬
with properties {name:basename})
end tell
set end of Output to result
end repeat
return Output -- list of lists of moved files
Just an alternative way of doing things. Not that it's better or worse, but just a different solution.
You could also save this as script.sh (in TextEdit in plain text mode) and run it with bash script.sh in Terminal:
cd ~/Target\ Folder/
for f in *.ai *.pdf *.jpg; do
dir=${f%.*}
dir=${dir% LOW}
mkdir -p "$dir"
mv "$f" "$dir"
done

Resources