MailSuite Script for Filing Messages and Retaining Additional Mailtag Data

I use MailSuite extensively in my workflows (breaking those workflows was one of the major factors that finally pushed me off Evernote) and I am making some changes to the “File messages & attachments” script to capture Mailtags that I use in my workflow for an inbox rule and a Mail Act-On rule to file specific messages in DEVONthink.

I’m wondering if my mappings make sense, and also, thoughts about how to mapping/scripting a couple I haven’t quite figured out:

Mailtag message property DEVONthink record property Notes
keywords tags working
project tags working, some thoughts about using this as a group or database in addition or instead
notes comment working
tickle date reminder (once, on tickle date, alert); not working
importance ? values 1-5, could us labels?? not really a good fit, especially since I actually use the DT labels right now.

Mailtags properties I’m not using:

  • original message
  • tag identifier
  • server serial number
  • message uuid
  • preferred project and keyword colors

Some thoughts and questions for the community:

  1. I use the same three domains (Home, Work, Church) as top-level projects across Mail, Todoist, and (previously) Evernote (as notebook stacks) with actual projects as sub-projects (or tags) under those domains. I have my DEVONthink database set up with three top-level groups with the same names with subgroups to match the other applications. Redundant to add the Mailtags project as a tag? Should I just file it in the right top-level group? Separate databases for each of the three projects? Wondering what others think and trying to wrap my head around the pros and cons of multiple databases.

  2. What are the rules for editing and sharing the included scripts by Christian Grunenberg–I usually share my scripts on my own website once I get them working, with appropriate credit. But I’ve also only worked from scratch or from public domain or CC scripts to begin with.

  3. I have not been able to find a good AppleScript example of adding a reminder to a record–and I am really stuck on this one. Going to take another crack at it today, but if anyone can help point me to a working example…

Also, really appreciate all the helpful and patient feedback around here! Has made this transition so much more fun than it would have been otherwise.

1 Like
  1. This is largely a matter of personal preference or the requirements of a collaborative situation. Go with what makes sense to you and allows you to work efficiently with the data. Personally, I would create three separate databases, but again, that makes sense to me.
  2. The scripts are free to modify and share as you see fit, though the attribution block at the top of the script should remain in place.
  3. Here’s an example snippet for adding a reminder…
set d to date "Saturday, January 9, 2021 at 02:48:00 PM"

tell application id "DNtp"
	repeat with thisRecord in (selected records)
		tell thisRecord to make new reminder with properties {schedule:once, alarm:speak, alarm string:"hi", due date:d}
	end repeat
end tell

The parameters for a reminder are in DEVONthink’s AppleScript dictionary.

Thanks for the nice feedback It’s appreciated.

2 Likes

Got the tickle date to reminder workflow working. Thanks for the example.

You’re welcome :slight_smile:

Sharing in case anyone else is interested. Still tweaking, but it works:

  1. Make sure to update with path to your database.
  2. The script is sometimes creating a reminder even though no tickledate is set in MailSuite. Still trying to nail that one down.
-- Mail Rule - File messages & attachments
-- Created by Christian Grunenberg on Fri May 25 2012.
-- Copyright (c) 2012-2020. All rights reserved.

-- MailSuite routines added by rpallred

(*
======================================
// USER SWITCHES
======================================
*)
--Set this to "OFF" if you do NOT want MailTags copied into your DEVONthink item
--It must also be set to "OFF" if you do not have MailSuite installed
-- property MT_Switch : "ON" --Currently disabled


(*
======================================
// MAIN SCRIPT
======================================
*)
-- POSIX path of destination database. Global inbox is used if not specified.
property pDatabasePath : "/Users/uname/Databases/DatabaseName.dtSparse"

