I wanted to send my close friend a “Good Luck at work today!” text message, but since he gets up and goes to work earlier than me, I decided I needed to schedule the message in advance. I found myself stymied because the iPhone doesn’t let you schedule messages.

There isn’t any such feature in the default Messages app, and Apple won’t allow any third-party apps to send a message without you explicitly tapping the Send button. There are some apps that offer workarounds such as Later, but they require you to either text from a different phone number than your own, or they throw up a notification for you to open the app and send a draft text. Neither one really works to my satisfaction.

Fortunately, thanks to Apple’s Continuity feature for iOS 8+ and OS X Yosemite, you can send a text message from your Mac through your iPhone. (Apple’s How-to.) That actually makes it somewhat straightforward, since Apple also helpfully includes scripting in most of their apps. All I need now is to make either an AppleScript or an Automator action to send the text via the Messages app, and then find a way to schedule the app to launch at the right time. Easy, right?

Scripting

Opening the Automator app in OS X reveals a long list of actions I can do… but none of them allow me to send anything using the Messages app. Okay, so instead I fired up the Script Editor app and after a few google searches to the appropriate forum I found the proper code necessary to send an iMessage.

tell application “Messages” send “This is an iMessage” to buddy “+12125551212” of (service 1 whose service type is iMessage) end tell

(You can also send SMS or AIM message or Google chat message, but Messages app considers them separate services and they are labeled as unintuitive strings. For now it’s simplest to go with iMessage for this discussion.)

Talking to myself late at night.

There we go. A few trials runs have me sending out test messages to myself without problems. It’s not all that useful, since the message and recipient are hardcoded into the app and it only sends at launch, but it’s a start. Let’s figure out how to make the app a bit more customizable:

display dialog “Who do you want to text?” default answer “” buttons {“OK”, “Cancel”} default button 1 set the recipient_name to result get text returned of recipient_name set recipient to (get text returned of recipient_name) display dialog “OK, what would you like to say to “ & (get text returned of recipient_name) default answer “” buttons {“OK”, “Cancel”} default button 1 set the recipient_message to result set theMessage to (get text returned of recipient_message) display dialog “OK, I will send to “ & recipient & “ the following: “ & return & return & theMessage buttons {“Confirm”, “Cancel”} default button 1 set the user_choice to the button returned of the result if the user_choice is “Cancel” then return user_choice tell application “Messages” send theMessage to buddy recipient of (service 1 whose service type is iMessage) end tell

Okay, okay, look in retrospect this isn’t exactly the most efficient way of copying variables, but this isn’t a language I use much. When you run the app, it pulls up a dialog box asking for the recipient, and then the message to send, and then a confirm box. Like so:

Note: it’s a good idea to comment out the actual message-sending when debugging. For some reason it would send repeated test messages to my friend in the middle of the night until I figured out how to set AppleScript variables properly.

I saved the script as a standalone Mac app and moved on to the next hurdle. (I tried recreating the app in Automator with AppleScript but I kept getting errors, so I gave up on that option.)

Scheduling

Apple has a few options for users to schedule apps to launch. You can use the UNIX-style cron system, but they want you to know cron is deprecated and may not work in future OS X versions. Instead, they prefer developers use the launchd system they created several versions of OS X ago. I tried looking through launchd and the XML plists required immediately seemed like too much effort to learn.

Instead I turned to the built-in Calendar app, which has a little-publicized feature that lets you launch an app instead of a typical calendar notification event. I set the calendar event to open the file as my alert, and did a test run.

Nothing happened. I tried a few times and got the same result, nothing. Some discussion on the OS X Yosemite forums speculated the event had to be saved on a Mac-only calendar not linked to iCloud or that GateKeeper wouldn’t let Calendar launch a first-run app, but I’m running El Capitan. Console showed me a cryptic error message:

3/21/16 12:35:00.179 AM CalendarAgent[310]: [com.apple.calendar.store.log.notifications] [Couldn’t resolve URL from bookmark: Error Domain=NSCocoaErrorDomain Code=259 “The file couldn’t be opened because it isn’t in the correct format.”]

Okay, I’m giving that up and trying another route. Cron it is then.

It’s not hard to schedule an app on OS X using crontab, provided you’ve used the Terminal before. My problem is that it’s not a one-off launch; it would be scheduled to launch at least yearly unless you went back later and removed the entry.

Yes I like the Matrix-style colors in Terminal. Because I’m cool.

Hard variables modified, script saved, cron job set. Took two hours to create, now to enjoy that extra hour I can sleep in. Oh joy.

My takeaway:

How has nobody created a “Schedule your text messages” app for OS X yet? The underlying APIs are really simple, and anyone could slap together a simple GUI. I’d do it myself but I don’t want to learn Swift. Will someone take this project off my hands pretty please?