As a fun little project, I decided to write a PHP script to post jokes and random bits of wisdom to Twitter. Now, I could easily have just logged in to Twitter each time I wanted to share something, but knowing my schedule and track record for follow-through, I instead decided to write a script to send the information to Twitter automatically from some great sources on my local linux install and an API call to https://icanhazdadjoke.com.
The first think I did was look into the sources I wanted to send. I found that https://icanhazdadjoke.com has a great API for retrieving jokes. The API can be found here: https://icanhazdadjoke.com/api. Their API is very easy to use. Now that I had my jokes, it was time to look for some wisdom. For those familiar with UNIX and UNIX like operating systems (looking at you linux), you may remember the program fortune. Fortune, is a great piece of software that will pull random, quotes, jokes, and insults with a simple command line. For more information on fortune, check out this Wikipedia article https://en.wikipedia.org/wiki/Fortune_(Unix).
Great, so now I have my sources. How do I go about posting them to Twitter? This on its own could become a daunting task. Thankfully, there is a great project on GitHub for just that https://github.com/jublo/codebird-php. Codebird-php contains the necessary bits and pieces to allow a Twitter Developer app to post to Twitter. That just leaves one thing before we get to writing our code, a Twitter Developer account. Getting a developer is quite easy, go to https://developer.twitter.com/, login and setup an app. Your app will will need an API Key, API Secret Key, Access Token, and Access Token Secret.
Great, we have all of the necessary pieces, now we can begin our coding.
Since this is an automated script running on a cron schedule, I also wanted to make it look like it isn’t running on a set schedule, I wanted to present a sense of randomness. To do this, I decided to use the rand() function in PHP to choose a number between 1 and 20. I then opted to only start the process if the random number was a 1. In essence what is happening, is my script is running every minute from cron and then determine if it should run. As seen in the code below, I am only running if the randomly selected number is 1.
// Choose random number between 1 and 20
$toPost = rand(1,20);
// If and only if variable $toPost is 1 start process
// of posting (if any other number - do nothing)
if ($toPost == "1") {For the sake of argument, we will assume that the random number selected is a 1. That will allow us to move on to the next step. We now need to ready the Twitter API call. Referring to the Codebird-PHP app, you will need to include their PHP file (codebird.php - located in the src directory) and also have the cacert.pem in the same location. I copied both of these files to the directory that contains my script. Their excellent README also gives examples on how to setup up the API call and actually make the post. Below is the necessary code to setup the API information for Twitter (be sure to replace the API-KEY, API-SECRET-KEY, ACCESS-TOKEN, and ACCESS-TOKEN-SECRET with your own app values from your Twitter Developer account).
require_once ('/PATH/TO/codebird.php');
\Codebird\Codebird::setConsumerKey('API-KEY', 'API-SECRET-KEY');
$cb = \Codebird\Codebird::getInstance();
$cb->setToken('ACCESS-TOKEN', 'ACCESS-TOKEN-SECRET');Once again, I use the rand() function to determine whether I am going to post a joke or a bit of wisdom from fortune. This time I choose a number between 1 and 2. This allows the program to flip between the two data types automatically.
// Choose random number between 1 and 2 to determine if
// posting from icanhasdadjoke or read random fortune
$val = rand(1,2);Now on to getting the actual information ready to post. In the case of icanhasdadjoke, their API can be retrieved with a simple curl command. The code below setups up the curl command in PHP and pulls a random joke from the general category (https://us-central1-dadsofunny.cloudfunctions.net/DadJokes/random/type/general)
// Setup Curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Pull general joke field (other options are available
// including not choosing a type)
// Note URL is included this way to display better in this
// editor, when placing in production change $URL = to be
// on one line only.
$URL = 'https://us-central1-dadsofunny.cloudfunctions.net';
$URL .= '/DadJokes/random/type/general';
curl_setopt($ch, CURLOPT_URL, $URL);
$query = curl_exec($ch);
$data = json_decode($query, true);The resulting call will return the joke setup in JSON format. This is quite easy to handle as it is already formatted in a way to easily pull the pieces out we need to post.
// Read returned json and pull setup and punchline variables
$setup = $data[0]["setup"];
$punchline = $data[0]["punchline"];
// Format a variable separating setup and punchline with a new line
$wisdom = $setup.'
'.$punchline;Everything is formatted for the joke. We will post the results later - check out code further below.
// Use codebird.php to post reply
$reply = $cb->statuses_update('status=' . urlencode($joke));Okay, but what about a piece of wisdom from fortune? This code is quite straight forward. Assuming you have fortune installed on your machine, all you have to do is call the program within PHP. If you do not have fortune installed, refer to your OS instructions on how to install. To accomplish reading from fortune, we are going to use the PHP function shell_exec to pull in the information. **NOTE: shell_exec may not be included within your PHP install as this can be considered a security risk if not setup properly - it has the ability to execute ANY program / read any file that the PHP / web server user has access to. Assuming you have the shell_exec function installed, it is quite simple to pull the information from fortune. The command line I use is fortune -s -n 280. This tells fortune to pull short form fortunes no longer than 280 characters (the Twitter limit).
// Create value and read in short line format less than 280
// characters to account for Twitter limits
$wisdom = shell_exec('/PATH/TO/fortune -s -n 280');Now that we have either our joke or fortune output ready, let’s post it to Twitter. To be safe, we use the urlencode function to clean-up the post. This removes any special characters that might otherwise mess up the Twitter API.
// Use codebird.php to post reply
$reply = $cb->statuses_update('status=' . urlencode($wisdom));There you go, you now have all of the pieces to put the script together. The full code is:
<?php
// Choose random number between 1 and 20
$toPost = rand(1,20);
// If and only if variable $toPost is 1 start process of posting
// (if any other number - do nothing)
if ($toPost == "1") {
// Setup Twitter API (API Keys included inline below)
// Use codebird PHP Twitter API library
// (https://github.com/jublo/codebird-php)
require_once ('/path/to/codebird.php');
\Codebird\Codebird::setConsumerKey('API-KEY', 'API-SECRET-KEY');
$cb = \Codebird\Codebird::getInstance();
$cb->setToken('ACCESS-TOKEN', 'ACCESS-TOKEN-SECRET');
// Choose random number between 1 and 2 to determine if posting
// from ihasdadjokes or read random fortune
$val = rand(1,2);
// If val equals 1 read API from ihasdadjokes and post to Twitter
if ($val == "1") {
// Setup Curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Pull general joke field (other options are available
// including not choosing a type)
// Note URL is included this way to display better in this
// editor, when placing in production change $URL = to be
// on one line only.
$URL = 'https://us-central1-dadsofunny.cloudfunctions.net';
$URL .= '/DadJokes/random/type/general';
curl_setopt($ch, CURLOPT_URL, $URL);
$query = curl_exec($ch);
$data = json_decode($query, true);
curl_close($ch);
// Read returned json and set setup and
// punchline variables
$setup = $data[0]["setup"];
$punchline = $data[0]["punchline"];
// Format a variable separating setup and punchline
// with a new line
$wisdom = $setup.'
'.$punchline;
} else {
// Create value and read in short line format less than
// 280 characters to account for Twitter limits
$wisdom = shell_exec('/path/to/fortune -s -n 280');
}
// Use codebird.php to post reply
$reply = $cb->statuses_update('status=' . urlencode($wisdom));
}
?>
To automate the process, I now run the script from cron with the following command:
* * * * * /path/to/php /path/to/file >/dev/null 2>& This runs every minute of every hour. Due to our coding above with the use of rand(), we will not have a new tweet every minute. Instead, the tweets will come randomly as the $toPost has to equal 1 before a call to our sources is made or post to the Twitter API happens.
You can find the results and output of my script on Twitter at https://twitter.com/ihaswisdom (@ihaswisdom). I have also included a screenshot below of some of the results that have been tweeted thus far.