-- This string is used when the message subject is empty
property pNoSubjectString : "(no subject)"

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		-- Location of destination groups.
		set pMessageLocation to "/Saved Emails"
		set pAttachmentLocation to pMessageLocation & "/Attachments"
		
		tell application id "DNtp"
			if pDatabasePath is "" then
				set destination_database to inbox
			else
				set destination_database to open database of pDatabasePath -- Ensure that the database is open
			end if
			set message_group to create location pMessageLocation in destination_database
			set attachment_group to create location pAttachmentLocation in destination_database
		end tell
		
		tell application "Mail"
			set theFolder to (POSIX path of (path to temporary items))
			repeat with theMessage in theMessages
				try
					tell theMessage
						set {theDateReceived, theDateSent, theSender, theSubject, theSource, theReadFlag} to {the date received, the date sent, the sender, subject, the source, the read status}
					end tell
					if theSubject is equal to "" then set theSubject to pNoSubjectString
					
					--Process MailTags Info //Subroutine wasn't working, so put it inline.
					--if MT_Switch is "ON" then my mt_Process(theMessage)
					using terms from application "SmallCubed MailSuite"
						
						--Process list of MailTags Keywords
						set mtListOfKeywords to the keywords of theMessage
						if mtListOfKeywords is not "" then
							set mtTags to mtListOfKeywords
						else
							set mtTags to ""
						end if
						
						--Get the MailTags project
						set mtProject to the project of theMessage
						if mtProject = "missing value" then set mtProject to ""
						
						--Create devonTags from mtTags and mtProject
						if mtTags is not "" then
							if mtProject is not "" then
								set devonTags to mtTags & ", " & mtProject
							else
								set devonTags to mtTags
							end if
						else
							if mtProject is not "" then
								set devonTags to mtProject
							else
								set devonTags to ""
							end if
						end if
						
						--Get the MailTags notes
						set mtNotes to the notes of theMessage as rich text
						if mtNotes = "missing value" then set mtNotes to ""
						
						--Get the Tickle Date		
						set mtTickle to tickle date of theMessage
						if mtTickle = "missing value" then set mtTickle to ""
                                                --Still creating a phantom reminder with a due date at import time--inconsistent.
						
						
						(*
						Leftover from the Evernote version--not currently used.
						*)
						--Create the correct importance tag
						--set mtUrgencyHTML to ""
						--set mtUrgency to the importance of theMessage
						--if (mtUrgency is 5) then
						--set mtUrgencyHTML to "<b>Importance: </b><font color=\"#ff0000\">&#9612;Urgent</font><br>"
						--else if (mtUrgency is 4) then
						--set mtUrgencyHTML to "<b>Importance: </b><font color=\"#FFFF00\">&#9612;High</font><br>"
						--else if (mtUrgency is 3) then
						--set mtUrgencyHTML to "<b>Importance: </b><font color=\"#2EBE60\">&#9612;Normal</font><br>"
						--else if (mtUrgency is 2) then
						--set mtUrgencyHTML to "<b>Importance: </b><font color=\"#0077C8\">&#9612;Low</font><br>"
						--else if (mtUrgency is 1) then
						--set mtUrgencyHTML to "<b>Importance: </b><font color=\"#666666\">&#9612;Very Low</font><br>"
						--end if
						
					end using terms from
					
					tell application id "DNtp"
						set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, URL:theSender, source:(theSource as string), unread:(not theReadFlag), label:1, tags:devonTags} in message_group
						set comment of theRecord to mtNotes
						if mtTickle is not "" then
							tell theRecord to make new reminder with properties {schedule:once, alarm:alert, alarm string:(name & " is due today!"), due date:mtTickle}
						end if
						
						
						perform smart rule trigger import event record theRecord
					end tell
					
					repeat with theAttachment in mail attachments of theMessage
						try
							if downloaded of theAttachment then
								set theFile to theFolder & (name of theAttachment)
								tell theAttachment to save in theFile
								tell application id "DNtp"
									set theAttachmentRecord to import theFile to attachment_group
									set unread of theAttachmentRecord to (not theReadFlag)
									set URL of theAttachmentRecord to theSender
									perform smart rule trigger import event record theAttachmentRecord
								end tell
							end if
						end try
					end repeat
				end try
			end repeat
		end tell
	end perform mail action with messages
end using terms from

(*
=======================================
// MailSuite SUBROUTINES **NOT WORKING AS A SUBROUTINE**
// Inspired by example from: 
// http://ojisanseiuchi.com/2016/04/25/Using-AppleScript-with-MailTags/
=======================================
*)

on mt_Process(theMessage)
	using terms from application "SmallCubed MailSuite"
		if active MailSuite components does not contain "MailTags" then
			display dialog "MailTags is required for this script" buttons {"OK"}
			return
		end if
		
		
		
		
		
	end using terms from
end mt_Process

I’ve made two small updates to this script:

  1. Mapped MailTags importance to DEVONthink custom metadata. You want to create a custom data with label mailtagsimportance, or update the correct portion of the script
  2. Corrected an error where a message with no tickle date would import with a reminder for the time of import.
-- Mail Rule - File messages & attachments
-- Created by Christian Grunenberg on Fri May 25 2012.
-- Copyright (c) 2012-2020. All rights reserved.

-- MailSuite routines added by rpallred
-- v1.2 

(*
======================================
// USER SWITCHES
======================================
*)
--Set this to "OFF" if you do NOT want MailTags copied into your DEVONthink item
--It must also be set to "OFF" if you do not have MailSuite installed
-- property MT_Switch : "ON" --Currently disabled


(*
======================================
// MAIN SCRIPT
======================================
*)
-- POSIX path of destination database. Global inbox is used if not specified.
property pDatabasePath : "/Users/uname/Databases/DatabaseName.dtSparse"

