Seperate single tweets into an individual collection, combine threaded Tweets / Tweet replies into combined collection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Seperate single tweets into an individual collection, combine threaded | |
* Tweets / Tweet replies into combined collection. | |
* | |
* Application-only authentication Tweets from a designated user timeline. | |
* Twitter offers applications the ability to issue authenticated requests on | |
* behalf of the application itself (as opposed to on behalf of a specific user). | |
* Twitter’s implementation is based on the Client Credentials Grant flow of | |
* the OAuth 2 specification. Note that OAuth 1.0a is still required to issue | |
* requests on behalf of users. | |
* With Application-only authentication you don’t have the context of an | |
* authenticated user and this means that any request to API for endpoints that | |
* require user context, such as posting Tweets, will not work. However, the | |
* set of endpoints that will still be available can have a higher rate limit. | |
* developer.twitter.com/en/docs/basics/authentication/overview/application-only | |
* | |
* @author Sunil Boodram <sunil.boodram@gmail.com> | |
* @link https://www.ma.co.tt | |
*/ | |
/** | |
* Retrieve Bearer Token | |
*/ | |
$tokens = api_twitter_connect(); | |
/** | |
* Make request to Twitter | |
*/ | |
$result = api_twitter_request($tokens); | |
/** | |
* Get Tweets | |
*/ | |
$tweets = get_tweets($result); | |
/** | |
* Dump/Display Tweets | |
*/ | |
var_dump($tweets); | |
/** | |
* Application-only authentication | |
* | |
* Application-only authentication is a form of authentication where an | |
* application makes API requests on its own behalf, without the user context. | |
* This method is for developers that just need to access public information. | |
* | |
* developer.twitter.com/en/docs/basics/authentication/overview/application-only | |
* | |
*/ | |
function api_twitter_connect() | |
{ | |
/** | |
* Consumer Keys & Secret | |
*/ | |
$key = 'xxxxxxxxxxxxxxxx'; | |
$sec = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; | |
/** | |
* Encode keys according to RFC 1738 | |
*/ | |
$enc_key = urlencode($key); | |
$enc_sec = urlencode($sec); | |
/** | |
* Base64 encoded bearer token credentials | |
*/ | |
$credential = base64_encode($enc_key.':'.$enc_sec); | |
/** | |
* Create cURL session to Twitter oauth2/token URL & return cURL handle | |
*/ | |
$ch = curl_init('https://api.twitter.com/oauth2/token'); | |
/** | |
* Set cURL options & create header request | |
* | |
* The request must be a HTTP POST request. | |
* The request must include an Authorization header with the value of | |
* Basic <base64 encoded value>. | |
* The request must include a Content-Type header with the value of | |
* application/x-www-form-urlencoded;charset=UTF-8. | |
* The body of the request must be grant_type=client_credentials. | |
*/ | |
curl_setopt_array($ch, [ | |
//set curl timeout | |
CURLOPT_TIMEOUT => 20, | |
//set a custom user-agent | |
CURLOPT_USERAGENT => 'MyAwesome Twitter App 1.0', | |
//create the header request with credentials | |
CURLOPT_HTTPHEADER => [ | |
'Authorization: Basic '.$credential, | |
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8', | |
'Accept-Encoding: gzip' | |
], | |
//set body of the request | |
CURLOPT_POSTFIELDS => 'grant_type=client_credentials', | |
//return transfer as string, instead of outputting directly | |
CURLOPT_RETURNTRANSFER => true, | |
//leaving CURLOPT_ENCODING empty allows uncompressing | |
CURLOPT_ENCODING => '', | |
]); | |
/** | |
* Return false if error | |
*/ | |
if (!$request = curl_exec($ch)) { | |
return false; | |
} | |
/** | |
* Decode the JSON response | |
*/ | |
$token = json_decode($request); | |
/** | |
* free request data | |
*/ | |
unset($request); | |
/** | |
* close cURL resource | |
*/ | |
curl_close($ch); | |
/** | |
* use token to make request | |
*/ | |
return $token; | |
} | |
/** | |
* Authenticate API requests with the bearer token | |
* | |
* The bearer token may be used to issue requests to API endpoints which | |
* support application-only auth. To use the bearer token, construct a normal | |
* HTTPS request and include an Authorization header with the value of | |
* Bearer <base64 bearer token value>. Signing is not required. | |
* | |
* developer.twitter.com/en/docs/basics/authentication/overview/application-only | |
* | |
*/ | |
function api_twitter_request($token) | |
{ | |
/** | |
* Check if token_type is bearer | |
*/ | |
if ($token === false || !isset($token->token_type) | |
|| $token->token_type != 'bearer') { | |
return false; | |
} | |
/** | |
* GET statuses/user_timeline using bearer token to make request | |
* | |
* | |
* Resource Url: Twitter URL to retrieve tweets | |
* https://api.twitter.com/1.1/statuses/user_timeline.json | |
* | |
* screen_name=TTPoliceService: Screen name of user we want results from. | |
* count=25: Retrieve 25 tweets | |
* trim_user=1: Do not include user object with tweets | |
* tweet_mode=extended: Return full text tweets | |
*/ | |
$res = 'https://api.twitter.com/1.1/statuses/user_timeline.json' | |
. '?screen_name=TTPoliceService' | |
. '&count=25&trim_user=1&tweet_mode=extended'; | |
/** | |
* Create cURL session to Twitter Resource URL & return cURL handle | |
*/ | |
$ch = curl_init($res); | |
/** | |
* set appropriate options | |
*/ | |
curl_setopt_array($ch, [ | |
CURLOPT_TIMEOUT => 20, | |
CURLOPT_USERAGENT => 'MyAwesome Twitter App 1.0', | |
CURLOPT_HTTPHEADER => [ | |
'Authorization: Bearer '.$token->access_token, | |
'Accept-Encoding: gzip' | |
], | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_ENCODING => '', | |
]); | |
/** | |
* Return false if error | |
*/ | |
if (!$result = curl_exec($ch)) { | |
return false; | |
} | |
/** | |
* close cURL resource | |
*/ | |
curl_close($ch); | |
/** | |
* Decode results | |
*/ | |
$data = json_decode($result); | |
/** | |
* Write results to file | |
*/ | |
return $data; | |
} | |
/** | |
* Seperate single tweets into an individual collection. | |
* Combine threaded Tweets / Tweet replies into combined collection. | |
*/ | |
function get_tweets($data) | |
{ | |
if ($data === false) { | |
return 'Cannot view tweets'; | |
} | |
//array contaning tweet data | |
$tweets = []; | |
//replied tweet id | |
$rid = null; | |
//index increment to group tweets | |
$idx = 1; | |
//loop over tweets | |
foreach ($data as $key => $tw) { | |
//Successive tweets in thread | |
if (!is_null($tw->in_reply_to_status_id) && is_null($rid)) { | |
$tweets[$idx][$tw->id] = $tw->full_text; | |
continue; | |
} | |
//First tweet in thread | |
if (is_null($tw->in_reply_to_status_id) && is_null($rid)) { | |
$tweets[$idx][$tw->id] = $tw->full_text; | |
} | |
//Store replied tweet id | |
$rid = $tw->in_reply_to_status_id; | |
//Index increment to group tweets | |
$idx++; | |
} | |
//return tweets | |
return $tweets; | |
} | |
/** | |
* Sample Output. | |
* | |
* array (size=14) | |
* 1 => | |
* array (size=1) | |
* 983041985819938816 => string 'Southern Division...' (length=116) | |
* 2 => | |
* array (size=2) | |
* 982963241600110594 => string 'During...connectionfind.' (length=239) | |
* 982963240220135424 => string 'A Taurus pistol...' (length=262) | |
* 3 => | |
* array (size=2) | |
* 982957764673712128 => string 'During the...illegally.' (length=196) | |
* 982957763616796672 => string 'Twenty-four...07.04.18.' (length=212) | |
* 4 => | |
* array (size=3) | |
* 982952341396652032 => string 'A...being discovered.' (length=145) | |
* 982952340310364160 => string 'During exercise...' (length=195) | |
* 982952339307925504 => string 'One man ...07.04.18.' (length=203) | |
* 5 => | |
* array (size=1) | |
* 982742338459131904 => string 'Come out and support' (length=129) | |
* 6 => | |
* array (size=1) | |
* 982656873538162688 => string 'to rank of Corporal' (length=90) | |
* 7 => | |
* array (size=3) | |
* 982632889232908288 => string 'The...with the find.' (length=59) | |
* 982632887752314880 => string 'Officers...' (length=278) | |
* 982632886561099776 => string 'Two...' (length=203) | |
* 8 => | |
* array (size=2) | |
* 982626267173457920 => string 'The ...find.' (length=187) | |
* 982626265994809344 => string 'A...land.' (length=280) | |
* 9 => | |
* array (size=1) | |
* 982625319206227968 => string 'Traffic Act...' (length=113) | |
* 10 => | |
* array (size=1) | |
* 982624080284266496 => string 'upcoming amendments...' (length=113) | |
* 11 => | |
* array (size=1) | |
* 982622837038043141 => string 'Are you...' (length=113) | |
* 12 => | |
* array (size=2) | |
* 982618568767438848 => string 'During...#iRoadSafe' (length=164) | |
* 982618567760891904 => string 'Two...07.04.18.' (length=200) | |
* 13 => | |
* array (size=4) | |
* 982611558420434945 => string 'Four men wh...incident.' (length=112) | |
* 982611557141139458 => string 'A report wa...cage.' (length=216) | |
* 982611555933179904 => string 'A 61yo man ...vehicle.' (length=263) | |
* 982611554632912896 => string 'Four ...yesterday.' (length=232) | |
* 14 => | |
* array (size=1) | |
* 982604235954118658 => string 'EXAM...' (length=90) | |
* | |
*/ | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment