3 * Abraham Williams (abraham@abrah.am) http://abrah.am
5 * Basic lib to work with Twitter's OAuth beta. This is untested and should not
6 * be used in production code. Twitter's beta could change at anytime.
9 * Fire Eagle code - http://github.com/myelin/fireeagle-php-lib
10 * twitterlibphp - http://github.com/jdp/twitterlibphp
15 * These are the URLs embrr use for all API calls,
16 * DO NOT change unless you know what you're doing!
18 define('API_URL', 'https://api.twitter.com/1.1');
19 define('UPLOAD_URL', 'https://upload.twitter.com/1.1');
25 /* Contains the last HTTP status code returned */
27 /* Contains the last API call */
28 public $last_api_call;
29 /* Set up the API root URL */
30 public $host = API_URL;
31 /* Set timeout default */
33 /* Set connect timeout */
34 public $connecttimeout = 30;
36 public $ssl_verifypeer = FALSE;
38 public $source = 'embr';
52 function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; }
53 function authenticateURL() { return 'https://api.twitter.com/oauth/authenticate'; }
54 function authorizeURL() { return 'https://api.twitter.com/oauth/authorize'; }
55 function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; }
60 function lastStatusCode() { return $this->http_status; }
61 function lastAPICall() { return $this->last_api_call; }
64 * construct TwitterOAuth object
66 function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
67 $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
68 $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
69 if (!empty($oauth_token) && !empty($oauth_token_secret)) {
70 $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
71 $this->screen_name = $_SESSION['access_token']['screen_name'];
72 $this->username = $_SESSION['access_token']['screen_name'];
73 $this->user_id = $_SESSION['access_token']['user_id'];
81 * Get a request_token from Twitter
83 * @returns a key/value array containing oauth_token and oauth_token_secret
85 function getRequestToken($oauth_callback = NULL) {
86 $parameters = array();
87 if (!empty($oauth_callback)) {
88 $parameters['oauth_callback'] = $oauth_callback;
90 $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
91 $token = OAuthUtil::parse_parameters($request);
92 $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
97 * Get the authorize URL
101 function getAuthorizeURL($token) {
102 if (is_array($token)) {
103 $token = $token['oauth_token'];
105 return $this->authorizeURL() . "?oauth_token={$token}";
109 * Exchange the request token and secret for an access token and
110 * secret, to sign API calls.
112 * @returns array("oauth_token" => the access token,
113 * "oauth_token_secret" => the access secret)
115 function getAccessToken($oauth_verifier = FALSE) {
116 $parameters = array();
117 if (!empty($oauth_verifier)) {
118 $parameters['oauth_verifier'] = $oauth_verifier;
120 $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
121 $token = OAuthUtil::parse_parameters($request);
122 $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
127 * GET wrappwer for oAuthRequest.
129 function get($url, $parameters = array(), $host=NULL) {
130 $response = $this->oAuthRequest($url, 'GET', $parameters, NULL, $host);
131 if($response == false){
134 return json_decode($response);
138 * POST wreapper for oAuthRequest.
140 function post($url, $parameters = array(), $multipart = NULL, $host = NULL) {
141 $response = $this->oAuthRequest($url, 'POST', $parameters, $multipart, $host);
142 if($response === false){
145 return json_decode($response);
149 * Format and sign an OAuth / API request, then make an HTTP request
151 function oAuthRequest($url, $method, $parameters, $multipart=NULL, $host=NULL) {
152 if ($url[0] == '/') { //non-twitter.com api shall offer the entire url.
156 $url = "{$host}{$url}.json";
158 $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
159 $request->sign_request($this->sha1_method, $this->consumer, $this->token);
160 $request->set_http_header($multipart);
164 curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
165 curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
166 curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
167 curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
171 curl_setopt($ci, CURLOPT_URL, $request->to_url());
172 curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:'));
175 $postfields = $multipart ? $multipart : $request->to_postdata();
176 curl_setopt($ci, CURLOPT_URL, $request->get_normalized_http_url());
177 curl_setopt($ci, CURLOPT_HTTPHEADER, $request->http_header);
178 curl_setopt($ci, CURLOPT_POST, TRUE);
179 if (!empty($postfields)) {
180 curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
184 $response = curl_exec($ci);
185 $this->http_header = $request->http_header;
186 $this->curl_info = curl_getinfo($ci);
187 $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
188 $this->last_api_call = curl_getinfo($ci, CURLINFO_EFFECTIVE_URL);
196 /* ---------- API METHODS ---------- */
198 /* ---------- Block ---------- */
199 function mutesList($cursor=-1, $skip_status = true){
200 $url = '/mutes/users/list';
203 $args['cursor'] = $cursor;
204 $args['skip_status'] = $skip_status;
205 return $this->get($url, $args);
208 function blockingList($id, $cursor=-1, $skip_status = true){
209 $url = '/blocks/list';
212 $args['screen_name'] = $id;
214 $args['cursor'] = $cursor;
215 $args['skip_status'] = $skip_status;
216 return $this->get($url, $args);
219 function blockUser($id){
220 $url = "/blocks/create";
222 $args['screen_name'] = $id;
223 return $this->post($url, $args);
226 function unblockUser($id){
227 $url = "/blocks/destroy";
229 $args['screen_name'] = $id;
230 return $this->post($url, $args);
233 /* ---------- Messages ---------- */
234 function deleteDirectMessage($id){
235 $url = "/direct_messages/destroy";
238 return $this->post($url, $args);
241 function directMessages($since_id = false, $max_id = false, $count = false, $include_entities = true){
242 $url = '/direct_messages';
245 $args['since_id'] = $since_id;
247 $args['max_id'] = $max_id;
249 $args['count'] = $count;
250 if($include_entities)
251 $args['include_entities'] = $include_entities;
252 return $this->get($url, $args);
255 function newDirectMessage($id = false, $message = false){ //TODO: Use this to send DMs
256 $url = '/direct_messages/new';
259 $args['screen_name'] = $id;
261 $args['text'] = $message;
262 return $this->post($url, $args);
265 function sentDirectMessages($since_id = false, $max_id = false, $count = false, $include_entities = true){
266 $url = '/direct_messages/sent';
269 $args['since_id'] = $since_id;
271 $args['max_id'] = $max_id;
273 $args['count'] = $count;
274 if($include_entities)
275 $args['include_entities'] = $include_entities;
276 return $this->get($url, $args);
279 /* ---------- List ---------- */
280 function addListMember($listid, $id, $memberid){
281 $url = "/lists/members/create_all";
284 $args['slug'] = $listid;
286 $args['owner_screen_name'] = $id;
288 $args['screen_name'] = $memberid;
290 return $this->post($url, $args);
293 function beAddedLists($username = '', $cursor = false){
294 $url = "/lists/memberships";
297 $args['screen_name'] = $username;
299 $args['cursor'] = $cursor;
301 return $this->get($url, $args);
304 function createList($name, $description, $isPortect){
305 $url = "/lists/create";
308 $args['name'] = $name;
310 $args['description'] = $description;
312 $args['mode'] = 'private';
314 return $this->post($url, $args);
317 function myLists($username = false, $user_id = false, $count = false){
318 $url = "/lists/ownerships";
321 $args['screen_name'] = $username;
323 $args['screen_name'] = $this->username;
326 return $this->get($url, $args);
329 function deleteList($slug){
330 $url = "/lists/destroy";
332 $args['slug'] = $slug;
333 $args['owner_screen_name'] = $this->username;
334 return $this->post($url, $args);
337 function deleteListMember($slug, $owner, $memberid){
338 $url = "/lists/members/destroy_all";
340 $args['slug'] = $slug;
341 $args['owner_screen_name'] = $owner;
342 $args['user_id'] = $memberid;
344 return $this->post($url, $args);
347 function editList($prename, $name, $description, $isProtect){
348 $url = "/lists/update";
351 $args['slug'] = $prename;
353 $args['name'] = $name;
355 $args['description'] = $description;
357 $args['mode'] = "private";
358 return $this->post($url, $args);
361 function followedLists($username = '', $cursor = false){
362 $url = "/lists/subscriptions";
365 $args['screen_name'] = $username;
367 $args['cursor'] = $cursor;
368 return $this->get($url, $args);
371 function followList($id){
372 $url = "/lists/subscribers/create";
373 $arr = explode("/", $id);
375 $args['slug'] = $arr[1];
376 $args['owner_screen_name'] = $arr[0];
377 return $this->post($url, $args);
380 function isFollowedList($id){
381 $url = "/lists/subscribers/show";
382 $arr = explode('/', $id);
384 $args['owner_screen_name'] = $arr[0];
385 $args['slug'] = $arr[1];
386 $args['screen_name'] = $this->username;
387 return isset($this->get($url, $args)->screen_name);
390 function listFollowers($id, $cursor = false, $skip_status = true){
391 $url = "/lists/subscribers";
392 $arr = explode('/', $id);
394 $args['slug'] = $arr[1];
395 $args['owner_screen_name'] = $arr[0];
397 $args['cursor'] = $cursor;
399 $args['skip_status'] = $skip_status;
400 return $this->get($url, $args);
403 function listInfo($id){
404 $arr = explode('/', $id);
405 $url = "/lists/show";
407 $args['slug'] = $arr[1];
408 $args['owner_screen_name'] = $arr[0];
409 return $this->get($url, $args);
412 function listMembers($id, $cursor = false, $skip_status = true){
413 $url = "/lists/members";
414 $arr = explode("/", $id);
416 $args['slug'] = $arr[1];
417 $args['owner_screen_name'] = $arr[0];
419 $args['cursor'] = $cursor;
421 $args['skip_status'] = $skip_status;
422 return $this->get($url, $args);
426 function listStatus($id, $since_id = false, $max_id = false, $include_rts = true, $include_entities = true){
427 $arr = explode('/', $id);
428 $url = "/lists/statuses";
430 $args['slug'] = $arr[1];
431 $args['owner_screen_name'] = $arr[0];
433 $args['since_id'] = $since_id;
435 $args['max_id'] = $max_id;
437 $args['include_rts'] = $include_rts;
438 if($include_entities)
439 $args['include_entities'] = $include_entities;
440 return $this->get($url, $args);
443 function unfollowList($id){
444 $url = "/lists/subscribers/destroy";
445 $arr = explode("/", $id);
447 $args['slug'] = $arr[1];
448 $args['owner_screen_name'] = $arr[0];
449 return $this->post($url, $args);
452 /* ---------- Friendship ---------- */
453 function destroyUser($id){
454 $url = "/friendships/destroy";
456 $args['screen_name'] = $id;
457 return $this->post($url, $args);
460 function followers($id = false, $cursor = -1, $skip_status = true){ // GET statuses/friends is removed, try GET followers/list instead
461 $url = '/followers/list';
464 $args['screen_name'] = $id;
466 $args['cursor'] = $cursor;
467 $args['skip_status'] = $skip_status;
468 return $this->get($url, $args);
471 function followUser($id, $notifications = false){
472 $url = "/friendships/create";
474 $args['screen_name'] = $id;
476 $args['follow'] = true;
477 return $this->post($url, $args);
480 function friends($id = false, $cursor = -1, $skip_status = true){ // GET statuses/friends is removed, try GET friends/list instead
481 $url = '/friends/list';
484 $args['screen_name'] = $id;
486 $args['cursor'] = $cursor;
487 $args['skip_status'] = $skip_status;
488 return $this->get($url, $args);
491 function relationship($target_screen_name, $source_screen_name = false){
492 $url = '/friendships/show';
494 $args['target_screen_name'] = $target_screen_name;
495 $args['source_screen_name'] = $source_screen_name ? $source_screen_name : $this->username;
496 return $this->get($url, $args);
499 function showUser($screen_name = false, $user_id = false, $include_entities = true){
500 $url = '/users/show';
503 $args['screen_name'] = $screen_name;
505 $args['user_id'] = $user_id ? $user_id : $this->user_id;
506 return $this->get($url, $args);
509 function muteUser($screen_name){
510 $url = "/mutes/users/create";
512 $args['screen_name'] = $screen_name;
513 return $this->post($url, $args);
516 function unmuteUser($screen_name){
517 $url = "/mutes/users/destroy";
519 $args['screen_name'] = $screen_name;
520 return $this->post($url, $args);
523 /* ---------- Ratelimit ---------- */
524 /* this API changed a lot due to the
525 * update of twitter's limit policy,
526 * get only status limits here by
528 function ratelimit($resources = "statuses"){
529 $url = '/application/rate_limit_status';
531 $args['resources'] = $resources;
532 return $this->get($url, $args);
535 /* ---------- Retweet ---------- */
536 function retweet($id){
537 $url = "/statuses/retweet/$id";
538 return $this->post($url);
541 function retweets($id, $count = 20){
545 $url = "/statuses/retweets/$id";
547 $args['count'] = $count;
548 return $this->get($url,$args);
551 function retweets_of_me($count = false, $since_id = false, $max_id = false, $include_entities = true){
552 $url = '/statuses/retweets_of_me';
555 $args['since_id'] = $since_id;
557 $args['max_id'] = $max_id;
559 $args['count'] = $count;
560 if($include_entities)
561 $args['include_entities'] = $include_entities;
562 return $this->get($url, $args);
565 /* ---------- Search ---------- */
566 function savedSearches(){
567 $url = '/saved_searches/list';
568 return $this->get($url);
571 function deleteSavedSearch($ssid){
572 $url = "/saved_searches/destroy/{$ssid}";
573 return $this->post($url);
576 function saveSearch($query){
577 $url = "/saved_searches/create";
579 $args['query'] = $query;
580 return $this->post($url, $args);
583 function search($q = false, $since_id = false, $max_id = false, $include_entities = true){
584 $url = '/search/tweets';
592 $args['since_id'] = $since_id;
595 $args['max_id'] = $max_id;
597 if($include_entities){
598 $args['include_entities'] = $include_entities;
600 return $this->get($url, $args);
603 /* ---------- Spam ---------- */
604 function reportSpam($screen_name){
605 $url = '/users/report_spam';
607 $args['screen_name'] = $screen_name;
608 return $this->post($url, $args);
611 /* ---------- Timeline ---------- */
612 function deleteStatus($id){
613 $url = "/statuses/destroy/$id";
614 return $this->post($url);
617 function homeTimeline($since_id = false, $max_id = false, $count = false, $include_entities = true) {
618 $url = '/statuses/home_timeline';
621 $args['max_id'] = $max_id;
623 $args['since_id'] = $since_id;
625 $args['count'] = $count;
628 if($include_entities)
629 $args['include_entities'] = $include_entities;
630 return $this->get($url, $args);
633 function getFavorites($userid = false, $sinceid = false, $maxid = false, $count = false, $include_entities = true){
634 $url = '/favorites/list';
637 $args['screen_name'] = $userid;
639 $args['since_id'] = $sinceid;
641 $args['max_id'] = $maxid;
643 $args['count'] = $count;
644 if($include_entities)
645 $args['include_entities'] = $include_entities;
646 return $this->get($url, $args);
649 function makeFavorite($id){
650 $url = "/favorites/create";
654 return $this->post($url, $args);
657 function removeFavorite($id){
658 $url = "/favorites/destroy";
662 return $this->post($url, $args);
665 function replies($since_id = false, $max_id = false, $count = false, $include_entities = true){
666 $url = '/statuses/mentions_timeline';
669 $args['max_id'] = $max_id;
671 $args['since_id'] = $since_id;
673 $args['count'] = $count;
674 if($include_entities)
675 $args['include_entities'] = $include_entities;
676 return $this->get($url, $args);
679 function showStatus($id,$include_entities = true){
680 $url = "/statuses/show";
684 if($include_entities)
685 $args['include_entities'] = $include_entities;
686 return $this->get($url,$args);
689 function update($status, $replying_to = false,$include_entities = true, $media_ids = false){
691 $url = '/statuses/update';
693 $args['status'] = $status;
695 $args['in_reply_to_status_id'] = $replying_to;
696 if($include_entities)
697 $args['include_entities'] = $include_entities;
699 $args['media_ids'] = $media_ids;
700 return $this->post($url, $args);
701 }catch(Exception $ex){
702 echo $ex->getLine." : ".$ex->getMessage();
706 function userTimeline($id = false, $since_id = false, $max_id = false, $count = false, $include_rts = true, $include_entities = true){
707 $url = '/statuses/user_timeline';
710 $args['max_id'] = $max_id;
712 $args['screen_name'] = $id;
714 $args['count'] = $count;
716 $args['since_id'] = $since_id;
718 $args['include_rts'] = $include_rts;
719 if($include_entities)
720 $args['include_entities'] = $include_entities;
721 $response = $this->get($url, $args);
725 function trends_closest($lat = false, $long=false) {
726 $url = "/trends/closest";
731 $args['long'] = $long;
732 return $this->get($url, $args);
735 function trends_place($id = 1) {
736 $url = "/trends/place";
740 return $this->get($url, $args);
742 /* ---------- Misc. ---------- */
743 function veverify($skip_status = false){
744 $url = '/account/verify_credentials';
745 $args = array('skip_status' => $skip_status);
746 return $this->get($url,$args);
749 function updateProfile($fields = array(), $skip_status = true){
750 $url = '/account/update_profile';
752 foreach( $fields as $pk => $pv ){
755 $args[$pk] = (string) substr( $pv, 0, 20 );
758 $args[$pk] = (string) substr( $pv, 0, 100 );
761 $args[$pk] = (string) substr( $pv, 0, 30 );
764 $args[$pk] = (string) substr( $pv, 0, 160 );
769 $args['skip_status'] = $skip_status;
771 return $this->post($url, $args);
775 function updateProfileImage($image, $skip_status = true) {
776 $url = '/account/update_profile_image';
779 $args['image']=$image;
780 $args['skip_status']=$skip_status;
782 return $this->post($url, $args);
785 function updateProfileBackground($image, $tile = false, $skip_status = true) {
786 $url = '/account/update_profile_background_image';
789 $args['image']=$image;
792 $args['tile']=($tile === 'true');
794 $args['skip_status']=$skip_status;
795 return $this->post($url, $args);
798 function uploadMedia($image) {
799 $url = '/media/upload';
802 $mul['media'] = $image;
803 return $this->post($url,$args,$mul,UPLOAD_URL);