Filed under: Software, Features, How-tos, Tips and tricks, Internet Tools, AppleScript
Use iCal to tweet automatically
Recently, the question came up of how to automatically "tweet" a birthday message to a friend or loved one on their special day. After thinking on this question for some time I finally came to a solution. As it turns out, intrepid TUAW blogger Dave Caolo wrote a Mac 101 article all about attaching AppleScripts to iCal events. Additionally, Brad Linder over at Download Squad put together a nice little tutorial for posting to Twitter via the command line.
It wasn't obvious at first, but these two articles together formed a dynamic duo of birthday tweeting proportions. If, dear reader, you are interested in setting up a system for sending out some birthday tweets then follow along as we travel the mysterious world of iCal events and command line tweeting. Read on for a somewhat technical tutorial on how to set up some pre-scheduled tweeting goodness. (If you're looking for a service to take care of all this for you, here you go.)
At first, I considered the possibility of using a cron job and shell script as the solution. I eventually discovered this would work, and we'll cover that later, but the melding of iCal and AppleScript was just too awesome to pass up.
The first thing we need to do is create our AppleScript which will be run by iCal. If you read Brad's article at Download Squad you have a basic idea of how this script is going to work. In the past we have covered AppleScripts so I'll skip the basics now; for more details check out this beginner's guide. Go ahead and launch Script Editor and create a new script like this one:
do shell script "curl -u username:password -d status=\"I'm in ur Tweets!\"https://twitter.com/statuses/update.xml"
stop
If the stuff in quotes seems familiar, it should -- I stole it from Brad. No, just kidding, but seriously Brad's post was a huge influence on this tutorial. Essentially, we're creating an AppleScript (which is iCal friendly) that runs a command line program to update your Twitter status. Because our AppleScript has to encapsulate the shell command in quotation marks, we have to use the UNIX escape character ("\") to tell AppleScript to ignore the quotation marks that are part of the shell command.
Replace "username" and "password" with the appropriate values as necessary and then add in your Twitter message. Press "Compile" to make sure everything is kosher and then go ahead and press "Run" to test it out. If all went according to plan your Twitter status will be updated with the test tweet you just typed (if you don't want to test with your regular Twitter account, you can create an alternate account for this purpose). Save the AppleScript somewhere that will be easy to locate. For example, I have a folder called "Scripts" in my Documents folder.
Now that we have an AppleScript that can update our Twitter status (you did save it somewhere right?) we can create an iCal event with an alarm to call our AppleScript. Using iCal, create an event called, for example, "Dad's birthday" on a given date such as July 16. Dave's article provides an excellent overview of the different types of iCal alarms that are available. The one that we are interested in is "Run Script." Selecting that option makes available a second option for choosing our birthday tweet AppleScript.
Just as with a standard message alarm, this AppleScript birthday tweet can be configured in several different ways. It can occur on the actual day at any given time or it can be configured to occur some number of days before or after. Additionally, because we used iCal for scheduling, it's possible to use multiple alerts on multiple days. You will also benefit from the fact that iCal is able to sync with MobileMe and with your iPhone. In other words, while iCal is doing your birthday Twittering for you, your iPhone can be reminding you its time to give your dad a phone call.
As I mentioned earlier it is also possible to send out some pre-scheduled Tweet-age using cron. For the uninitiated, cron is a time-based scheduler found in *nix operating systems. If you are using Windows, you can get cron set up using Cygwin. A cron-based sample of the above script looks something like this:
38 16 14 07 * curl -u username:password -d status="This was posted thanks tocron and the Twitter API! " https://twitter.com/statuses/update.xml
I won't get into the finer points of setting up a cron job; for a good overview read more here. Basically, it goes like this: create/view cron jobs by opening Terminal.app and running "crontab -e." If this is your first cron job then the resulting file will be blank. The cron jobs will be displayed using a command line text editor called "vi." Chances are, though, that if you're trying to set up a cron job you know how to use vi; for more on vi start here.
The beginning part of the line tells you at what interval to repeat the task. In the above example, the task (which starts with "curl" by the way) would be repeated on the 38th minute of the 16th hour of the 14th day of the 7th month. The simplest way of saying that is it will repeat on July 14 at 4:38PM. If you are setting up your cron job using OS X there is a great GUI program called Cronnix which can be used for easily setting up new cron jobs.
One thing to consider when using a shell script: the Twitter account credentials will be stored in plain text. For this reason it might be a good idea to store the credentials in ~/.netrc and chmod 600 ~/.netrc to prevent unwanted access from other users. In the case of using .netrc to store the user credentials the command would then look like this:
38 16 14 07 * curl -n -d status="This was posted thanks to cron and the TwitterAPI! " https://twitter.com/statuses/update.xml
Whether you use cron and a shell script or iCal and an AppleScript there are about a million other applications for automation and Twitter. It's clear that Twitter has taken the world by storm and with a little code sorcery you can really amp up your ninja ways. If you have any other Twitter automation tips throw them out in the comments; I am always looking for ways in which I can solve a repetitive problem with a little bit of coding.
Update: It seems that a couple people are having trouble getting this to work. The first thing I have run into is that there seems to be a problem with having special characters at the end of your tweet. If you are going to conclude your message with an exclamation point and are having problems try adding a space afterwards. Twitter will trim off any trailing spaces and it does not seem to count against the 140 character limit.
Another issue that has cropped up is that cURL is not able to authenticate Twitter's SSL certificate when using HTTPS. The solution is to either add the "-k" option before "-u" (more secure) or to change the script to use HTTP instead of HTTPS (less secure). As always, if you have any other issues speak up in the comments.

![TUAW [Cafepress]](http://www.blogsmithmedia.com/www.tuaw.com/media/tuaw-cafepress-promo.png)


Reader Comments (Page 1 of 1)
emil said 11:24AM on 7-17-2009
Wow, an automatic birthday greeting. How thoughtful. You shouldn't have.
Really.
Reply
josh said 9:53AM on 7-22-2009
When I try to use the script, I get the message "A application constant or consideration can’t go after this “"”." - any ideas?
jason said 11:47AM on 7-17-2009
Happy birthday, iCal.
Reply
kenfagerdotcom said 11:43AM on 7-17-2009
I'm getting the same error as Josh.
Reply
Martijn said 11:52AM on 7-17-2009
Put the stop command on the second line and it will work.
Reply
Tice said 12:55PM on 7-17-2009
To sad, doesn't work:
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). The default
bundle is named curl-ca-bundle.crt; you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
Does anyone know the solution for that error?
Reply
k626 said 1:07PM on 7-17-2009
Why is Brad Linder at DownloadSquad pretending that he wrote this post? Although he links to this original post, it's not at all amusing how people just copy whatever they like online.
http://www.downloadsquad.com/2008/03/07/post-to-twitter-using-the-command-line/#comments
Reply
greg said 1:14PM on 7-17-2009
I have a daemon running that blocks ssh break-in attempts, then it also tweets them to here:
http://www.twitter.com/cumuluscontent
It uses the perl module net::twitter
Reply
radek said 1:26PM on 7-17-2009
Agree! Twitter sucks a lot.
Reply
Frank said 3:12PM on 7-17-2009
i disagree. haters, move along – don't you have better things to do than post about how much you hate twitter?
Reply
Rob E. said 4:18PM on 7-17-2009
Some people just want to be grumpy. If you don't like Twitter, this obviously has no use for you. Doesn't mean it's a bad/or useless tip. It's just not for you. And maybe an automated birthday greeting is not for you. Great. That an Example. If you can't find an example that's helpful to you, fine, this tip is not for you. But here's what I immediately thought of: I work at a non-profit that has periodic events. I was thinking of setting up a Twitter account to communicate with some of our users and, in particular, to remind them of upcoming events. This tip is perfect for that. Especially because some events I would like to tweet about an hour or two ahead of time, but I have not guarantee that I'll be in a position to send out a tweet (or that I'll remember), so this tip seems perfect for that.
So thanks for this tip. But don't go posting other tips that aren't directly relevant to me and my life, because that's just a waste of time, and I will be forced to come back and whine about it. ;-)
Reply
NoAndThen said 4:30PM on 7-17-2009
Frank, we're not Haters, we're realistic people. Nobody gives a shit about your life (generalization here, not you specifically)- especially when it's described in 160 characters of broken English or less.
This is just a dumbass way to legitimize
'nigga-technology' by creating a roundabout way to plug that shit into a printer (God I love The Boondocks.)
There are plenty of far more worthwhile ways to spend your time.
What are you, 12? Way to use the word 'haters' in a sentence defending something as intelligent as Twitter, btw. Really high class.
Have a good day!
Reply
sodapop said 12:49PM on 7-18-2009
Seek therapy.
Reply
CSI48CJ01 said 7:52PM on 7-17-2009
I got this message. I copied the exact text from this site, changed the user:pass, and the status, but no luck. Please help me, because this would be so awesome!
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
sh: line 1: https://twitter.com/statuses/update.xml: No such file or directory
Reply
Zettt said 6:26AM on 7-18-2009
This script may be better (uses quoted form of, so you don't have to escape special characters):
set tweet to quoted form of "Here i am tweeting from Terminal"
do shell script "curl -k -n -d status=" & tweet & " https://twitter.com/statuses/update.xml"
stop
Regarding .netrc:
machine twitter.com login YOUR_USERNAME password YOUR_PASSWORD
Same without adding twitter.com to your .netrc:
set tweet to quoted form of "Here i am tweeting from Terminal"
do shell script "curl -u username:password -d status=" & tweet & " https://twitter.com/statuses/update.xml"
stop
Thanks for posting.
Reply
Robert said 5:30PM on 7-23-2009
I got the same error as CSI48CJ01... No clue how to get past that.. I'm in over my head! I couldn't find out how to get or install cURL though... is that necessary?
Reply