How to Tweet Automatically With a PHP-OAuth Twitter Bot

|

UPDATE: I did this better in Python here

One day I tweeted “Treme & Engineering – Fight Club & Anti-Consumerism,“ and was immediately answered by a Twitter account IAmJacksBot whose user was “Tyler Durden.” After looking at this Twitter account, I realized it was run by a computer program that searched recent tweets for the words “fight club” and simply responded to them with a random quote from the movie. Needless to say, this is pretty awesome and inspired me to do the same with some of my favorite television characters.

I’ve set up a Jimmy McNulty Twitter bot. For those of you who haven’t seen The Wire, which is only the best television series ever, McNulty is an insubordinate Baltimore police detective who gets on everyone’s nerves. He’s an alcoholic, adulterer, womanizer, irresponsible father, and an all around asshole, but you gotta love how he pursues tough criminals so tenaciously.

My McNulty bot tweets an arbitrary quotation from the show every three hours. So how can you set one up?

This webpage titled “How to Make a Twitter Bot with PHP in Five Minutes” got me started. You should first create a database. I used MySQL because it’s open source and free. Then create a table to the tweets your bot will choose from:

1
2
3
4
5
CREATE TABLE tweets (
    id INT(11) NOT NULL AUTO_INCREMENT,
    tweet VARCHAR(140) DEFAULT NULL,
    PRIMARY KEY (id)
)

Note that the tweet column is limited to 140, the maximum number of characters allowed by Twitter. The next step is to create the PHP file that will connect to this database, randomly select a quote, and post it to Twitter via their API. Open a text editor and paste the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

mysql_connect("localhost", "USERNAME", "PASSWORD") or die('Could not connect to database');
mysql_select_db("DATABASE") or die('Could not select database');
$result = mysql_query ("SELECT * FROM tweets ORDER BY RAND() LIMIT 1");
while ($row = mysql_fetch_array($result)) {
    $tweet = "$row[tweet]";
    sendTweet($tweet);
}

function sendTweet($msg) {
    $username = 'TWITTER-USER-NAME';
    $password = 'TWITTER-PASS';
    $url = 'http://twitter.com/statuses/update.xml';
    $curl_handle = curl_init();

    curl_setopt($curl_handle, CURLOPT_URL, "$url");
    curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl_handle, CURLOPT_POST, 1);
    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, "status=$msg");
    curl_setopt($curl_handle, CURLOPT_USERPWD, "$username:$password");
    $buffer = curl_exec($curl_handle);
    curl_close($curl_handle);
    if (empty($buffer)) {
        echo 'fail';
    } else {
        echo 'success';
    }
}

Replace USERNAME, PASSWORD, DATABASE, TWITTER-USER-NAME, and TWITTER-PASS with their respective values. Save the text file, and make sure it has the “.php” extension. Once you’ve added rows of quotations to your table and uploaded this php file into a server with php installed, you can run this script anytime. You can even instruct the machine to post to Twitter every hour or so by setting up a cron job. At first I made the php script run every half hour, but I think Twitter caught onto my tricks because after half a day, posts weren’t appearing as frequently.

The disadvantage to the above approach is that Twitter might not allow this type of “naked” login in the future. You had to specify your Twitter username and password in the file itself. Many websites are now switching to a identity verification protocol called OAuth. This protocol is more secure because instead of revealing your login credentials, you grant access to a third party program, like the php script above, by permitting temporary access with a key. I’m not an expert so here’s a nice explanation.

After using the non-OAuth method above, I rewrote my php script to login to Twitter via OAuth with the help of this tutorial

I haven’t figured out how to make my bot search for recent tweets that mention The Wire or McNulty. So that’ll be for next time.

Update

I’ve figured out how to search for tweets that contain certain words like “Mad Men” or “McNulty.” By using this Twitter OAuth library generously provided by some dude Abraham, I can have my bot query Twitter’s search API using this line:

1
$search_result = $oauth->get('http://search.twitter.com/search.json', array('q' => $query))->results;

This returns a key-value paired list which I store in $search_result and can access like so:

1
$a = array('user' => $search_result[0]->from_user, 'id' => $search_result[0]->id, 'text' => $search_result[0]->text);

So if I want the name of the account that tweeted something, I use $a["user"].

Update 2

Despite sporadic and unexplained stretches of time when attempts to tweet are unsuccessful, my Don Draper and James McNulty Twitter bots are humming along and even garnering some followers. This has led to an unexpected yet delightful rivalry between Draper and McNulty. The insubordinate Baltimore detective currently has a commanding lead: 32 followers compared to Draper’s paltry eight. But we’ll see if the 1960s ad man doesn’t have a trick or two up his tweed jacket sleeve.

These are the files you’ll need to have a functioning bot:

  • “access_token” and “access_token_secret” files (to generate, follow this tutorial)
  • a folder titled “twitteroauth” containing files “OAuth.php” and “twitteroauth.php
  • the PHP file that actually tweets (explanation below)
  • (optional).htaccess file to prevent other people from executing your PHP script

You’ll have to fill in the URL for the server on which the MySQL database resides for “HOST,” user and password to connect to that database for “USER” and “PASSWORD,” and database name for “DATABASE.” I titled the table holding all the quotations “bot_tweets” and have a where clause in the SQL because I have one table for both bots (this makes it easy to scale up in the future). Quotations corresponding to Draper have the value ‘Draper’ in the ‘person’ column (apparently ‘character’ is a MySQL reserved word), and those corresponding to McNulty have the value ‘McNulty’ in that column. The select SQL statement retrieves one random row from this three-columned table. The three columns are ‘id’ (the primary key set to auto-increment), ‘quote,’ and ‘person.’ The while loop takes only the value in the ‘quote’ column.

This script’s body calls the function “respond” which includes CONSUMER_KEY and CONSUMER_SECRET which you receive after registering your script/app with Twitter (sign-in with your Twitter login first). Don’t forget to make this PHP file’s extension “.php” and put it in the same folder as the rest of the files.

The .htaccess file (quick tutorial here) prevents random websurfers from executing your PHP script. If someone knows the URL of your PHP script, they can execute it by simply typing it into their browser’s address bar. An .htaccess file can prevent if it includes these three words:

deny from all

You can then be fancy and redirect people to a customized error page:

ErrorDocument 403 [file path to another page]