Remove tags after moving item with AppleScript

I have chosen to automatically file items in DEVONThink using the below AppleScript inside a smart rule if / when an items is tagged. I am unable to get the last step (—Remove Tags) of the script to execute. Is it because the item has been moved? I am not a programmer so please speak slowly and I may understand it :). If there is a better way to do / write this I am all ears…

on performSmartRule(theRecords)
	tell application id "DNtp"
		repeat with theRecord in theRecords
			
			--Bryan Tag
			if tags of theRecord contains "Bryan" then
				set BryanFollowUp to get record at "/" & "Follow Up" & "/" & "Bryan" in database named "1. Smith Group"
				move record theRecord to BryanFollowUp
				
				--Deborah Tag
			else if tags of theRecord contains "Deborah" then
				set DeborahFollowUp to get record at "/" & "Follow Up" & "/" & "Deborah" in database named "1. Smith Group"
				move record theRecord to DeborahFollowUp
				
				--Jasmine Tag
			else if tags of theRecord contains "Jasmine" then
				set JasmineFollowUp to get record at "/" & "Follow Up" & "/" & "Jasmine" in database named "1. Smith Group"
				move record theRecord to JasmineFollowUp
				
				--Mike Tag
			else if tags of theRecord contains "Mike" then
				set MikeFollowUp to get record at "/" & "Follow Up" & "/" & "Mike" in database named "1. Smith Group"
				move record theRecord to MikeFollowUp
				
				--Patty Tag
			else if tags of theRecord contains "Patty" then
				set PattyFollowUp to get record at "/" & "Follow Up" & "/" & "Patty" in database named "1. Smith Group"
				move record theRecord to PattyFollowUp
				
				--Positive Results Tag
			else if tags of theRecord contains "Positive Results" then
				set PositiveResultsFollowUp to get record at "/" & "Follow Up" & "/" & "Positive Results" in database named "1. Smith Group"
				move record theRecord to PositiveResultsFollowUp
				
				-- Spencer Tag
			else if tags of theRecord contains "Spencer" then
				set SpencerFollowUp to get record at "/" & "Follow Up" & "/" & "Spencer" in database named "1. Smith Group"
				move record theRecord to SpencerFollowUp
				
				--Church Tag
			else if tags of theRecord contains "Church" then
				set ChurchFollowUp to get record at "/" & "Follow Up" in database named "3. Church"
				move record theRecord to ChurchFollowUp
				
				--Archive Tag				
			else if tags of theRecord contains "Archive" then
				set ArchiveItem to get record at "/" & "To be Filed" in database named "Ξ Archive"
				move record theRecord to ArchiveItem
				
			end if
			
			-- Remove all tags
			set the tags of theRecord to ""
			
		end repeat
	end tell
end performSmartRule

Before getting to your question, I’d like to remark on a very general problem with this code (which is not meant personally, it is just something that one can see fairly often). Whenever I see repetitions like “<tag>/identical group in identical database”, I cringe. This pattern calls for a data structure (very loudly). Even in AppleScript, a record might do the trick like so

set theTargets to {
  {tag:"Bryan", group:"/Follow Up/Bryan", database: "1. Smith Group"}, 
  {tag:"Deborah", group: "/Follow Up/Deborah", database: "1. Smith Group"}}

Then, in your main code, just loop over all the keys in theTargets. Adding a new tag/target combination is a lot easier that way (as is removing), and the code becomes easier to read. I know that this is a technique that is not obvious for beginners. Nevertheless, it is useful. See for a possible, untested solution in JavaScript at the end of this post.

Now to your code in particular, ignoring what I just said about a data structure.

First, instead of using the string concatenation operators in each and every set statement with constants, why not simply write
set BryanFollowUp to get record at "/Follow Up/Bryan" (and so on)?
A lot more legible, and it makes absolutely no sense at all to call a concatenation operator with constants.

Second, I’d also get rid of these SomethingFollowUp variables and just call them target everywhere, like
set target to get record at "/Follow Up/Bryan" in database named "1. Smith Group"

Third remove all these move statements acting on a particular record and replace them by a single one after the end if:
move record to target.

After that, your code should be shorter and cleaner, which are both necessary for “easier to understand”.

Now to your question. Since you not only want to remove the single tag that your script is acting on but all tags, you could

  • either remove the tags before you move the record (since you do not need them any more)
  • or use something like set newRecord to move record theRecord to target since (cf the documentation of DT’s scripting methods in Script Editor!) movereturns the record it just moved and then use set tags of newRecord to "

However, I’m not sure that setting tags to an empty string works since tags are a list. So you might have to use {} instead of "". OTH, it might be possible that AppleScript converts the empty string silently to an empty list – it is known to be “clever” sometimes.

I’d (of course) rewrite that in JavaScript, like so (UNTESTED!)

/* First, create a mapping of tags to groups and databases */
const mapping =  (() => {
  const retVal = {};
  ["Bryan", "Deborah", "Jasmine", "Mike", "Patty", "Spencer", "Positive Results"].forEach(name => {
    retVal[name] = [`/Follow Up/${name}`, "1. Smith Group"]
  })
  retVal["Church"] = ["/Follow Up", "3. Church"];
  retVal["Archive"] = ["/To be Filed", "Ξ Archive"];
  return retVal;
})()

function performsmartrule(records) {
  const app = Application("DEVONthink 3");

/* Loop over selected records */
  records.forEach(record => {
   /* Save the current record's tags in t */
    const t = record.tags();
  /* Loop over all predefined tags, i.e. the keys of the mapping defined above */
    for (const key of retVal) {
      /* If the current tag is in this record's tags list, index is its position in this list.
          This value is needed later to remove the tag from this record's tags list */
      const index = t.indexOf(key);
      if (index >= 0) {
        /* Get the target group/db for this key */
        const targetInfo = mapping[key];
        /* Abuse createLocation to get the target group as a record */
        const group = app.createLocation(targetInfo[0], {in: targetInfo[1]});
        /* Move the current record to the target, save it in newRecord */
        const newRecord = app.move({record: record, to: group});
        /* Set the newRecord's tags list to the old one's minus the current tag */
        newRecord.tags = t.splice(index,1);
      }
    }
  })
}

Thank you, very helpful