public
Last active

Twitter autoresponder bot

  • Download Gist
1_Twitter autoresponder bot.md
Markdown

Twitter autoresponder bot

By Daniel15 (dan.cx) This is a very simple Twitter autoresponder bot. It requires PECL OAuth extension to be installed (run "pecl install oauth", or if on Windows, grab php-oauth.dll. If using cPanel you can install it via WHM). The authentication is designed for command-line usage, it won't work too well via a web browser. You'll have to sign up for an application on Twitter's site to get the consumer key and secret.

Could be modified to be more advanced (match regular expressions to answer questions, etc.)

Questions? See my blog post - http://dan.cx/blog/2011/06/twitter-autoreply-bot-dbznappa

Modified 2013-06-13 - Twitter API 1.0 discontinued, modified to use Twitter API 1.1

TwitterAutoReply.php
PHP
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
<?php
// Twitter autoreply
// By Daniel15 <http://dan.cx/>
// Modified 2013-06-13 to support Twitter API 1.1
 
class TwitterAutoReply
{
// Constants
const SEARCH_URL = 'https://api.twitter.com/1.1/search/tweets.json?q=%s&since_id=%s';
const UPDATE_URL = 'https://api.twitter.com/1.1/statuses/update.json';
const VERIFY_URL = 'https://api.twitter.com/1.1/account/verify_credentials.json';
const REQUEST_TOKEN_URL = 'https://twitter.com/oauth/request_token';
const ACCESS_TOKEN_URL = 'https://twitter.com/oauth/access_token';
const AUTH_URL = 'http://twitter.com/oauth/authorize';
// Variables
private $_replies = array();
private $_oauth;
private $_screenName;
// Methods
public function __construct($consumer_key, $consumer_secret)
{
$this->_oauth = new OAuth($consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
$this->_oauth->disableSSLChecks();
}
public function setToken($token, $secret)
{
$this->_oauth->setToken($token, $secret);
}
public function addReply($term, $reply)
{
$this->_replies[$term] = $reply;
}
public function run()
{
echo '========= ', date('Y-m-d g:i:s A'), " - Started =========\n";
// Get the last ID we replied to
$since_id = @file_get_contents('since_id');
if ($since_id == null)
$since_id = 0;
// This will store the ID of the last tweet we get
$max_id = $since_id;
// Verify their Twitter account is valid
if (!$this->verifyAccountWorks())
{
// Get a request token and show instructions
$this->doAuth();
die();
}
// Go through each reply
foreach ($this->_replies as $term => $reply)
{
echo 'Performing search for "', $term, '"... ';
$this->_oauth->fetch(sprintf(self::SEARCH_URL, urlencode($term), $since_id));
$search = json_decode($this->_oauth->getLastResponse());
echo 'Done, ', count($search->statuses), " results.\n";
// Store the max ID
if ($search->search_metadata->max_id_str > $max_id)
$max_id = $search->search_metadata->max_id_str;
// Now let's go through the results
foreach ($search->statuses as $tweet)
{
// Ensure we don't reply to ourself!
if ($tweet->user->screen_name == $this->_screenName)
continue;
 
$this->sendReply($tweet, $reply);
sleep(1);
}
}
file_put_contents('since_id', $max_id);
echo '========= ', date('Y-m-d g:i:s A'), " - Finished =========\n";
}
private function sendReply($tweet, $reply)
{
try
{
echo '@', $tweet->user->screen_name, ' said: ', $tweet->text, "\n";
$this->_oauth->fetch(self::UPDATE_URL, array(
'status' => '@' . $tweet->user->screen_name . ' ' . $reply,
'in_reply_to_status_id' => $tweet->id_str,
), OAUTH_HTTP_METHOD_POST);
}
catch (OAuthException $ex)
{
echo 'ERROR: ' . $ex->lastResponse;
die();
}
}
private function verifyAccountWorks()
{
try
{
$this->_oauth->fetch(self::VERIFY_URL, array(), OAUTH_HTTP_METHOD_GET);
$response = json_decode($this->_oauth->getLastResponse());
$this->_screenName = $response->screen_name;
return true;
}
catch (Exception $ex)
{
return false;
}
}
private function doAuth()
{
// First get a request token, and prompt them to go to the URL
$request_token_info = $this->_oauth->getRequestToken(self::REQUEST_TOKEN_URL);
echo 'Please navigate to the following URL to get an authentication token:', "\n";
echo self::AUTH_URL, '?oauth_token=', $request_token_info['oauth_token'], "\n";
echo 'Once done (and you have a PIN number), press ENTER.';
fread(STDIN, 10);
echo 'PIN Number: ';
$pin = trim(fread(STDIN, 10));
// Now let's swap that for an access token
$this->_oauth->setToken($request_token_info['oauth_token'], $request_token_info['oauth_token_secret']);
$access_token_info = $this->_oauth->getAccessToken(self::ACCESS_TOKEN_URL, null, $pin);
echo 'Success, ', $access_token_info['screen_name'], ' has authorized the application. Please change your setToken line to something like the following:', "\n";
echo '$twitter->setToken(\'', $access_token_info['oauth_token'], '\', \'', $access_token_info['oauth_token_secret'], '\');';
die();
}
public function testTweet()
{
$this->_oauth->fetch(self::UPDATE_URL, array(
'status' => 'Test from TwitterAutoReply',
), OAUTH_HTTP_METHOD_POST);
}
}
?>
example.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13
#!/usr/bin/php
<?php
date_default_timezone_set('Australia/Melbourne');
require('TwitterAutoReply.php');
 
// Consumer key and consumer secret
$twitter = new TwitterAutoReply('******', '************************');
// Token and secret
$twitter->setToken('********-*******************', '*****************8');
$twitter->addReply('over 9000', 'WHAT?! NINE THOUSAND?!');
$twitter->addReply('over nine thousand', 'WHAT?! NINE THOUSAND?!');
$twitter->run();
?>

How to do it without Pecl OAuth? I'm php newbie... sorry... )

Find a PHP library that does OAuth (take a look at http://oauth.net/code/) and replace all $this->_oauth calls with calls to the new library. You only need to worry about __construct and sendReply, the other functions aren't used normally.

I installed ubuntu, php5, apache2
Correctcly installed pecl oauth (i saw it in my phpinfo - all work fine)
But get an error :
PHP Fatal error: Class 'OAuth' not found in /var/www/twbot/twitterautoreply.php on line 22

Maybe class have another name? Can u send your oauth classes?

Hm, very odd! Did you restart your web server after installing the PECL OAuth extension? Maybe try the example in the PHP OAuth documentation (http://au.php.net/manual/en/oauth.examples.php) and see if that works?

I need to manually set this parameters ?
// Consumer key and consumer secret
$twitter = new TwitterAutoReply('******', '************************');
// Token and secret
$twitter->setToken('********-*******************', '*****************8');

Yes you do. Create an application at https://dev.twitter.com/apps and you'll get all the parameters. Here's a screenshot of where all the values go:

This will post under the user you log in as when you create the app. To post with a different user, set the token and secret to empty values (in the setToken call), and run the script. It'll prompt you on how to authenticate.

I restarted my server, but same error about OAuth class... Dont know what to do
And same error with example

Hmm. Not too sure then. Sounds like some sort of configuration issue.
You could try a pure PHP OAuth implementation. I don't have time to implement that, unfortunately.

I modified the code is now?

All those errors are unrelated, they're PHP errors. You'll have to fix your
PHP installation :)

php5ts.dll is a core component of PHP. If you're getting php5ts.dll errors,
you may need to reinstall PHP.

Regards,
Daniel Lo Nigro
http://dan.cx/ | http://twitter.com/Daniel15

On Thu, Mar 8, 2012 at 8:12 AM, axfelix <
reply@reply.github.com

wrote:

I have a feeling this may be me/Windows issues, but I'm getting lots of
"file not found" errors when I try to run this:

php5ts.dll -- downloaded, and added extension to php.ini; still not being
found.
oci.dll -- download, put in sys32; still not being found.
sqlite3.dll -- downloaded, and added extension to php.ini; still not being
found.
aspell-15.dll -- download, put in sys32; still not being found.
libcs.dll -- can't download; apparently entails some weird old Sybase
dependency.

Any ideas?


Reply to this email directly or view it on GitHub:
https://gist.github.com/820281

Hey Daniel,

Great work! Very easy to read and by following the comments here I was able to implement an alternative to PECL OAuth since my Dreamhost account doesn't seem to have it available.

I swapped it out for tmhOAuth by downloading the source files (found here https://github.com/themattharris/tmhOAuth), including them at the top:

require_once('tmhUtilities.php');
require_once('tmhOAuth.php');

and swapping out the following in Daniels twitterautoreply.php:

in the __construct delete everything and paste the following:

$this->_oauth = new tmhOAuth(array(
'consumer_key' => '',
'consumer_secret' => '',
'user_token' => '',
'user_secret' => '',
'curl_ssl_verifypeer' => false,
));

and instead of using the fetch command (lines 79 & 89) you'll need to re-order the variables and feed it to the request command in tmhoauth. So at line 79 (of the source, will be different if you added the above code) switch this:

$this->_oauth->fetch(self::UPDATE_URL, array(
'status' => '@' . $tweet->from_user . ' ' . $reply,
'in_reply_to_status_id' => $tweet->id_str,
), OAUTH_HTTP_METHOD_POST);

with this:

$this->_oauth->request('POST',$this->_oauth->url('1/statuses/update'), array(
'status' => '@' . $tweet->from_user . ' ' . $reply,
'in_reply_to_status_id' => $tweet->id_str,
));

and at line 89 switch this:

$response = $this->_oauth->fetch(self::VERIFY_URL, array(), OAUTH_HTTP_METHOD_GET);

with this:

$response = $this->_oauth->request('GET',$this->_oauth->url('1/statuses/update'), array());

Hope this helps someone! Feel free to follow me @russ152 if you have any questions, suggestions.

Thanks again Daniel!

Hmmm, I will try to take a look at it a little later, but for now I'd verify that the URL is correct by echoing something at that location

Sent from my iPhone

On Jul 11, 2012, at 9:39 AM, CWEnSreply@reply.github.com wrote:

Hi rlamb2,

I'm getting this error:

#!/usr/bin/php
Fatal error: Call to undefined method tmhOAuth::setToken() in /home/leylaca/public_html/lmrobot/TwitterAutoReply.php on line 36

help please.


Reply to this email directly or view it on GitHub:
https://gist.github.com/820281

I've got this running as an auto reply to anyone that has mentioned a specific account but it keeps replying to same ones over and over. Anyone got an idea how i can stop this?

@benpalmer have you checked that it is successfully created the file 'since_id'? And the contents?

Anyway, the reason I was here was to thank Daniel for posting this - it just gave me a few leads to get something very similar up using Twitter-Async. I also dropped a conditional ... if (!$tweet->in_reply_to_status_id) ... into the innermost foreach loop so that it didn't auto-reply to @replies, only to brand new tweets. Nice and simple.

Pretty cool!! A year ago I forked and implemented a method to match regexp. Today I change the method 'sendReply' of my fork to match your one.

This bot still work?! Did you test lately?

@iskigow Yes, the bot is still functioning :) See http://twitter.com/DBZNappa

Hey Daniel, just an FYI that Twitter is deprecating v1 of the API very soon. Will need to update the URLs to fit.

11 days to update the API 1.1 URL, right?

Sorry about the delay @jasonclemons and @nobitargh, I updated the bot for v1.1 of the API a few days ago.

Daniel, do you know any way to enable multiple bots simultaneously instead of one? In the case here, each bot wheel separately. Is there any way when the 1000 replyes are exhausted, another bot take?

Hi, Daniel, how do you manage to to avoid your account being suspended?

Per your instructions, I did everything correctly but... I'm getting a PHP: Error parsing on line 3:
1./usr/bin/php
2.<?php
3.date_default_timezone_set('Australia/Melbourne');
4. require('TwitterAutoReply.php');

???

It's the "date_default_timezone_set('Australia/Melbourne');"

Help!

ERROR: {"errors":[{"code":86,"message":"This method requires a POST."}]}

helo sir, i wanna ask,
whether it should be i upload to host? just it,right?

and where must i changes?

Most of time i am getting this error
ERROR: {"errors":[{"code":187,"message":"Status is a duplicate."}]}
How i can ignore this..??

I get this errors :S
Notice: Use of undefined constant STDIN - assumed 'STDIN' in C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php on line 123

Warning: fread() expects parameter 1 to be resource, string given in C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php on line 123
PIN Number:
Notice: Use of undefined constant STDIN - assumed 'STDIN' in C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php on line 126

Warning: fread() expects parameter 1 to be resource, string given in C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php on line 126

Fatal error: Uncaught exception 'OAuthException' with message 'Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect)' in C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php:130 Stack trace: #0 C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php(130): OAuth->getAccessToken('https://twitter...', '', '') #1 C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php(53): TwitterAutoReply->doAuth() #2 C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\example.php(12): TwitterAutoReply->run() #3 {main} thrown in C:\Users\USER\Dropbox\Documentos\Desarrollo Web\xampp\htdocs\twitterbot\TwitterAutoReply.php on line 130

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.