-- This string is used when the message subject is empty
property pNoSubjectString : "(no subject)"

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		-- Location of destination groups.
		set pMessageLocation to "/Saved Emails"
		set pAttachmentLocation to pMessageLocation & "/Attachments"
		
		tell application id "DNtp"
			if pDatabasePath is "" then
				set destination_database to inbox
			else
				set destination_database to open database of pDatabasePath -- Ensure that the database is open
			end if
			set message_group to create location pMessageLocation in destination_database
			set attachment_group to create location pAttachmentLocation in destination_database
		end tell
		
		tell application "Mail"
			set theFolder to (POSIX path of (path to temporary items))
			repeat with theMessage in theMessages
				try
					tell theMessage
						set {theDateReceived, theDateSent, theSender, theSubject, theSource, theReadFlag} to {the date received, the date sent, the sender, subject, the source, the read status}
					end tell
					if theSubject is equal to "" then set theSubject to pNoSubjectString
					
					--Process MailTags Info //Subroutine wasn't working, so put it inline.
					--if MT_Switch is "ON" then my mt_Process(theMessage)
					using terms from application "SmallCubed MailSuite"
						
						--Process list of MailTags Keywords
						set mtListOfKeywords to the keywords of theMessage
						if mtListOfKeywords is not "" then
							set mtTags to mtListOfKeywords
						else
							set mtTags to ""
						end if
						
						--Get the MailTags project
						set mtProject to the project of theMessage
						--if mtProject = "missing value" then set mtProject to ""
						
						--Create devonTags from mtTags and mtProject
						if mtTags is not "" then
							if mtProject is not "" then
								set devonTags to mtTags & ", " & mtProject
							else
								set devonTags to mtTags
							end if
						else
							if mtProject is not "" then
								set devonTags to mtProject
							else
								set devonTags to ""
							end if
						end if
						
						--Get the MailTags notes
						set mtNotes to the notes of theMessage as rich text
						if mtNotes = "missing value" then set mtNotes to ""
						
						--Get the Tickle Date		
						set mtTickle to tickle date of theMessage
						if mtTickle = "missing value" then
							set tickleTest to "0"
						else
							set tickleTest to "1"
						end if
						
						--Create the correct importance tag
						--Requires a custom metadata tag with identifier 'mailtagsimportance'
						set messageImportance to the importance of theMessage
						if (messageImportance is 5) then
							set mtImportance to "Urgent"
						else if (messageImportance is 4) then
							set mtImportance to "High"
						else if (messageImportance is 3) then
							set mtImportance to "Normal"
						else if (messageImportance is 2) then
							set mtImportance to "Low"
						else if (messageImportance is 1) then
							set mtImportance to "Very Low"
						end if
						
					end using terms from
					
					tell application id "DNtp"
						set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, URL:theSender, source:(theSource as string), unread:(not theReadFlag), label:1, tags:devonTags} in message_group
						set comment of theRecord to mtNotes
						--Make sure you have created a custom meta data with the label 'mailtagsimportance' or update the script
						add custom meta data mtImportance for "mailtagsimportance" to theRecord
						if tickleTest = 1 then
							tell theRecord to make new reminder with properties {schedule:once, alarm:alert, alarm string:(name & " is due today!"), due date:mtTickle}
						end if
						
						
						perform smart rule trigger import event record theRecord
					end tell
					
					repeat with theAttachment in mail attachments of theMessage
						try
							if downloaded of theAttachment then
								set theFile to theFolder & (name of theAttachment)
								tell theAttachment to save in theFile
								tell application id "DNtp"
									set theAttachmentRecord to import theFile to attachment_group
									set unread of theAttachmentRecord to (not theReadFlag)
									set URL of theAttachmentRecord to theSender
									perform smart rule trigger import event record theAttachmentRecord
								end tell
							end if
						end try
					end repeat
				end try
			end repeat
		end tell
	end perform mail action with messages
end using terms from

(*
=======================================
// MailSuite SUBROUTINES **NOT WORKING AS A SUBROUTINE**
// Inspired by example from: 
// http://ojisanseiuchi.com/2016/04/25/Using-AppleScript-with-MailTags/
=======================================
*)

on mt_Process(theMessage)
	using terms from application "SmallCubed MailSuite"
		if active MailSuite components does not contain "MailTags" then
			display dialog "MailTags is required for this script" buttons {"OK"}
			return
		end if
		
		
		
		
		
	end using terms from
end mt_Process
2 Likes

This was absolutely great.

How do I change the script so that:

  1. Instead of the mailto:// URL I get the message:// URL in the URL field
  2. Not get a red to-do label
  3. Import the attachments (with tags) as separate records?

