{"id":13405137,"url":"https://github.com/jublo/codebird-php","last_synced_at":"2025-12-12T04:32:59.138Z","repository":{"id":46562359,"uuid":"1973023","full_name":"jublo/codebird-php","owner":"jublo","description":"Easy access to the Twitter REST API, Direct Messages API, Account Activity API, TON (Object Nest) API and Twitter Ads API — all from one PHP library.","archived":false,"fork":false,"pushed_at":"2021-10-13T08:21:53.000Z","size":1374,"stargazers_count":774,"open_issues_count":29,"forks_count":231,"subscribers_count":64,"default_branch":"develop","last_synced_at":"2025-07-08T18:17:11.574Z","etag":null,"topics":["codebird","php","streaming-api","twitter-api","twitter-stream"],"latest_commit_sha":null,"homepage":"https://www.jublo.net/projects/codebird/php","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jublo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-06-29T15:32:43.000Z","updated_at":"2025-07-03T15:25:21.000Z","dependencies_parsed_at":"2022-08-31T00:20:53.509Z","dependency_job_id":null,"html_url":"https://github.com/jublo/codebird-php","commit_stats":null,"previous_names":["jublonet/codebird-php"],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/jublo/codebird-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jublo%2Fcodebird-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jublo%2Fcodebird-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jublo%2Fcodebird-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jublo%2Fcodebird-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jublo","download_url":"https://codeload.github.com/jublo/codebird-php/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jublo%2Fcodebird-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278539009,"owners_count":26003499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codebird","php","streaming-api","twitter-api","twitter-stream"],"created_at":"2024-07-30T19:01:56.326Z","updated_at":"2025-10-06T00:18:42.621Z","avatar_url":"https://github.com/jublo.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"# codebird-php\n\n_Easy access to the Twitter REST API, Direct Messages API, Account Activity API, TON (Object Nest) API and Twitter Ads API — all from one PHP library._\n\nCopyright (C) 2010-2018 Jublo Limited \u003csupport@jublo.net\u003e\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3cd81a521d334648b9958327621a3070)](https://www.codacy.com/app/jublonet/codebird-php?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=jublonet/codebird-php\u0026utm_campaign=badger)\n[![Coverage Status](https://img.shields.io/coveralls/jublonet/codebird-php/develop.svg)](https://coveralls.io/github/jublonet/codebird-php?branch=develop)\n[![Travis Status](https://img.shields.io/travis/jublonet/codebird-php/develop.svg)](https://travis-ci.org/jublonet/codebird-php/branches)\n\n### Requirements\n\n- PHP 7.1.0 or higher\n- OpenSSL extension\n\n## Summary\n\nUse Codebird to connect to the Twitter **REST API, Streaming API, Collections API, TON (Object Nest) API**\nand **Twitter Ads API** from your PHP code — all using just one library.\nCodebird supports full 3-way OAuth as well as application-only auth.\n\n## Authentication\n\nTo authenticate your API requests on behalf of a certain Twitter user\n(following OAuth 1.0a), take a look at these steps:\n\n```php\nrequire_once ('codebird.php');\n\\Codebird\\Codebird::setConsumerKey('YOURKEY', 'YOURSECRET'); // static, see README\n\n$cb = \\Codebird\\Codebird::getInstance();\n```\n\nYou may either set the OAuth token and secret, if you already have them:\n\n```php\n$cb-\u003esetToken('YOURTOKEN', 'YOURTOKENSECRET');\n```\n\nOr you authenticate, like this:\n\n```php\nsession_start();\n\nif (! isset($_SESSION['oauth_token'])) {\n  // get the request token\n  $reply = $cb-\u003eoauth_requestToken([\n    'oauth_callback' =\u003e 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']\n  ]);\n\n  // store the token\n  $cb-\u003esetToken($reply-\u003eoauth_token, $reply-\u003eoauth_token_secret);\n  $_SESSION['oauth_token'] = $reply-\u003eoauth_token;\n  $_SESSION['oauth_token_secret'] = $reply-\u003eoauth_token_secret;\n  $_SESSION['oauth_verify'] = true;\n\n  // redirect to auth website\n  $auth_url = $cb-\u003eoauth_authorize();\n  header('Location: ' . $auth_url);\n  die();\n\n} elseif (isset($_GET['oauth_verifier']) \u0026\u0026 isset($_SESSION['oauth_verify'])) {\n  // verify the token\n  $cb-\u003esetToken($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);\n  unset($_SESSION['oauth_verify']);\n\n  // get the access token\n  $reply = $cb-\u003eoauth_accessToken([\n    'oauth_verifier' =\u003e $_GET['oauth_verifier']\n  ]);\n\n  // store the token (which is different from the request token!)\n  $_SESSION['oauth_token'] = $reply-\u003eoauth_token;\n  $_SESSION['oauth_token_secret'] = $reply-\u003eoauth_token_secret;\n\n  // send to same URL, without oauth GET parameters\n  header('Location: ' . basename(__FILE__));\n  die();\n}\n\n// assign access token on each page load\n$cb-\u003esetToken($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);\n```\n\n### Logging out\n\nIn case you want to log out the current user (to log in a different user without\ncreating a new Codebird object), just call the `logout()` method.\n\n```\n$cb-\u003elogout();\n```\n\nCodebird also supports calling the oauth/invalidate_token method directly:\n\n```\n$reply = $cb-\u003eoauth_invalidateToken([\n    'access_token'        =\u003e '1234',\n    'access_token_secret' =\u003e '5678'\n]);\n```\n\n### Application-only auth\n\nSome API methods also support authenticating on a per-application level.\nThis is useful for getting data that are not directly related to a specific\nTwitter user, but generic to the Twitter ecosystem (such as `search/tweets`).\n\nTo obtain an app-only bearer token, call the appropriate API:\n\n```php\n$reply = $cb-\u003eoauth2_token();\n$bearer_token = $reply-\u003eaccess_token;\n```\n\nI strongly recommend that you store the obtained bearer token in your database.\nThere is no need to re-obtain the token with each page load, as it becomes invalid\nonly when you call the `oauth2/invalidate_token` method.\n\nIf you already have your token, tell Codebird to use it:\n\n```php\n\\Codebird\\Codebird::setBearerToken('YOURBEARERTOKEN');\n```\n\nIn this case, you don't need to set the consumer key and secret.\nFor sending an API request with app-only auth, see the ‘Usage examples’ section.\n\n### A word on your callback URL\n\nTwitter is very restrictive about which URLs may be used for your callback URL.\nFor example, even the presence of the ‘www’ subdomain must match with the domain\nthat you specified in the settings of your app at https://developer.twitter.com/en/apps.\n\n## Mapping API methods to Codebird function calls\n\nAs you can see from the last example, there is a general way how Twitter’s API methods\nmap to Codebird function calls. The general rules are:\n\n1. For each slash in a Twitter API method, use an underscore in the Codebird function.\n\nExample: `statuses/update` maps to `Codebird::statuses_update()`.\n\n2. For each underscore in a Twitter API method, use camelCase in the Codebird function.\n\nExample: `statuses/home_timeline` maps to `Codebird::statuses_homeTimeline()`.\n\n3. For each parameter template in method, use UPPERCASE in the Codebird function.\n   Also don’t forget to include the parameter in your parameter list.\n\nExamples:\n\n- `statuses/show/:id` maps to `Codebird::statuses_show_ID('id=12345')`.\n- `users/profile_image/:screen_name` maps to\n  `Codebird::users_profileImage_SCREEN_NAME('screen_name=jublonet')`.\n\n## Usage examples\n\nWhen you have an access token, calling the API is simple:\n\n```php\n$cb-\u003esetToken($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']); // see above\n\n$reply = (array) $cb-\u003estatuses_homeTimeline();\nprint_r($reply);\n```\n\nTweeting is as easy as this:\n\n```php\n$reply = $cb-\u003estatuses_update('status=Whohoo, I just Tweeted!');\n```\n\n:warning: _Make sure to urlencode any parameter values that contain\nquery-reserved characters, like Tweeting the `\u0026` sign:_\n\n```php\n$reply = $cb-\u003estatuses_update('status=' . urlencode('Fish \u0026 chips'));\n// will result in this:\n$reply = $cb-\u003estatuses_update('status=Fish+%26+chips');\n```\n\nIn most cases, giving all parameters in an array is easier,\nbecause no encoding is needed:\n\n```php\n$params = [\n  'status' =\u003e 'Fish \u0026 chips'\n];\n$reply = $cb-\u003estatuses_update($params);\n```\n\n```php\n$params = [\n  'status' =\u003e 'I love London',\n  'lat'    =\u003e 51.5033,\n  'long'   =\u003e 0.1197\n];\n$reply = $cb-\u003estatuses_update($params);\n```\n\n```php\n$params = [\n  'screen_name' =\u003e 'jublonet'\n];\n$reply = $cb-\u003eusers_show($params);\n```\n\nThis is the [resulting Tweet](https://twitter.com/LarryMcTweet/status/482239971399835648)\nsent with the code above.\n\n### Requests with app-only auth\n\nTo send API requests without an access token for a user (app-only auth),\nadd a second parameter to your method call, like this:\n\n```php\n$reply = $cb-\u003esearch_tweets('q=Twitter', true);\n```\n\nBear in mind that not all API methods support application-only auth.\n\n## HTTP methods (GET, POST, DELETE etc.)\n\nNever care about which HTTP method (verb) to use when calling a Twitter API.\nCodebird is intelligent enough to find out on its own.\n\n## Response codes\n\nThe HTTP response code that the API gave is included in any return values.\nYou can find it within the return object’s `httpstatus` property.\n\n### Dealing with rate-limits\n\nBasically, Codebird leaves it up to you to handle Twitter’s rate limit.\nThe library returns the response HTTP status code, so you can detect rate limits.\n\nI suggest you to check if the `$reply-\u003ehttpstatus` property is `400`\nand check with the Twitter API to find out if you are currently being\nrate-limited.\nSee the [Rate Limiting FAQ](https://developer.twitter.com/en/docs/basics/rate-limiting)\nfor more information.\n\nUnless your return format is JSON, you will receive rate-limiting details\nin the returned data’s `$reply-\u003erate` property,\nif the Twitter API responds with rate-limiting HTTP headers.\n\n## Return formats\n\nThe default return format for API calls is a PHP object.\nFor API methods returning multiple data (like `statuses/home_timeline`),\nyou should cast the reply to array, like this:\n\n```php\n$reply = $cb-\u003estatuses_homeTimeline();\n$data = (array) $reply;\n```\n\nUpon your choice, you may also get PHP arrays directly:\n\n```php\n$cb-\u003esetReturnFormat(CODEBIRD_RETURNFORMAT_ARRAY);\n```\n\nThe Twitter API natively responds to API calls in JSON (JS Object Notation).\nTo get a JSON string, set the corresponding return format:\n\n```php\n$cb-\u003esetReturnFormat(CODEBIRD_RETURNFORMAT_JSON);\n```\n\n## Uploading images and videos\n\nTwitter will accept the following media types, all of which are supported by Codebird:\n\n- PNG\n- JPEG\n- BMP\n- WebP\n- GIF\n- Animated GIF\n- Video\n\nTweet media can be uploaded in a 2-step process:\n\n**First** you send each media to Twitter. For **images**, it works like this:\n\n```php\n// these files to upload. You can also just upload 1 image!\n$media_files = [\n  'bird1.jpg', 'bird2.jpg', 'bird3.jpg'\n];\n// will hold the uploaded IDs\n$media_ids = [];\n\nforeach ($media_files as $file) {\n  // upload all media files\n  $reply = $cb-\u003emedia_upload([\n    'media' =\u003e $file\n  ]);\n  // and collect their IDs\n  $media_ids[] = $reply-\u003emedia_id_string;\n}\n```\n\nUploading **videos** requires you to send the data in chunks. See the next section on this.\n\n**Second,** you attach the collected media ids for all images to your call\nto `statuses/update`, like this:\n\n```php\n// convert media ids to string list\n$media_ids = implode(',', $media_ids);\n\n// send Tweet with these medias\n$reply = $cb-\u003estatuses_update([\n  'status' =\u003e 'These are some of my relatives.',\n  'media_ids' =\u003e $media_ids\n]);\nprint_r($reply);\n```\n\nHere is a [sample Tweet](https://twitter.com/LarryMcTweet/status/475276535386365952)\nsent with the code above.\n\nMore [documentation for uploading media](https://developer.twitter.com/en/docs/media/upload-media/overview) is available on the Twitter Developer site.\n\n### Remote files\n\nRemote files received from `http` and `https` servers are supported, too:\n\n```php\n$reply = $cb-\u003emedia_upload(array(\n  'media' =\u003e 'http://www.bing.com/az/hprichbg/rb/BilbaoGuggenheim_EN-US11232447099_1366x768.jpg'\n));\n```\n\n:warning: _URLs containing Unicode characters should be normalised. A sample normalisation function can be found at http://stackoverflow.com/a/6059053/1816603_\n\nTo circumvent download issues when remote servers are slow to respond,\nyou may customise the remote download timeout, like this:\n\n```php\n$cb-\u003esetRemoteDownloadTimeout(10000); // milliseconds\n```\n\n### Video files\n\nUploading videos to Twitter (≤ 15MB, MP4) requires you to send them in chunks.\nYou need to perform at least 3 calls to obtain your `media_id` for the video:\n\n1. Send an `INIT` event to get a `media_id` draft.\n2. Upload your chunks with `APPEND` events, each one up to 5MB in size.\n3. Send a `FINALIZE` event to convert the draft to a ready-to-Tweet `media_id`.\n4. Post your Tweet with video attached.\n\nHere’s a sample for video uploads:\n\n```php\n$file       = 'demo-video.mp4';\n$size_bytes = filesize($file);\n$fp         = fopen($file, 'r');\n\n// INIT the upload\n\n$reply = $cb-\u003emedia_upload([\n  'command'     =\u003e 'INIT',\n  'media_type'  =\u003e 'video/mp4',\n  'total_bytes' =\u003e $size_bytes\n]);\n\n$media_id = $reply-\u003emedia_id_string;\n\n// APPEND data to the upload\n\n$segment_id = 0;\n\nwhile (! feof($fp)) {\n  $chunk = fread($fp, 1048576); // 1MB per chunk for this sample\n\n  $reply = $cb-\u003emedia_upload([\n    'command'       =\u003e 'APPEND',\n    'media_id'      =\u003e $media_id,\n    'segment_index' =\u003e $segment_id,\n    'media'         =\u003e $chunk\n  ]);\n\n  $segment_id++;\n}\n\nfclose($fp);\n\n// FINALIZE the upload\n\n$reply = $cb-\u003emedia_upload([\n  'command'       =\u003e 'FINALIZE',\n  'media_id'      =\u003e $media_id\n]);\n\nvar_dump($reply);\n\nif ($reply-\u003ehttpstatus \u003c 200 || $reply-\u003ehttpstatus \u003e 299) {\n  die();\n}\n\n// if you have a field `processing_info` in the reply,\n// use the STATUS command to check if the video has finished processing.\n\n// Now use the media_id in a Tweet\n$reply = $cb-\u003estatuses_update([\n  'status'    =\u003e 'Twitter now accepts video uploads.',\n  'media_ids' =\u003e $media_id\n]);\n```\n\n**Find more information about [accepted media formats](https://developer.twitter.com/en/docs/media/upload-media/uploading-media/media-best-practices) in the Twitter Developer docs.**\n\n:warning: When uploading a video in multiple chunks, you may run into an error `The validation of media ids failed.` even though the `media_id` is correct. This is known. Please check back in the [Twitter community forums](https://twittercommunity.com/tags/video).\n\n## Twitter Streaming API\n\nThe Streaming APIs give developers low latency access to Twitter’s global stream of\nTweet data. A proper implementation of a streaming client will be pushed messages\nindicating Tweets and other events have occurred, without any of the overhead\nassociated with polling a REST endpoint.\n\nTo consume one of the available Twitter streams, follow these **two steps:**\n\n1. Set up a callback function that gets called for every new streaming message that arrives.\n\n   Codebird also calls this function once per second, to allow you to work on any due tasks, and to give you the chance to cancel the stream even if no new messages appear.\n\n2. After creating the callback, tell Codebird about it using a [callable](http://php.net/manual/en/language.types.callable.php). Then start consuming the stream.\n\n```php\n// First, create a callback function:\n\nfunction some_callback($message)\n{\n  // gets called for every new streamed message\n  // gets called with $message = NULL once per second\n\n  if ($message !== null) {\n    print_r($message);\n    flush();\n  }\n\n  // return false to continue streaming\n  // return true to close the stream\n\n  // close streaming after 1 minute for this simple sample\n  // don't rely on globals in your code!\n  if (time() - $GLOBALS['time_start'] \u003e= 60) {\n    return true;\n  }\n\n  return false;\n}\n\n// set the streaming callback in Codebird\n$cb-\u003esetStreamingCallback('some_callback');\n\n// any callable is accepted:\n// $cb-\u003esetStreamingCallback(['MyClass', 'some_callback']);\n\n// for canceling, see callback function body\n// not considered good practice in real world!\n$GLOBALS['time_start'] = time();\n\n// Second, start consuming the stream:\n$reply = $cb-\u003estatuses_filter();\n\n// See the *Mapping API methods to Codebird function calls* section for method names.\n// $reply = $cb-\u003estatuses_filter('track=Windows');\n```\n\nYou should be able to set a timeout for the streaming API using `setTimeout`.\nIn addition, your callback will receive empty messages if no events occur,\nand you should make your function `return true;` in order to cancel the stream.\n\nFind more information on the [Streaming API](https://developer.twitter.com/en/docs/tweets/filter-realtime/overview)\nin the developer documentation website.\n\n## Twitter Collections, Direct Messages and Account Activity APIs\n\nCollections are a type of timeline that you control and can be hand curated\nand/or programmed using an API.\n\nPay close attention to the differences in how collections are presented —\noften they will be decomposed, efficient objects with information about users,\nTweets, and timelines grouped, simplified, and stripped of unnecessary repetition.\n\nNever care about the OAuth signing specialities and the JSON POST body\nfor POST and PUT calls to these special APIs. Codebird takes off the work for you\nand will always send the correct Content-Type automatically.\n\nFind out more about the [Collections API](https://developer.twitter.com/en/docs/tweets/curate-a-collection/overview/about_collections) in the Twitter API docs.\nMore information on the [Direct Messages API](https://developer.twitter.com/en/docs/direct-messages/api-features) and the [Account Activity API](https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/overview) is available there as well.\n\nHere’s a sample for adding a Tweet using the Collections API:\n\n```php\n$reply = $cb-\u003ecollections_entries_curate([\n  'id' =\u003e 'custom-672852634622144512',\n  'changes' =\u003e [\n  ['op' =\u003e 'add', 'tweet_id' =\u003e '672727928262828032']\n  ]\n]);\n\nvar_dump($reply);\n```\n\n## TON (Twitter Object Nest) API\n\nThe [TON (Twitter Object Nest) API](https://developer.twitter.com/en/docs/ads/audiences/overview/ton-upload.html) allows implementers to upload media and various assets to Twitter.\nThe TON API supports non-resumable and resumable upload methods based on the size of the file.\nFor files less than 64MB, non-resumable may be used. For files greater than or equal to 64MB,\nresumable must be used. Resumable uploads require chunk sizes of less than 64MB.\n\nFor accessing the TON API, please adapt the following code samples for uploading:\n\n### Single-chunk upload\n\n```php\n// single-chunk upload\n\n$reply = $cb-\u003eton_bucket_BUCKET([\n  'bucket' =\u003e 'ta_partner',\n  'Content-Type' =\u003e 'image/jpeg',\n  'media' =\u003e $file\n]);\n\nvar_dump($reply);\n\n// use the Location header now...\necho $reply-\u003eLocation;\n```\n\nAs you see from that sample, Codebird rewrites the special TON API headers into the reply,\nso you can easily access them. This also applies to the `X-TON-Min-Chunk-Size` and\n`X-Ton-Max-Chunk-Size` for chunked uploads:\n\n### Multi-chunk upload\n\n```php\n// multi-chunk upload\n$file       = 'demo-video.mp4';\n$size_bytes = filesize($file);\n$fp         = fopen($file, 'r');\n\n// INIT the upload\n\n$reply = $cb-\u003e__call(\n  'ton/bucket/BUCKET?resumable=true',\n  [[ // note the double square braces when using __call\n    'bucket' =\u003e 'ta_partner',\n    'Content-Type' =\u003e 'video/mp4',\n    'X-Ton-Content-Type' =\u003e 'video/mp4',\n    'X-Ton-Content-Length' =\u003e $size_bytes\n  ]]\n);\n\n$target = $reply-\u003eLocation;\n// something like: '/1.1/ton/bucket/ta_partner/SzFxGfAg_Zj.mp4?resumable=true\u0026resumeId=28401873'\n$match = [];\n\n// match the location parts\npreg_match('/ton\\/bucket\\/.+\\/(.+)\\?resumable=true\u0026resumeId=(\\d+)/', $target, $match);\nlist ($target, $file, $resumeId) = $match;\n\n// APPEND data to the upload\n\n$segment_id = 0;\n\nwhile (! feof($fp)) {\n  $chunk = fread($fp, 1048576); // 1MB per chunk for this sample\n\n  // special way to call Codebird for the upload chunks\n  $reply = $cb-\u003e__call(\n    'ton/bucket/BUCKET/FILE?resumable=true\u0026resumeId=RESUMEID',\n    [[ // note the double square braces when using __call\n      'bucket' =\u003e 'ta_partner',\n      'file' =\u003e $file, // you get real filename from INIT, see above\n      'Content-Type' =\u003e 'image/jpeg',\n      'Content-Range' =\u003e 'bytes '\n        . ($segment_id * 1048576) . '-' . strlen($chunk) . '/' . $size_bytes,\n      'resumeId' =\u003e $resumeId,\n      'media' =\u003e $chunk\n    ]]\n  );\n\n  $segment_id++;\n}\n\nfclose($fp);\n```\n\n## Twitter Ads API\n\nThe [Twitter Ads API](https://developer.twitter.com/en/docs/ads/general/overview) allows partners to\nintegrate with the Twitter advertising platform in their own advertising solutions.\nSelected partners have the ability to create custom tools to manage and execute\nTwitter Ad campaigns.\n\nWhen accessing the Ads API or Ads Sandbox API, access it by prefixing your call\nwith `ads_`. Watch out for the usual replacements for in-url parameters,\nparticularly `:account_id`.\n\n**Tip:** For accessing the Ads Sandbox API, use the `ads_sandbox_` prefix,\nlike shown further down.\n\nHere is an example for calling the Twitter Ads API:\n\n```php\n$reply = $cb-\u003eads_accounts_ACCOUNT_ID_cards_appDownload([\n  'account_id' =\u003e '123456789',\n  'name' =\u003e 'Test',\n  'app_country_code' =\u003e 'DE'\n]);\n```\n\n### Multiple-method API calls\n\nIn the Twitter Ads API, there are multiple methods that can be reached by\nHTTP `GET`, `POST`, `PUT` and/or `DELETE`. While Codebird does its best to guess\nwhich HTTP verb you’ll want to use, it’s the safest bet to give a hint yourself,\nlike this:\n\n```php\n$reply = $cb-\u003eads_sandbox_accounts_ACCOUNT_ID_cards_imageConversation_CARD_ID([\n  'httpmethod' =\u003e 'DELETE',\n  'account_id' =\u003e '123456789',\n  'card_id' =\u003e '2468013579'\n]);\n```\n\nCodebird will remove the `httpmethod` parameter from the parameters list automatically,\nand set the corresponding HTTP verb.\n\n## How Do I…?\n\n### …use multiple Codebird instances?\n\nBy default, Codebird works with just one instance. This programming paradigma is\ncalled a _singleton_.\n\nGetting the main Codebird object is done like this:\n\n```php\n$cb = \\Codebird\\Codebird::getInstance();\n```\n\nIf you need to run requests to the Twitter API for multiple users at once,\nCodebird supports this as well. Instead of getting the instance like shown above,\ncreate a new object:\n\n```php\n$cb1 = new \\Codebird\\Codebird;\n$cb2 = new \\Codebird\\Codebird;\n```\n\nPlease note that your OAuth consumer key and secret is shared within\nmultiple Codebird instances, while the OAuth request and access tokens with their\nsecrets are _not_ shared.\n\n### …access a user’s profile image?\n\nFirst retrieve the user object using\n\n`$reply = $cb-\u003eusers_show(\"screen_name=$username\");`\n\nwith `$username` being the username of the account you wish to retrieve the profile image from.\n\nThen get the value from the index `profile_image_url` or `profile_image_url_https` of the user object previously retrieved.\n\nFor example:\n\n`$reply['profile_image_url']` will then return the profile image url without https.\n\n### …get user ID, screen name and more details about the current user?\n\nWhen the user returns from the authentication screen, you need to trade\nthe obtained request token for an access token, using the OAuth verifier.\nAs discussed in the section ‘Usage example,’ you use a call to\n`oauth/access_token` to do that.\n\nThe API reply to this method call tells you details about the user that just logged in.\nThese details contain the **user ID** and the **screen name.**\n\nTake a look at the returned data as follows:\n\n```\nstdClass Object\n(\n  [oauth_token] =\u003e 14648265-rPn8EJwfB**********************\n  [oauth_token_secret] =\u003e agvf3L3**************************\n  [user_id] =\u003e 14648265\n  [screen_name] =\u003e jublonet\n  [httpstatus] =\u003e 200\n)\n```\n\nIf you need to get more details, such as the user’s latest Tweet,\nyou should fetch the complete User Entity. The simplest way to get the\nuser entity of the currently authenticated user is to use the\n`account/verify_credentials` API method. In Codebird, it works like this:\n\n```php\n$reply = $cb-\u003eaccount_verifyCredentials();\nprint_r($reply);\n```\n\nI suggest to cache the User Entity after obtaining it, as the\n`account/verify_credentials` method is rate-limited by 15 calls per 15 minutes.\n\n### …walk through cursored results?\n\nThe Twitter REST API utilizes a technique called ‘cursoring’ to paginate\nlarge result sets. Cursoring separates results into pages of no more than\n5000 results at a time, and provides a means to move backwards and\nforwards through these pages.\n\nHere is how you can walk through cursored results with Codebird.\n\n1. Get the first result set of a cursored method:\n\n```php\n$result1 = $cb-\u003efollowers_list();\n```\n\n2. To navigate forth, take the `next_cursor_str`:\n\n```php\n$nextCursor = $result1-\u003enext_cursor_str;\n```\n\n3. If `$nextCursor` is not 0, use this cursor to request the next result page:\n\n```php\n  if ($nextCursor \u003e 0) {\n    $result2 = $cb-\u003efollowers_list('cursor=' . $nextCursor);\n  }\n```\n\nTo navigate back instead of forth, use the field `$resultX-\u003eprevious_cursor_str`\ninstead of `next_cursor_str`.\n\nIt might make sense to use the cursors in a loop. Watch out, though,\nnot to send more than the allowed number of requests to `followers/list`\nper rate-limit timeframe, or else you will hit your rate-limit.\n\n### …use xAuth with Codebird?\n\nCodebird supports xAuth just like every other authentication used at Twitter.\nRemember that your application needs to be whitelisted to be able to use xAuth.\n\nHere’s an example:\n\n```php\n$reply = $cb-\u003eoauth_accessToken([\n  'x_auth_username' =\u003e 'username',\n  'x_auth_password' =\u003e '4h3_p4$$w0rd',\n  'x_auth_mode' =\u003e 'client_auth'\n]);\n```\n\nAre you getting a strange error message? If the user is enrolled in\nlogin verification, the server will return a HTTP 401 error with a custom body.\nIf you are using the `send_error_codes` parameter, you will receive the\nfollowing error message in the response body:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cerrors\u003e\n\u003cerror code=\"231\"\u003eUser must verify login\u003c/error\u003e\n\u003c/errors\u003e\n```\n\nOtherwise, the response body will contain a plaintext response:\n\n```\nUser must verify login\n```\n\nWhen this error occurs, advise the user to\n[generate a temporary password](https://twitter.com/settings/applications)\non twitter.com and use that to complete signing in to the application.\n\n### …know what cacert.pem is for?\n\nConnections to the Twitter API are done over a secured SSL connection.\nCodebird-php checks if the Twitter API server has a valid SSL certificate.\nValid certificates have a correct signature-chain.\nThe cacert.pem file contains a list of all public certificates for root\ncertificate authorities. You can find more information about this file\nat http://curl.haxx.se/docs/caextract.html.\n\n### …set the timeout for requests to the Twitter API?\n\nFor connecting to Twitter, Codebird uses the cURL library, if available.\nYou can specify both the connection timeout and the request timeout,\nin milliseconds:\n\n```php\n$cb-\u003esetConnectionTimeout(2000);\n$cb-\u003esetTimeout(5000);\n```\n\nIf you don't specify the timeout, codebird uses these values:\n\n- connection time = 3000 ms = 3 s\n- timeout = 10000 ms = 10 s\n\n### …disable cURL?\n\nCodebird automatically detects whether you have the PHP cURL extension enabled.\nIf not, the library will try to connect to Twitter via socket.\nFor this to work, the PHP setting `allow_url_fopen` must be enabled.\n\nYou may also manually disable cURL. Use the following call:\n\n```php\n$cb-\u003esetUseCurl(false);\n```\n\n### …use a proxy?\n\nCodebird allows proxy support for both cURL handles and sockets.\n\nTo activate proxy mode, use the following call:\n\n```php\n$cb-\u003esetProxy('\u003chost\u003e', '\u003cport\u003e');\n```\n\nYou may also use an authenticated proxy. Use the following call:\n\n```php\n$cb-\u003esetProxy('\u003chost\u003e', '\u003cport\u003e');\n$cb-\u003esetProxyAuthentication('\u003cusername\u003e:\u003cpassword\u003e');\n```\n\nBy default, a HTTP proxy is assumed. To use a different proxy type,\nuse the corresponding [`CURLPROXY_*` constants](http://php.net/curl_setopt), like this:\n\n```php\n$cb-\u003esetProxy('\u003chost\u003e', '\u003cport\u003e', CURLPROXY_SOCKS5);\n```\n\n### …quote a Tweet?\n\nQuoting a Tweet is different from a Retweet because you may add your own text.\nThe original Tweet will appear below your quote.\nTo quote a Tweet, add a link to the original Tweet to your quote, like in this sample:\n\n```php\n$original_tweet = [\n  'id_str' =\u003e '684483801687392256',\n  'user' =\u003e [\n    'screen_name' =\u003e 'LarryMcTweet'\n  ]\n];\n$original_tweet = (object) $original_tweet; // sample, get real Tweet from API\n\n$id = $original_tweet-\u003eid_str; // use the `id_str` field because of long numbers\n$screen_name = $original_tweet-\u003euser-\u003escreen_name;\n\n// looks like this: https://twitter.com/LarryMcTweet/status/684483801687392256\n$url = \"https://twitter.com/$screen_name/status/$id\";\n$text = 'I’d like to quote a Tweet.'; // maximum length = 140 minus 24 (link length) minus 1 space\n\n$reply = $cb-\u003estatuses_update([\n  'status' =\u003e \"$text $url\"\n]);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjublo%2Fcodebird-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjublo%2Fcodebird-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjublo%2Fcodebird-php/lists"}