The first twitter bot I created for a site was an ugly critter. It consisted of ~30 pre-constructed tweets that the cronjob would randomly go through. Some messages were double posted, some were too similar and it was just terrible. I didn’t track numbers but I’m wiling to bet I lost a lot of REAL followers because of it.
So this time around I wanted to mix in some more “random” message tweets with all of my auto generated ones. We’ve already talked about the search action tweets and I’ve mentioned posting categories and products. All of those drove traffic to the site, these random posts needed to come across as moderately conversational or at least human generated.
So I set about creating a set of 20 posts that were fairly generalized, not time sensitive and could be posted indefinitely. After 10 I realized I needed to have posts that were time sensitive or would at least expire at some point. Maybe even posts that I didn’t want to expire in a specific amount of time, but rather after they were posted a certain number of times.
So I constructed my table
| Field | Type | Desc |
|---|---|---|
| id | int | PRIMARY KEY |
| tweet | text | The tweet to post |
| start | timestamp | When this tweet can start |
| expire | timestamp (can be NULL) | When this tweet expires |
| last_tweet | timestamp | The last time this message was tweeted |
| times_tweeted | int | The number of times this message has been tweeted |
| max_tweets | int | The maximum number of times this message can be tweeted |
| active | enum(‘yes’,'no’) | An easy on/off toggle for the messages |
Pretty simple – there’s no functionality for recurring time sensitive posts like holiday or seasonal messages but it could easily be expanded for that.
Once I filled in my posts I began querying. While I didn’t want the searches from the earlier post to repeat the same query more often than every 2 days I knew that I would need way more than 10 variations to have these comfortably repeat every two days. That’s where my buddy spinning comes into it.
Spinning Content for Exponential Variations!
Spinning gets a bad wrap. I like to think of it as a way to communicate a single thought randomly and exponentially. Any single message can be communicated 100 different ways, and the same goes for tweets. Here’s the function and syntax I use to spin with PHP
PHP Code for Spinning Content
<?php
function spin($content)
{
// replaces {{aa|bb|cc}}
$pattern = '/\{\{([^{}]*)\}\}/si';
preg_match_all($pattern,$content,$matches);
for ($i=0; $i< count($matches[0]); $i++) {
$search = explode("|",$matches[1][$i]);
shuffle($search);
$content = str_replace($matches[0][$i],$search[0],$content);
}
return $content;
}
$message = '{{Hello everyone|Hello|Greeting|Hey|Hey there}} my name is {{Terri|Terri Ann}}, I am a {{creative professional|web developer|photography enthusiast|cheeseburgler}} and today I will be {{educating you on spinning|showing you how to spin content|boosting your random tweet count}}!';
echo "Spin 1\n";
echo spin($message) ."\n";
echo "Spin 2\n";
echo spin($message) ."\n";
echo "Spin 3\n";
echo spin($message) ."\n";
?>
The first time I loaded the script the output was:
- Hey my name is Terri, I am a creative professional and today I will be showing you how to spin content!
- Greeting my name is Terri Ann, I am a web developer and today I will be boosting your random tweet count!
- Hello my name is Terri, I am a cheeseburgler and today I will be boosting your random tweet count!
With that string and 5 variations in the first set of {{}}, 2 in the next, 4 in the next and 3 variations in the last there’s a total of 120 (5x2x4x3) unique messages that can come out of that one entry. The best part is I didn’t have to write 120 different entries and when you mix that in with 9 other spinable messages most people will never notice the repetition. If I’d just added one more segment in the last set of {{}} there would have been 160 possible variations.
If there was ever a time to over test, it’s NOW
Be careful to do extensive testing with your spinner, when it fails, it fails badly. Watch to make sure you have your opening and closing{{}} all doubled up and that you aren’t posting un-spun content.I think @shoemoney put it best in this tweet
Random Tweet Queue
Now back to picking the message! The query isn’t terribly complicate but there are a lot of AND’s to it SELECT * FROM random_tweets WHERE start <= NOW() AND (expire IS NULL OR expire >= NOW()) AND last_tweet <= DATE_SUB(NOW(), INTERVAL 2 DAY) AND active ='yes' ORDER BY RAND LIMIT 1
If you have any tweets pass them through the spinner (yup, this is why we kept the tweet field text rather than varchar, so we can store the spinable version in the database) then tweet it!
Now just update the database, increment the times_tweeted by +1, update the last_tweeted = NOW() and if this post pushed times_tweeted >= max_tweets set the row to active = 'no'
I cannot write this SQL for you cause there are too many variables, you’ll need your language of choice (likely PHP) to help you make those decisions.
This site runs on the Thesis WordPress Theme
If you're someone who doesn't understand a lot of PHP, HTML, or CSS, Thesis will give you a ton of functionality without having to alter any code. For the advanced, Thesis has incredible customization possibilities via extensive hooks and filters. And with so many design options, you can use the template over and over and never have it look like the same site.
If you're more familiar with how websites work, you can use the fantastic Thesis User's Guide and world-class support forums to make more professional customizations than you ever thought possible. The theme is not only highly customizable, but it allows me to build sites with a much more targeted focus on monetization than ever before. You can find out more about Thesis below:










{ 4 comments… read them below or add one }
nice tutorial… but can i see demo page?
Twitter: terrianns
June 21, 2011 at 10:57 am
Nope, as I mentioned in the post I was going to talk through the concept not just dump some code on the page. You’ve gotta work for it if you want an auto tweeter, I have no interest in making it TOO easy for people to build out more auto tweeters, it’s worth the time to think about the goals and architecture to build a good automatic tweeting bot.
Hi, I’m on parsing project now (rss into html content) using php. I wanna add “spinning” system to make every article uniquifier.
Could you please give us some advice?
Twitter: terrianns
June 23, 2011 at 10:33 am
Advice? Sure! Don’t scrape other people’s content via RSS and come asking how you can turn their hard work into a more unique spam site. (Cause that’s sure what it sounds like you are asking, if that’s not the case please do clarify.)
Spinning is best done from original content and using spinning as a way to create infinite variations of YOUR OWN original content. If you want a spinner to auto spin scraped content you are on your own. I won’t even go that low to get rank for my own sites and I’m sure as shit not gonna help someone else do it.