I’m glad you like it!

This is beyond my off-the-cuff AppleScripting skills. I’ll add this to my list of potential upgrades. If someone else wants to try to figure it out…

It would be in this line:

set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, URL:theSender, source:(theSource as string), unread:(not theReadFlag), label:1, tags:devonTags} in message_group

Change URL:theSender to a variable that has captured the message ID link

In the same line above, change or remove label:1

I use a totally different script (one of those included in DT) and workflow (Mail rule) if I want just to save the attachments–it could be incorporated into a script like this, but it would significantly increase the complexity of the script…I’ll consider it for a future improvement.

…
tell theMessage
   set {theDateReceived, theDateSent, theSender, theSubject, theSource, theReadFlag, theID} to {the date received, the date sent, the sender, subject, the source, the read status, message id}
end tell
   set msgID to "message://%3c" & theID & "%3e"
…
  set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, source:(theSource as string), unread:(not theReadFlag), label:1, tags:devonTags} in message_group
  set URL of theRecord to msgID -- Set the URL here
2 Likes

Tickle date has been replaced by review date. Any solution please? Thank you.

Let me take a look!

1 Like

I see that in the interface, SmallCubed has changed Tickle Date to Review Date:

But in the AppleScript dictionary, the property is still called tickle date and the scripts correctly pulls it in this portion of the script:

--Get the Tickle Date		
						set mtTickle to tickle date of theMessage
						display dialog "Tickle Date: " & mtTickle -- Test that tickle date is correctly pulled
						if mtTickle = "missing value" then
							set tickleTest to "0"
						else
							set tickleTest to "1"
						end if

I have confirmed, however, that the date is not transferring to the DT reminder correctly:

image

if tickleTest = 1 then
							tell theRecord to make new reminder with properties {schedule:once, alarm:alert, alarm string:(name & " is due today!"), due date:mtTickle}
						end if

–so still working on that–after I get home from my kid’s friend’s birthday party…

1 Like

Thank you. Much appreciated.

Finally had the time to troubleshoot this and updated the Tickle Date section to read:

--Get the Tickle Date
set mtTickle to tickle date of theMessage
if mtTickle is missing value then
    set tickleTest to "No"
else
	set tickleTest to "Yes"
end if

and the record creation section to:

tell application id "DNtp"
	set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, URL:theSender, source:(theSource as string), unread:(not theReadFlag), label:1, tags:devonTags} in message_group
	set comment of theRecord to mtNotes
	if tickleTest is not "No" then
		tell theRecord to make new reminder with properties {schedule:once, alarm:alert, alarm string:(name & " is due today!"), due date:mtTickle}
	end if
	--Make sure you have created a custom metadata with the label 'mailtagsimportance' or update the script
	--must be last part or others don't work
	add custom meta data mtImportance for "mailtagsimportance" to theRecord

I’m not an AppleScript person, but why are you using strings for tickleTest instead of a boolean? And why even have a variable if the record part could simply do a
if mTickle is not missing value then …. Or maybe that’s not possible in AppleScript?

Also, double negation (if something is not false) is more difficult to understand than a positive statement like if something is true.

Good lord–you’re right!

Have you ever heard the story of the woman who cut the ends off her roast? I originally broke this part out and added the test (and a bunch of dialogs) trying to trace an issue where the reminder wasn’t getting created at all.

It turns out, the issue is the custom metadata–it has to happen after everything else (note sure why). But in all my troubleshooting (and sometimes just throwing code at the wall until anything worked), I made it way more complex than it needed to be, then forgot to go back in and simplify once I knew what the problem was.

Thank you.

The corrected sections of code:

--Get the Tickle Date
set mtTickle to tickle date of theMessage

and

tell application id "DNtp"
	set theRecord to create record with {name:theSubject & ".eml", type:unknown, creation date:theDateSent, modification date:theDateReceived, URL:theSender, source:(theSource as string), unread:(not theReadFlag), label:1, tags:devonTags} in message_group
	set comment of theRecord to mtNotes
	if mtTickle is not missing value then
		tell theRecord to make new reminder with properties {schedule:once, alarm:alert, alarm string:(name & " is due today!"), due date:mtTickle}
	end if
	--Make sure you have created a custom metadata with the label 'mailtagsimportance' or update the script
	--must be last part or others don't work
	add custom meta data mtImportance for "mailtagsimportance" to theRecord

One (perhaps final :wink: ) question: Why do you set type to “unknown” in the call to create record?

…because that’s how @cgrunenberg does it in his script, “Mail Rule - Add messages to DEVONthink,” upon which my script is based.

So…I dunno. ¯\_(ツ)_/¯

That is correct and has been for a very long time. This may change in the future.