Since getting my new Mac a few days ago, I’ve been trying to move my iOS writing automations over. However, one of the main shortcuts just wasn’t possible on the Mac. It’s the “Link Post” shortcut that I’ve been using for quite some time on my iPad.
It doesn’t exactly do much, but it saves a lot of time and effort. It essentially uses the share menu in Safari to pass the article and the highlighted text to a shortcut. From there, it extracts the title, author, and url of the article, along with formatting the selected text as a markdown blockquote (using my app, Text Case), formats it nicely, and creates a new sheet in Ulysses. Leaving me to add some comments to the sheet, before publishing it to my blog.
Turns out the Mac’s a bit more complicated, as while there’s a share menu, you can’t use it to launch a shortcut. So, my existing solution was out the window.
I tried a few other options that sounded promising, such as the “Get Article from Safari Reader” action that seemed to be precisely what I wanted. I’d be able to detect the URL somehow, and then be able to extract any information manually. Unfortunately, this action doesn’t work, and I’ve been told it hasn’t been working for some time.
After some experimenting, I realised that as long as I could have the URL and highlighted text, then I would be able to come up with something sufficient. Because from the URL, I can make a quick GET request, and get the page title. I haven’t worked out how to get the author using this method, but it wasn’t exactly reliable on iOS anyway.
My last option was to try to use macOS Services. I discovered that if I used a service from Safari, then it received the selected text as the input. And to top it off there was also a way to receive the “onscreen content” inside a shortcut, which in the case of Safari, returns the URL of the current page.
That meant I was able to combine the selected text from the input, and the URL from the onscreen content, and put together a link post generator.
After fetching the page title and url, the only thing it needs to do is to format the selected text as a Markdown blockquote using Text Case, and put it together into a nice format.
It’s definitely not the quickest shortcut, with it taking around 5 seconds to create the Ulysses sheet, but it’s definitely better than doing all of this manually. I also added a notification after the sheet is created, so you can be sure it’s done. And you also get an option to open the sheet straight away.
How I Managed to Automate Posting to My Ghost Blog #
For those that don’t know, this blog runs on the Ghost blogging platform. A platform that is notoriously not that good at dealing with automation, or working from iOS devices, since they don’t have their own apps, and rely on third-parties integrating with their API.
The app I use for writing right now is iA Writer, and luckily for me, it has integrated with the Ghost API. So after I created an API token from my blog’s admin panel, I was able to publish to my blog. Except that you can only publish drafts, you can’t control things like tags or the slug, and the title is the name of the file, not the typical H1 title from the Markdown content.
I wasn’t happy with the process, since I had to use the web interface for every post, but I just got on with it because there wasn’t an alternative.
But, I’ve been looking into Craft recently, and it reminded me that my publishing workflow isn’t flexible at all. So there would be no chance of me publishing anything from Craft.
Ghost Admin API
That lead me to have a look at the [documentation for the Ghost Admin API]. Which to be honest I think is pretty bad, it’s written like a blog post, rather than clearly defining each request. Plus they override the ⌘ + F keyboard shortcut for a stupid search tool, so that made it more difficult to find anything.
After I got to grips with how it worked, I realised that it would be too much of a hassle to interact with the API just using the Shortcuts app. Simply because of the authentication method. It uses a signed JWT token, which isn’t a bad thing, but it is when you have to construct and sign the token yourself.
After you add a custom integration to your blog, you can find an “Admin API key”, which sounds pretty good. Except this isn’t a ready-made key that you can use for authorisation. First of all, this key is actually two things, one half is a key that goes as part of the kid inside the JWT token, and the other half is a string that you need convert from hexadecimal into bytes, and then use that to sign the JWT token.
It was too complex for me to even attempt using Shortcuts, and I’d need a few libraries if I wanted to write some JavaScript, so I couldn’t use Scriptable either.
Which meant the only option was to write an app instead.
Although, not a fully functioning app, I only actually wanted a few Shortcut actions. So I ended up creating a SwiftUI app that looks like this:
However, there are actually three Shortcut actions that it provides:
Get Blog Info
Upload Image
Create Post
The first one isn’t actually needed, but I used that to test out the Shortcuts action and API integration, since it has no parameters, and doesn’t require authentication. It just fetches some basic information about a Ghost blog.
Image Upload
But the first real action I worked on was uploading images. It was a bit tricky, dealing with accepting a file as an input, and then getting the data in a state where it could be uploaded. I had an issue for a while where the app didn’t have permission to access the file, so I had to copy the data, write it to the app, and upload it to the blog.
I’m not too sure how stable this action is, especially since the endpoint only accepts a few image formats (not HEIC). So I have to do a conversion first. Although I’m doing this in Shortcuts for simplicity. But at least it works!
Here is the Shortcut I’ve created to upload an image:
Post Creation
Now the big one, creating posts. This was a slightly bigger task, but a relatively straightforward one to build.
There are five parameters in the Create Post action:
Title
Slug
Content
Status (Draft/Published)
Tags
Essentially, they just all need to be passed on to the API. A bit of formatting is involved, with the tags being parsed from a comma-separated list to an array of strings, and the HTML content being wrapped in Mobiledoc format (which is what Ghost uses).
There is a ton of data in the response, but since I don’t see most of it being useful, I only look for four pieces of information:
Title
Slug (I thought this would be helpful, not so sure now)
URL
Featured Image URL
I’m only using the title and URL in my shortcut right now, as it’s still pretty simple.
The first part of the Shortcut deals with the title. First of all, it removes the first H1 from the document and also extracts the title without formatting for later. This was taken from Federico Viticci’s Publish to WordPress shortcut.
After that, I use my app Text Case to format the title into AP Title Case, convert the Markdown content into HTML, and also to create a slug from the title.
Then I run it through the new Create Post action.
From there I have the post information, which means I can automate sending a tweet about the new blog post and launch the page in Safari.
It’s good to have publishing to the blog and Twitter in one place because I plan on experimenting with different types of posts on my blog soon, so it’s nice to have control.
The App
To be honest, I don’t think the app will ever go public. That thought did pop into my head a few times while building it, but it will take a bit of work to make it user-friendly. I’d have to untie it from my blog, add some stability, and maybe even do error handling. Because right now, it either works or it doesn’t.
But you never know, maybe this is an idea I can take further? Not sure how much I’d need to charge for it though, since the number of people that have a blog, use Ghost, want to automate the process, and also want to pay money for it, is probably quite low.
Josh Holtz, has announced his new app ConnectKit for Shortcuts, which bridges the gap between Shortcuts and the App Store Connect API. Surprisingly, you can access quite a lot of the functionality from App Store Connect over the API, including managing users, TestFlight, app metadata, reporting, and even more!
You can use the built-in token storage for free, along with the action to generate a JWT token that can be used to make authentication requests to the API. But for just a small tip, you can unlock four premium actions which is where the magic is.
There’s an action to get your apps, and also your sales and finance reports, which both come with quite a lot of parameters. For the rest of the API functonality, you can use the Make Request action, which lets you interact with the API directly, but you get the added bonus of the JWT token being generated for you automatically.
When I saw this app on Twitter, I immediately thought about how you could combine it with something like Charty to view super custom charts for sales. Fortunately, Josh has gone one step further and provided a ton of examples in the app, and on his blog post. Some you may expect like viewing charts in Charty, and app data in WidgetPack. But also submitting an app for review via Siri.
It sounds great, and I’m very much looking forward to seeing how I can put it to use.
Apple in iOS 14.3 is streamlining the Home Screen customization process by simplifying the way that app shortcuts work. With the launch of iOS 14, users quickly discovered that Shortcuts could be used to replace traditional app icons to create an entirely customized Home Screen look.
Unfortunately, while these Home Screens created with Shortcuts looked fantastic, the experience was less than ideal because launching an app through shortcuts required the Shortcuts app to open briefly, slowing the app opening process. In iOS 14.3 beta 2, that’s no longer the case because shortcuts no longer have to route through the Shortcuts app.
Such a small change, but yet this is going to make a massive difference. Custom home screens are the thing now, and major component of that is using Shortcuts to create custom app launchers. And until 14.3, they require Shortcuts to open before running the shortcut. But with this change, they’ll start to look and feel like real apps.
I like how Apple have been slowly integrating Shortcuts into the system. Bit by bit, iOS is becoming more customisable, allowing users to really make their devices their own.
A bit of a weird headline, I know. However, to be honest, this post was originally going to be a short aside, about myself being delighted with the delay function on my washing machine.
For content, I bought a house with my girlfriend a little over 18 months ago, and the seller left a perfectly functioning washing machine. It was always something we were thinking about replacing at some point in the future, especially when after a few months we noticed that it would occasionally leak water from the door. Probably just needed a new seal, but it was old anyway, and it didn’t fit the style in our kitchen anymore.
Luckily for us, a few weeks ago someone in my girlfriends family had a washing machine going spare (moving house), and it was in pretty good condition. So we gladly took it off their hands.
Fortunately for me, it had a delay function. I know it’s not advanced technology, I’ve seen what you can get for stupid amounts of money. But it’s enough to do the job for me.
The only issue I have with doing the laundry is that I always feel the need to do it at weird times. For example, it’s 22:00 and I’ve only just put a load of washing on. That’s not a problem in itself though, the issue is that I would prefer to have it freshly washed at a time where the sun is out and I am free to put it outside to dry. Right now, that time is around 12:30pm. Because that’s around the time I take my lunch break, and it means I can get it put in a few minutes, and it dries pretty quickly.
So by having a delay function, I’m able to be sporadically productive at weird times, put a load of washing in the machine, and set it to be ready for exactly when I need it. Except, the delay is exactly that, a period of time before the function starts, not a set time for it to run or finish by. Also, the precision is to an hour. So the only calculation I need to do is to work out the number of hours until noon the next day, and then subtract however long the wash duration is. Not exactly a hard calculation, but I’m lazy. So I came up with a needlessly complicated shortcut to do it for me.
If you’re expecting something minimal that just does the job, then look away now. This may look a mess, but it produces a pretty nice output.
First of all, it asks for the time that I wish the washing to be ready. In most cases this will be 12:00, so that’s the default value. It then formats this time, so it can be used later in the format, and stores it in the Washing Time variable.
Afterwards, it calculates the time between the current date and time and the selected time (which by default uses the current date). It’s to check whether that time has already passed in the current day or not. If it has passed, then I must mean tomorrow, if not, then it’s today. I could simply prompt for input, but if I can save any interaction then I will.
If it determines that I must mean tomorrow, then it adds 1 day to the date stored in the Washing Time variable, and also sets a new variable called Today or Tomorrow to “tomorrow”.
If it’s for today, then the date stays the same, and Today or Tomorrow is set to “today”. This variable is nothing special, just a string that I use later on in the final message that appears. This if statement was just a good place to put it, to avoid duplicate logic.
Now it knows the date and time that the wash needs to be ready by, it also needs to take into consideration the duration of the wash. Similarly to the previous input, the most used wash on my washing machine is 76 minutes, so I put that as the default to make it easier.
That duration is subtracted from the earlier calculated wash time, this will be the time that the wash needs to start. It then calculates how minutes there are until that time.
That duration is now formatted into an Hour:Minute format. The minutes are first calculates using the modulus operation, and the hours are calculated by removing the aforementioned “minutes” value, and diving by 60.
There is a little if statement afterwards to check if the minutes value is less than 10. This is to make sure the minutes are always formatted as two digits. There could be a better way for this, but I know that this way works.
After calculating the delay needed, it wraps it into a friendly message with all the information I may or may not need.
Example: 🕰 The required delay for a 76 minute wash to finish today at 12:00 is 10:32 🧼
Now I’ve finished writing about this, it has occurred to me that I’ve blown this problem completely out of proportion. But it was fun, so who cares?
How I’m Using Shortcuts and Data Jar To Help Write Link Posts #
Last night I spent some time reading on my iPad, and I noticed a few articles that I might want to link to from my blog. Except I didn’t want to start creating drafts in iA Writer, or doing any manual work. I just wanted a way to remind myself that I want to link to this at some point.
I started to think that I could simply create a reminder in the Reminders app (I’ve switched from Things), possibly with the URL as a note so I could get back to it when I needed it again. However, that would require me to then later load the URL, and fetch the details from it. And seeing as I would have had the article loaded at the time of reading, it made more sense to store this data, and then be able to reference it at a later date.
So I came up with an idea of two shortcuts, one to store relevant data about the article I wanted to reference, and then another which I could use to select from the list and kick off a draft in iA Writer.
That’s when I thought about using the recently released data store app, Data Jar, which is a fantastic tool for storing all kinds of data.
Store Link Post Idea
To start off, the Shortcut I created to do the initial data storing and reminder creation was relatively simple. It accepts input from the Share sheet, in the form of a Safari web page, and then has just three actions:
Add a new reminder with the title of the article to my blog list.
Create a dictionary with four pieces of data – the title, URL, any text that was selected that I want to quote, and also the author. Although I’ve found the author to not be very reliable.
Store this dictionary at the end of my drafts list in Data Jar.
This shortcut is a bit more complex, as it has to do quite a few things:
Retrieve the list of link post ideas from Data Jar.
Show the list, and allow the user (me) to select an option.
Transform the various pieces of data into a link post outline.
Create a new document in iA Writer.
It’s a bit long, so I’ll put the long screenshot below, and then explain why it may seem pretty complicated for what it does, and the things I had to work around.
To start off, the shortcut gets the list of drafts from Data Jar. This contains all the drafts that have been saved.
It then does a little transformation with that data, using a temporary variable in Data Jar. It clears the value for the specific key I’m going to use, and then it loops through the list of articles, and extracts the title and the index of each article into a new list. This is because we need to show the list of articles, and also perform operations on the specific article that was selected.
The temporary list is then displayed, and from the chosen article, the Index is then used to fetch the complete article data from Data Jar. That includes the title, author, page selection (snippet), and the URL.
Once that data is extracted, the page section is formatted as a Markdown Blockquote via Text Case (my app), and then it’s put together with the rest of the data to form a basic link post outline.
Finally, the outline is URL encoded and opened as a new document in iA Writer via the URL scheme.
These two shortcuts are simple in theory, and to be honest I could have achieved the same result with less complexity, and maybe even without Data Jar. However, I like that the storing and kicking off a link post in iA Writer are separate processes. Because it allowed for more flexibility in the future and also doesn’t distract me at the time of reading an article. Which was one of the big reasons for me making these.
I really liked using Data Jar for these as well, so I hope I can make use of it again in future shortcuts!
I write a lot of my blog posts on my iPad using iA Writer, and because it is mainly a text editor, it doesn’t support adding photos directly into a document. This makes it slightly more cumbersome for myself when I’m trying to include an image in a post, so I’d have to go to the web interface of my blog, upload an image manually, and then copy the URL.
However, it recently came to my mind that I could probably automate this process. And of course, that would be with the Shortcuts app.
So I made a simple Shortcut that can be run from the Share Sheet, accepting only images.
Then because I simply want to upload it to my WordPress blog (I have no separate CDN for images), I attempted to use the “Post to WordPress” action. Which I only just discovered can upload media, along with posts and pages.
And just like when you upload a new post using that action, the result is the URL of the uploaded post/page/media.
Although the URL that was returned wasn’t exactly the one I was looking for. I was expecting the absolute URL for the image that was uploaded. But instead, it was the URL of a kind of “preview” page, which is essentially the same template used for a blog post, except the content is the image that was uploaded.
This stumped me, and I was considering giving up with the Shortcut at this point. But I realised that Shortcuts can handle articles on websites pretty well.
So I played around with the various actions that dealt with articles and found a very simple solution to extract the image URL. It turns out, in the weird media post (that’s not actually uploaded as a blog post 🤨) has the uploaded image set as being the featured image.
That meant that I could extract that using the “Get Details of Article” action, right after the “Get Article using Safari Reader” action, and then select to get the “Main Image URL”. And it worked perfectly.
So with the fundamental work done, I added an “Ask for Input” action at the beginning, to extract the title of the media. And also a “Text” block, to use the title and image URL and format it as Markdown so it can then be quickly copied and pasted into a document in iA Writer.
So after all of that talking, I’m sure you would like to see what the Shortcut actually looks like:
Hopefully either the resulting Shortcut can be useful to other people, or at least my thought process behind it, as no matter how good you think you know Shortcuts, it also seems to surprise you.
After I started writing the entries, I realised I didn’t want the boring task of creating the file in a specific directory, and creating the same title/header over and over again. So I added a tiny bit of automation.
Things Task
The first thing I did was to set up a task in Things, that repeated every day, simply to tell me to write my journal. After a while, I noticed that I would sometimes get very close to 12 before remembering about it. So I added a reminder for 11 pm, which gives me a bit of time to delay and still get it done in time.
Journal Template Shortcut
To take the hassle out of creating the initial file, I created a relatively small shortcut that creates the template and opens it in iA Writer.
I have a specific directory for my journal entries, and this keeps them all in one place.
It also uses the current date to create the filename and the heading for the post.
From there, it opens iA Writer, so I can jot down what I did in that day. And it’s ready to be published
While Things is useful enough to help me remember I need to write my entry, and the shortcut helps to create the initial file, I also linked these together.
I did that by adding a custom URL into the body of the Things task, so whenever it notified me, I could tap on the task and then on the link. It would then launch the shortcut, and lets me immediately start writing.
It also allows me to not starting right away, as sometimes I’m not in the best place to do it, or I just want to put it off a bit longer.
The url is quite simple, and is in the following format:
shortcuts://run-shortcut?name={name}
{name} is the name of the Shortcut, but URL encoded. You may be able to work this out yourself, but my app Text Case can also do this for you.
More Automation
After I finish writing my journal entry for the day, I then publish it to my blog. I use the built-in “New Draft on WordPress” share extension, which then opens the draft in Safari where I can add the category, and publish.
It’s a reasonably quick task, but something else I plan on automating. So in the near future, I will be creating another shortcut, that can take the latest journal entry and publish it to my blog using the specific category and time I like.