Email merge from spreadsheet or CSV data using Shortcuts

Shortcuts support for Numbers is surprisingly limited. On the Mac, if you display the list of available actions for Numbers, you will get a short list, none allowing you to read out from a Numbers file.

2023-05-06-14.50.53

In terms of being able to read data out, then a CSV file is a plain text file format and Shortcuts can read plain text files, so that would be better.

Given you are mail merging using basic contact data (first name, e-mail address, (house) number, and street (presumably first address line), it could make sense for you to use your address book and have a group for the contacts.

The following example will build an example CSV file, and then process it. The default CSV file it creates is as follows:

"Steve","cap@shield.com","50","Brooklyn Street"
"Bruce","bruce@hulk.com","-","Anywhere"
"Tony","iamironman@enterprises.stark","1","Avengers Tower"

The output is then as follows:

Steve,

Your mailing address is 50 Brooklyn Street.  Blah Blah Blah.

Best,

Me

---

Bruce,

Your mailing address is - Anywhere.  Blah Blah Blah.

Best,

Me

---

Tony,

Your mailing address is 1 Avengers Tower.  Blah Blah Blah.

Best,

Me

Many text editors would with a bit of find and replace, or a crafted shortcut, would allow you to change simple text formats (e.g. manay spreadsheet applications copy as tab separated values (TSV) into a structured JSON format, which is a dictionary interchange format that Shortcuts uses. But for maintenance purposes, I think using a CSV or contacts as covered above would be a better fit.

They are all working fine, you are just referencing the wrong variables. I have colour coded what actions each of your “Updated Text” magic variables reference. It is good practice to give your magic variables meaningful names to avoid confusion.

In effect what you have is your third replace carried out a replace on the first rather than the second replace, and then you simply never use the third replace, instead making rich text from the second replace action. If you had set it to the third action, then you would have found you second replace action, for NUMBER, would have been the variable that seemed to be being missed out.

2023-05-06-15.56.52

A little further down, I have a reworking that includes renaming of variables to make things clearer.

When hovering over the select all option there is a pop up about a list, but the base documentation for the action does suggest dictionaries are treated as lists. Really I think it is just poor documentation.

2023-05-06-16.03.45

It certainly does work for lists, and that’s the key to thinking about this.

If you are selecting from a dictionary, the dictionary can be multiple levels deep. Would a select all mean select all the root level items, all items at all levels, or something else? What would be the consistency?

The way to deal with this is to choose from the list of keys at the root level of the dictionary, then in the loop, instead of working on the repeat item, which would just be a key name, you use the repeat item to get the nested dictionary and then work on the elements in that.

That’s probably not all that meaningful in words, but don’t worry I’ve got a reworking of the shortcut a little further down.

Shortcuts is defaulting the rich text to the Times font. The rich testxt is already set as that before it ever reaches the Mail app, which is presumably where you specified your default font. The resolution is to specify the font you want before you convert the Markdown to rich text.

While it might seem at first there is no way to do this, the key things to know are that Markdown supports HTML, and behind the scenes the Shortcuts conversion engine is transforming the Markdown to HTML and then generating rich text from that. Because of this you can add a bit of HTML and CSS to the text before it is passed to the Markdown to Rich Text action.

The shortcuts example below takes your original shortcut, adds in more variable names, uses the dictionary keys for choosing, sets the generated rich text to be Helvetica, and shows each output instead of producing an e-mail (I didn’t want to be e-mailing and I don’t use the stock Mail app).

Try unchecking the show compose sheet option.

2023-05-06-16.37.16

There are a number if ways you could tackle this. Here are just a few.

  • You could add an entry in the listing that tracks if they have been mailed before.
    • Note this requires writing back to your original file into a specific field of a contact record (or updating some property of a contact if you opt to use contacts and a contact group).
  • You could store a separate list of previously mailed users and filter those out.
    • This is just a different way of tracking the same data.
  • You could use a new file (ad hoc) each time that once they are mailed get appended to your mailed to list.
  • You could start looking at databases to track data, but that will only be worthwhile if your complexity grows.

In addition to the above, you could also potentially filter your list to allow you to select the last X entries (you enter X when the shortcut is run - you could even have a menu of options - All, last 5, last 10, last N (where you enter a number)). The assumption would be you always add your new records at the start or at the end each time. You then fetch the file content, split it into a list, reverse the list and filter it to your desired number.

There are apps that can help with this, but if you need to do it with native Shortcuts, there are a few “tricks” you can apply that are not at all obvious, but come in handy sometimes.

But ultimately, yes you can build in more flexibility, but flexibility introduces more complexity and given you note that you are a novice, maybe think about this now and consider it as part of a phase 2 once you have something in place that let’s you work for now.

Your shortcut is set to use the input to the shortcut which is what that block refers to. You can see it referenced in your Send action.

2023-05-06-17.11.01

Here is the in app description for the Comment action.

2023-05-06-17.12.17

The purpose is purely documentation.

I think fundamentally this one relates back to the post you referred to where you had found an answer I had posted. I believe this was simply a modification of Mike’s shortcut. the comment was his, and he was taking input to the shortcut. For my testing, as noted in the post, I put the content of the comment into a text action so I could use it rather than passing it in all the time. It simply kept the shortcut self contained, and Mike sould then just revert it easily to using the shortcut input if he wished - the comment still being in place.


I think that covers all of the requirements, issues and questions you had, but if I’ve missed anything, I can try and pick it up in a second pass.

2 Likes