Net-Twitter-Lite-0.12008/000755 000766 000024 00000000000 13021411233 015021 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/Build.PL000644 000766 000024 00000000263 13021411233 016316 0ustar00marcstaff000000 000000 # This Build.PL for Net-Twitter-Lite was generated by Dist::Zilla::Plugin::ModuleBuildTiny 0.015. use strict; use warnings; use 5.006; use Module::Build::Tiny 0.034; Build_PL(); Net-Twitter-Lite-0.12008/Changes000644 000766 000024 00000012472 13021411233 016322 0ustar00marcstaff000000 000000 Revision history for Net::Twitter::Lite 0.12008 2016-12-05 17:21:25 PST - modifed example/oauth_webapp.pl (issue 18) - added upload_media; deprecated update_with_media 0.12007 2016-11-18 - depend on LWP::Protocol::https instead of Crypt::SSLeay - make SSL the default for Net::Twitter::Lite::WithAPIv1_1 0.12006 2014-01-24 - Added WrapResult: return both the Twitter result and HTTP::Response 0.12005 2014-01-17 - Twitter now requires SSL connections 0.12004 2013-05-03 - restore list_subscriptions 0.12003 2013-04-25 - Added list_ownerships 0.12002 2013-03-11 - 30 second delay in OAuth requests fixed with Net::HTTP 6.06 0.12001 2013-03-06 - Fixed tests (Net::OAuth is optional) (closses issue #7) - Updated examples to use Twitter API v1.1 0.12000 2013-03-04 - URI encode POSTDATA to match Twitter's more stringent (non-standard) requirements - created Net::Twitter::Lite::WithAPIv1_1 for Twitter API v1.1 support 0.11002 2012-06-27 - rebuilt from Net::Twitter 3.18003 to fix replies, mentions path 0.11001 2012-05-08 - CPAN release 0.11000_01 2012-04-24 - functional parity with Net::Twitter 3.18002 - Replaced JSON::Any with JSON - new lists methods, legacy_lists_api option for back compat - update_with_media and other new API methods ported from Net::Twitter 0.10004 2011-03-28 - ported from Net::Twitter 3.16000 - fixed: methods requiring HTTP DELETE failed with OAuth - doc fix: use verifier in request_access_token call - always use SSL for token exchange 0.10003 2010-05-27 - fixed ssl test: skip_all if Crypt::SSLeay is not available 0.10002 2010-05-27 - fixed: set correct url to https when ssl is specified RT#57889 0.10001 2010-05-26 - fixed "plan twice" error in unicode test 0.10000 2010-05-21 - production release, ported from Net::Twitter 3.13003 0.09002_03 2010-05-13 - ported from Net::Twitter 3.13002_03 - handle DELETE HTTP method (for Lists API) 0.09002_02 2010-05-12 - ported from Net::Twitter 3.13002_02 - Added Lists API support 0.09001 2010-05-10 - removed Try::Tiny from unicode test to avoid an additional dependency - Fixed unicode test, aburch (Ansgar Burchardt) 0.09000 2010-05-09 - New API methods (from Net::Twitter): friendships_incoming, friendships_outgoing, geo_id, retweeted_by, retweeted_by_ids, reverse_geocode. - Added XAuth support (method xauth) - Fixed: Net::Twitter::Lite::Error - needed overload fallback => 1 - Fixed: utf8 encoding error for latin1 using Basic Authentication (ported from Net::Twitter) 0.08006 2009-12-15 - Ported from Net::Twitter: - netrc/netrc_machine changes from Net::Twitter - trends_available/trends_location API methods - documented lat/long parameters to update - added users_search/find_people API method - updated apiurl default to http://api.twitter.com/1 - Fixed: retweeted_{to,of}_me API URLs (RT#52784) 0.08005 2009-11-02 - Return user_id and screen_name from request_access token (ported from Net::Twitter) 0.08004 2009-10-22 - Fixed: cached request_token resulted in stale authentication/autorization urls - Added better runtime error message when SSL support is missing 0.08003 2009-10-13 - Added new API method: report_spam 0.08002 2009-10-12 - ported support for multipart/from-data posts, used by update_profile_image and update_profile_background_image, from Net::Twitter - Improved error message when Net::OAuth is not install or version is inadequate - Changed nonce generation to remove dependency on Digest::SHA - Doc patch: created_at, not time (thanks to Blair Christensen RT#50313) 0.08001 2009-09-10 - URI 1.35 causes utf8 encoding problems; require 1.40 (thanks to Dan Boger, @zigdon) - Removed deprecated is_authorized from examples in pod (thanks to Nigel Metheringham) 0.08000 2009-08-27 - Ported get_authentication_url from Net::Twitter - Work around perl bug requiring encoded hash keys when client uses "use utf8" 0.07000 2009-08-14 - Removed JSON::DWIW as a handler (no support for JSON::Any's utf8 option) 0.06002 2009-07-29 - Fix: spurious OAuth signature failures (ported from Net::Twitter) 0.06001 2009-07-28 - Fix: OAuth / unicode conflict 0.06000 2009-07-28 - Bug fix: OAuth signatures on POST requests (Galen Huntington) - Unicode fixes 0.05000 2009-07-09 - Added ssl and netrc arguments to new 0.04001 2009-07-07 - Added documentation for the required callback param to get_authorization_url - New nonce algorithm to eliminate potential duplicates on forked processes 0.04000 2009-06-27 - Added support for the "authenticate" parameter to API methods - Twitter API update: - Added screen_name and user_id parameters to new_direct_message - Added show_friendship method (friendships/show.json) 0.03001 2009-06-20 - Fixed Basic Auth regression error 0.03000 2009-06-20 - Added OAuth 1.0a support - Added examples using OAuth 0.02002 2009-06-11 - Reverted the 'forceauth' feature; it requires too recent LWP::UserAgent 0.02000 2009-06-07 - Added support for the saved_searches API methods 0.01001 2009-06-06 - Fixed: accept extra args as a hashref (search behaved this way in 2.12) 0.01000 2009-06-06 - non-Moose variation of Net::Twitter Net-Twitter-Lite-0.12008/dist.ini000644 000766 000024 00000004255 13021411233 016473 0ustar00marcstaff000000 000000 name = Net-Twitter-Lite main_module = lib/Net/Twitter/Lite.pm abstract = A perl API library for the Twitter API author = Marc Mims license = Perl_5 copyright_holder = Marc Mims copyright_year = 2013-2016 ; Make the git repo installable [Git::GatherDir] exclude_filename = Build.PL exclude_filename = META.json exclude_filename = LICENSE exclude_filename = README.md [CopyFilesFromBuild] copy = META.json copy = LICENSE copy = Build.PL [VersionFromModule] [ReversionOnRelease] prompt = 1 ; after ReversionOnRelease for munge_files, before Git::Commit for after_release [NextRelease] format = %-7v %{yyyy-MM-dd HH:mm:ss VVV}d%{ (TRIAL RELEASE)}T [Git::Check] allow_dirty = dist.ini allow_dirty = Changes allow_dirty = META.json allow_dirty = README.md allow_dirty = Build.PL ; for $VERSION allow_dirty = lib/Net/Twitter/Lite.pm [GithubMeta] issues = 1 [MetaResources] x_IRC = irc://irc.perl.org#net-twitter [MetaNoIndex] directory = src directory = t directory = xt directory = inc directory = share directory = eg directory = examples [PkgVersion] [PodVersion] [AutoPrereqs] [Prereqs] JSON = 2.02 URI = 1.40 LWP::UserAgent = 2.032 LWP::Protocol::https = 0 Net::HTTP = >= 0,!= 6.04,!= 6.05 parent = 0 [Prereqs / Recommends] Net::OAuth = 0.25 Net::Netrc = 0 [Prereqs / TestRequires] Test::Simple = 0.98 Test::Fatal = 0 [ModuleBuildTiny] [MetaJSON] ; x_contributors for MetaCPAN [Git::Contributors] ; standard stuff [PodSyntaxTests] [MetaYAML] [License] [ReadmeAnyFromPod] [ReadmeAnyFromPod/ReadmeTextInBuild] [ExtraTests] [ExecDir] dir = script [ShareDir] [Manifest] [ManifestSkip] [CheckChangesHasContent] [TestRelease] [Test::Compile] [PodCoverageTests] ; authordep Pod::Coverage::TrustPod [ConfirmRelease] [UploadToCPAN] [Git::Commit] commit_msg = Release %v allow_dirty = dist.ini allow_dirty = Changes allow_dirty = META.json allow_dirty = Build.PL ; for $VERSION allow_dirty = lib/Net/Twitter/Lite.pm ; .pm files copied back from Release ;allow_dirty_match = \.pm$ ; .pm files copied back from Release [Git::Tag] tag_format = %v tag_message = [Git::Push] Net-Twitter-Lite-0.12008/examples/000755 000766 000024 00000000000 13021411233 016637 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/lib/000755 000766 000024 00000000000 13021411233 015567 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/LICENSE000644 000766 000024 00000043663 13021411233 016042 0ustar00marcstaff000000 000000 This software is copyright (c) 2013-2016 by Marc Mims. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2013-2016 by Marc Mims. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2013-2016 by Marc Mims. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Net-Twitter-Lite-0.12008/MANIFEST000644 000766 000024 00000001225 13021411233 016152 0ustar00marcstaff000000 000000 # This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.008. Build.PL Changes LICENSE MANIFEST META.json META.yml README dist.ini examples/oauth_desktop.pl examples/oauth_webapp.pl lib/Net/Twitter/Lite.pm lib/Net/Twitter/Lite.pod lib/Net/Twitter/Lite/API/V1.pm lib/Net/Twitter/Lite/API/V1_1.pm lib/Net/Twitter/Lite/Error.pm lib/Net/Twitter/Lite/WithAPIv1_1.pm lib/Net/Twitter/Lite/WithAPIv1_1.pod lib/Net/Twitter/Lite/WrapResult.pm t/00-compile.t t/00_load.t t/01_basic.t t/02_regression.t t/03-v1_1.t t/04-wrapresult.t t/99-pod_spelling.t t/author-pod-coverage.t t/author-pod-syntax.t t/legacy_lists_api.t t/new-lists.t t/ssl.t t/unicode.t Net-Twitter-Lite-0.12008/META.json000644 000766 000024 00000005146 13021411233 016450 0ustar00marcstaff000000 000000 { "abstract" : "A perl API library for the Twitter API", "author" : [ "Marc Mims " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.008, CPAN::Meta::Converter version 2.150001", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Net-Twitter-Lite", "no_index" : { "directory" : [ "eg", "examples", "inc", "share", "src", "t", "xt" ] }, "prereqs" : { "configure" : { "requires" : { "Module::Build::Tiny" : "0.034" } }, "develop" : { "requires" : { "Pod::Coverage::TrustPod" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08" } }, "runtime" : { "recommends" : { "Net::Netrc" : "0", "Net::OAuth" : "0.25" }, "requires" : { "Carp" : "0", "Encode" : "0", "HTTP::Request::Common" : "0", "JSON" : "2.02", "LWP::Protocol::https" : "0", "LWP::UserAgent" : "2.032", "Net::HTTP" : ">= 0, != 6.04, != 6.05", "Net::Netrc" : "0", "URI" : "1.40", "URI::Escape" : "0", "overload" : "0", "parent" : "0", "perl" : "5.006", "strict" : "0", "warnings" : "0" } }, "test" : { "requires" : { "Data::Dumper" : "0", "File::Spec" : "0", "IO::Handle" : "0", "IPC::Open3" : "0", "Test::Fatal" : "0", "Test::More" : "0", "Test::Simple" : "0.98", "blib" : "1.01", "perl" : "5.006" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/semifor/net-twitter-lite/issues" }, "homepage" : "https://github.com/semifor/net-twitter-lite", "repository" : { "type" : "git", "url" : "https://github.com/semifor/net-twitter-lite.git", "web" : "https://github.com/semifor/net-twitter-lite" }, "x_IRC" : "irc://irc.perl.org#net-twitter" }, "version" : "0.12008", "x_contributors" : [ "Ansgar Burchardt ", "Chris ", "Marc Mims ", "zhouzhen1 " ], "x_serialization_backend" : "Cpanel::JSON::XS version 3.0213" } Net-Twitter-Lite-0.12008/META.yml000644 000766 000024 00000002677 13021411233 016306 0ustar00marcstaff000000 000000 --- abstract: 'A perl API library for the Twitter API' author: - 'Marc Mims ' build_requires: Data::Dumper: '0' File::Spec: '0' IO::Handle: '0' IPC::Open3: '0' Test::Fatal: '0' Test::More: '0' Test::Simple: '0.98' blib: '1.01' perl: '5.006' configure_requires: Module::Build::Tiny: '0.034' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.008, CPAN::Meta::Converter version 2.150001' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-Twitter-Lite no_index: directory: - eg - examples - inc - share - src - t - xt recommends: Net::Netrc: '0' Net::OAuth: '0.25' requires: Carp: '0' Encode: '0' HTTP::Request::Common: '0' JSON: '2.02' LWP::Protocol::https: '0' LWP::UserAgent: '2.032' Net::HTTP: '>= 0, != 6.04, != 6.05' Net::Netrc: '0' URI: '1.40' URI::Escape: '0' overload: '0' parent: '0' perl: '5.006' strict: '0' warnings: '0' resources: IRC: irc://irc.perl.org#net-twitter bugtracker: https://github.com/semifor/net-twitter-lite/issues homepage: https://github.com/semifor/net-twitter-lite repository: https://github.com/semifor/net-twitter-lite.git version: '0.12008' x_contributors: - 'Ansgar Burchardt ' - 'Chris ' - 'Marc Mims ' - 'zhouzhen1 ' x_serialization_backend: 'YAML::Tiny version 1.69' Net-Twitter-Lite-0.12008/README000644 000766 000024 00000202400 13021411233 015677 0ustar00marcstaff000000 000000 NAME Net::Twitter::Lite - A perl interface to the Twitter API VERSION version 0.12008 STOP! You probably want Net::Twitter::Lite::WithAPIv1_1 which has support for Twitter API v1.1. If you're using a service with an API compatible with Twitter's deprecated API v1, then you're in the right place. SYNOPSIS use Net::Twitter::Lite; my $nt = Net::Twitter::Lite->new( username => $user, password => $password legacy_lists_api => 0, ); my $result = eval { $nt->update('Hello, world!') }; eval { my $statuses = $nt->friends_timeline({ since_id => $high_water, count => 100 }); for my $status ( @$statuses ) { print "$status->{created_at} <$status->{user}{screen_name}> $status->{text}\n"; } }; warn "$@\n" if $@; DESCRIPTION This module provides a perl interface to the Twitter API v1. It uses the same API definitions as Net::Twitter, but without the extra bells and whistles and without the additional dependencies. Same great taste, less filling. This module is related to, but is not part of the Net::Twitter distribution. It's API methods and API method documentation are generated from Net::Twitter's internals. It exists for those who cannot, or prefer not to install Moose and its dependencies. You should consider upgrading to Net::Twitter for additional functionality, finer grained control over features, backwards compatibility with older versions of Net::Twitter, and additional error handling options. CLIENT CODE CHANGES REQUIRED Legacy Lists API Twitter re-implemented the Lists API using new endpoints and semantics. For backwards compatibility, this version of Net::Twitter::Lite defaults to the deprecated, legacy endpoints and semantics. It issues a warning if the legacy_lists_api option to new is not provided. To enable the new Lists endpoints and semantics, pass (legacy_lists_api = 0)> to new. To disable the warning, and keep the backwards compatible endpoints and semantics, pass (legacy_lists_api = 1)> to new. The legacy_lists_api option to new sets the default for all lists API method calls. You can override the default an each API call by passing a -legacy_lists_api option set to 1 or 0. Support for legacy_lists_api option will be removed in a future version and the option to new will be silently ignored. netrc option The default apiurl changed in version 0.08006. The change should be transparent to client code, unless you're using the netrc option. If so, you'll need to either update the .netrc entry and change the machine value from twitter.com to api.twitter.com, or set either the netrc or netrc_machine options to twitter.com. $nt = Net::Twitter::Lite->new(netrc_machine => 'twitter.com', netrc => 1); # -or- $nt = Net::Twitter::Lite->new(netrc => 'twitter.com'); OAuth requires callback parameter Beginning with version 0.03, it is necessary for web applications using OAuth authentication to pass the callback parameter to get_authorization_url. In the absence of a callback parameter, when the user authorizes the application a PIN number is displayed rather than redirecting the user back to your site. MIGRATING FROM NET::TWITTER 2.x If you are migrating from Net::Twitter 2.12 (or an earlier version), you may need to make some minor changes to your application code in order to user Net::Twitter::Lite successfully. The primary difference is in error handling. Net::Twitter::Lite throws exceptions on error. It does not support the get_error, http_code, and http_message methods used in Net::Twitter 2.12 and prior versions. Instead of # DON'T! my $friends = $nt->friends(); if ( $friends ) { # process $friends } wrap the API call in an eval block: # DO! my $friends = eval { $nt->friends() }; if ( $friends ) { # process $friends } Here's a much more complex example taken from application code using Net::Twitter 2.12: # DON'T! my $friends = $nt->friends(); if ( $friends ) { # process $friends } else { my $error = $nt->get_error; if ( ref $error ) { if ( ref($error) eq 'HASH' && exists $error->{error} ) { $error = $error->{error}; } else { $error = 'Unexpected error type ' . ref($error); } } else { $error = $nt->http_code() . ": " . $nt->http_message; } warn "$error\n"; } The Net::Twitter::Lite equivalent is: # DO! eval { my $friends = $nt->friends(); # process $friends }; warn "$@\n" if $@; return; In Net::Twitter::Lite, an error can always be treated as a string. See Net::Twitter::Lite::Error. The HTTP Status Code and HTTP Message are both available. Rather than accessing them via the Net::Twitter::Lite instance, you access them via the Net::Twitter::Lite::Error instance thrown as an error. For example: # DO! eval { my $friends = $nt->friends(); # process $friends }; if ( my $error = $@ ) { if ( blessed $error && $error->isa("Net::Twitter::Lite::Error) && $error->code() == 502 ) { $error = "Fail Whale!"; } warn "$error\n"; } Unsupported Net::Twitter 2.12 options to new Net::Twitter::Lite does not support the following Net::Twitter 2.12 options to new. It silently ignores them: no_fallback If Net::Twitter::Lite is unable to create an instance of the class specified in the useragent_class option to new, it dies, rather than falling back to an LWP::UserAgent object. You really don't want a failure to create the useragent_class you specified to go unnoticed. twittervision Net::Twitter::Lite does not support the TwitterVision API. Use Net::Twitter, instead, if you need it. skip_arg_validation Net::Twitter::Lite does not API parameter validation. This is a feature. If Twitter adds a new option to an API method, you can use it immediately by passing it in the HASH ref to the API call. Net::Twitter::Lite relies on Twitter to validate its own parameters. An appropriate exception will be thrown if Twitter reports a parameter error. die_on_validation See "skip_arg_validation". If Twitter returns an bad parameter error, an appropriate exception will be thrown. arrayref_on_error This option allowed the following idiom in Net::Twitter 2.12: # DON'T! for my $friend ( @{ $nt->friends() } ) { # process $friend } The equivalent Net::Twitter::Lite code is: # DO! eval { for my $friend ( @{ $nt->friends() } ) { # process $friend } }; Unsupported Net::Twitter 2.12 methods clone The clone method was added to Net::Twitter 2.x to allow safe error handling in an environment where concurrent requests are handled, for example, when using LWP::UserAgent::POE as the useragent_class. Since Net::Twitter::Lite throws exceptions instead of stashing them in the Net::Twitter::Lite instance, it is safe in a current request environment, obviating the need for clone. get_error http_code http_message These methods are replaced by Net::Twitter::Lite::Error. An instance of that class is thrown errors are encountered. METHODS AND ARGUMENTS new This constructs a Net::Twitter::Lite object. It takes several named parameters, all of them optional: username This is the screen name or email used to authenticate with Twitter. Use this option for Basic Authentication, only. password This is the password used to authenticate with Twitter. Use this option for Basic Authentication, only. consumer_key A string containing the OAuth consumer key provided by Twitter when an application is registered. Use this option for OAuth authentication, only. consumer_secret A string containing the OAuth consumer secret. Use this option for OAuth authentication, only. the OAuth trait is included. oauth_urls A HASH ref of URLs to be used with OAuth authentication. Defaults to: { request_token_url => "http://twitter.com/oauth/request_token", authorization_url => "http://twitter.com/oauth/authorize", access_token_url => "http://twitter.com/oauth/access_token", xauth_url => "https://twitter.com/oauth/access_token", } clientname The value for the X-Twitter-Client-Name HTTP header. It defaults to "Perl Net::Twitter::Lite". clientver The value for the X-Twitter-Client-Version HTTP header. It defaults to current version of the Net::Twitter::Lite module. clienturl The value for the X-Twitter-Client-URL HTTP header. It defaults to the search.cpan.org page for the Net::Twitter::Lite distribution. useragent_class The LWP::UserAgent compatible class used internally by Net::Twitter::Lite. It defaults to "LWP::UserAgent". For POE based applications, consider using "LWP::UserAgent::POE". useragent_args An HASH ref of arguments to pass to constructor of the class specified with useragent_class, above. It defaults to {} (an empty HASH ref). useragent The value for User-Agent HTTP header. It defaults to "Net::Twitter::Lite/0.11002 (Perl)". source The value used in the source parameter of API method calls. It is currently only used in the update method in the REST API. It defaults to "twitterpm". This results in the text "from Net::Twitter" rather than "from web" for status messages posted from Net::Twitter::Lite when displayed via the Twitter web interface. The value for this parameter is provided by Twitter when a Twitter application is registered. See http://apiwiki.twitter.com/FAQ#HowdoIget%E2%80%9CfromMyApp%E2%80%9DappendedtoupdatessentfrommyAPIapplication. apiurl The URL for the Twitter API. This defaults to "http://twitter.com". identica If set to 1 (or any value that evaluates to true), apiurl defaults to "http://identi.ca/api". ssl If set to 1, an SSL connection will be used for all API calls. Defaults to 0. netrc (Optional) Sets the machine key to look up in .netrc to obtain credentials. If set to 1, Net::Twitter::Lite will use the value of the netrc_machine option (below). # in .netrc machine api.twitter.com login YOUR_TWITTER_USER_NAME password YOUR_TWITTER_PASSWORD machine semifor.twitter.com login semifor password SUPERSECRET # in your perl program $nt = Net::Twitter::Lite->new(netrc => 1); $nt = Net::Twitter::Lite->new(netrc => 'semifor.twitter.com'); netrc_machine (Optional) Sets the machine entry to look up in .netrc when > is used. Defaults to api.twitter.com. legacy_lists_api If set to 1, this option enables backwards compatibility by using the now deprecated endpoints and semantics for lists API methods. If set to 0, the new endpoints and semantics will be used. Only the new lists API methods are documented here. If you do not provide this option to new a warning is issued. Support for this option and the legacy lists API methods will be removed in a future version. wrap_result (Optional) If set to 1, this option will return an Net::Twitter::Lite::WrapResult object, which provides both the Twitter API result and the HTTP::Response object for the API call. See Net::Twitter::Lite::WrapResult for details. BASIC AUTHENTICATION METHODS credentials($username, $password) Set the credentials for Basic Authentication. This is helpful for managing multiple accounts. OAUTH METHODS authorized Whether the client has the necessary credentials to be authorized. Note that the credentials may be wrong and so the request may fail. request_access_token Returns list including the access token, access token secret, user_id, and screen_name for this user. Takes a HASH of arguments. The verifier argument is required. See "OAUTH EXAMPLES". The user must have authorized this app at the url given by get_authorization_url first. For desktop applications, the Twitter authorization page will present the user with a PIN number. Prompt the user for the PIN number, and pass it as the verifier argument to request_access_token. Returns the access token and access token secret but also sets them internally so that after calling this method, you can immediately call API methods requiring authentication. get_authorization_url(callback => $callback_url) Get the URL used to authorize the user. Returns a URI object. For web applications, pass your applications callback URL as the callback parameter. No arguments are required for desktop applications (callback defaults to oob, out-of-band). get_authentication_url(callback => $callback_url) Get the URL used to authenticate the user with "Sign in with Twitter" authentication flow. Returns a URI object. For web applications, pass your applications callback URL as the callback parameter. No arguments are required for desktop applications (callback defaults to oob, out-of-band). xauth($username, $password) Exchanges a username and password for OAuth tokens. Your application must be approved for XAuth access by Twitter for this method to work. Twitter does not grant XAuth access for web applications except for a brief period of time to allow them to switch form Basic authentication to OAuth authentication. access_token Get or set the access token. access_token_secret Get or set the access token secret. request_token Get or set the request token. request_token_secret Get or set the request token secret. access_token_url Get or set the access_token URL. authentication_url Get or set the authentication URL. authorization_url Get or set the authorization URL. request_token_url Get or set the request_token URL. xauth_url Get or set the XAuth access token request URL. API METHODS AND ARGUMENTS Most Twitter API methods take parameters. All Net::Twitter::Lite API methods will accept a HASH ref of named parameters as specified in the Twitter API documentation. For convenience, many Net::Twitter::Lite methods accept simple positional arguments as documented, below. The positional parameter passing style is optional; you can always use the named parameters in a hash ref if you prefer. For example, the REST API method update has one required parameter, status. You can call update with a HASH ref argument: $nt->update({ status => 'Hello world!' }); Or, you can use the convenient form: $nt->update('Hello world!'); The update method also has an optional parameter, in_reply_to_status_id. To use it, you must use the HASH ref form: $nt->update({ status => 'Hello world!', in_reply_to_status_id => $reply_to }); Convenience form is provided for the required parameters of all API methods. So, these two calls are equivalent: $nt->friendship_exists({ user_a => $fred, user_b => $barney }); $nt->friendship_exists($fred, $barney); Many API methods have aliases. You can use the API method name, or any of its aliases, as you prefer. For example, these calls are all equivalent: $nt->friendship_exists($fred, $barney); $nt->relationship_exists($fred, $barney); $nt->follows($fred, $barney); Aliases support both the HASH ref and convenient forms: $nt->follows({ user_a => $fred, user_b => $barney }); Methods that support the page parameter expect page numbers > 0. Twitter silently ignores invalid page values. So { page => 0 } produces the same result as { page => 1 }. In addition to the arguments specified for each API method described below, an additional authenticate parameter can be passed. To request an Authorization header, pass authenticated => 1; to suppress an authentication header, pass authentication => 0. Even if requested, an Authorization header will not be added if there are no user credentials (username and password for Basic Authentication; access tokens for OAuth). This is probably only useful for the "rate_limit_status" method in the REST API, since it returns different values for an authenticated and a non-authenticated call. REST API Methods Several of these methods accept a user ID as the id parameter. The user ID can be either a screen name, or the users numeric ID. To disambiguate, use the screen_name or user_id parameters, instead. For example, These calls are equivalent: $nt->create_friend('perl_api'); # screen name $nt->create_friend(1564061); # numeric ID $nt->create_friend({ id => 'perl_api' }); $nt->create_friend({ screen_name => 'perl_api' }); $nt->create_friend({ user_id => 1564061 }); However user_id 911 and screen_name 911 are separate Twitter accounts. These calls are NOT equivalent: $nt->create_friend(911); # interpreted as screen name $nt->create_friend({ user_id => 911 }); # screen name: richellis Whenever the id parameter is required and user_id and screen_name are also parameters, using any one of them satisfies the requirement. account_settings Parameters: none Required: none Returns the current trend, geo and sleep time information for the authenticating user. Returns: HashRef account_totals Parameters: none Required: none Returns the current count of friends, followers, updates (statuses) and favorites of the authenticating user. Returns: HashRef add_list_member Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id Required: none Add a member to a list. The authenticated user must own the list to be able to add members to it. Note that lists can't have more than 500 members. Returns: User add_place add_place(name, contained_within, token, lat, long) Parameters: name, contained_within, token, lat, long, attribute:street_address, callback Required: name, contained_within, token, lat, long Creates a new place object at the given latitude and longitude. Before creating a place you need to query similar_places with the latitude, longitude and name of the place you wish to create. The query will return an array of places which are similar to the one you wish to create, and a token. If the place you wish to create isn't in the returned array you can use the token with this method to create a new one. Returns: Place all_subscriptions alias: all_lists alias: list_subscriptions Parameters: user_id, screen_name, count, cursor Required: none Returns all lists the authenticating or specified user subscribes to, including their own. The user is specified using the user_id or screen_name parameters. If no user is given, the authenticating user is used. Returns: ArrayRef[List] block_exists block_exists(id) Parameters: id, user_id, screen_name, include_entities Required: id Returns if the authenticating user is blocking a target user. Will return the blocked user's object if a block exists, and error with HTTP 404 response code otherwise. Returns: BasicUser blocking Parameters: page, include_entities Required: none Returns an array of user objects that the authenticating user is blocking. Returns: ArrayRef[BasicUser] blocking_ids Parameters: none Required: none Returns an array of numeric user ids the authenticating user is blocking. Returns: ArrayRef[Int] contributees Parameters: user_id, screen_name, include_entities, skip_satus Required: none Returns an array of users that the specified user can contribute to. Returns: ArrayRef[User] contributors Parameters: user_id, screen_name, include_entities, skip_satus Required: none Returns an array of users who can contribute to the specified account. Returns: ArrayRef[User] create_block create_block(id) Parameters: id, user_id, screen_name, include_entities Required: id Blocks the user specified in the ID parameter as the authenticating user. Returns the blocked user when successful. You can find out more about blocking in the Twitter Support Knowledge Base. Returns: BasicUser create_favorite create_favorite(id) Parameters: id, include_entities Required: id Favorites the status specified in the ID parameter as the authenticating user. Returns the favorite status when successful. Returns: Status create_friend create_friend(id) alias: follow_new Parameters: id, user_id, screen_name, follow, include_entities Required: id Befriends the user specified in the ID parameter as the authenticating user. Returns the befriended user when successful. Returns a string describing the failure condition when unsuccessful. Returns: BasicUser create_list Parameters: list_id, slug, name, mode, description, owner_screen_name, owner_id Required: none Creates a new list for the authenticated user. Note that you can't create more than 20 lists per account. Returns: List create_saved_search create_saved_search(query) Parameters: query Required: query Creates a saved search for the authenticated user. Returns: SavedSearch delete_list Parameters: owner_screen_name, owner_id, list_id, slug Required: none Deletes the specified list. The authenticated user must own the list to be able to destroy it. Returns: List delete_list_member alias: remove_list_member Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id Required: none Removes the specified member from the list. The authenticated user must be the list's owner to remove members from the list. Returns: User destroy_block destroy_block(id) Parameters: id, user_id, screen_name Required: id Un-blocks the user specified in the ID parameter as the authenticating user. Returns the un-blocked user when successful. Returns: BasicUser destroy_direct_message destroy_direct_message(id) Parameters: id, include_entities Required: id Destroys the direct message specified in the required ID parameter. The authenticating user must be the recipient of the specified direct message. Returns: DirectMessage destroy_favorite destroy_favorite(id) Parameters: id, include_entities Required: id Un-favorites the status specified in the ID parameter as the authenticating user. Returns the un-favorited status. Returns: Status destroy_friend destroy_friend(id) alias: unfollow Parameters: id, user_id, screen_name, include_entities Required: id Discontinues friendship with the user specified in the ID parameter as the authenticating user. Returns the un-friended user when successful. Returns a string describing the failure condition when unsuccessful. Returns: BasicUser destroy_saved_search destroy_saved_search(id) Parameters: id Required: id Destroys a saved search. The search, specified by id, must be owned by the authenticating user. Returns: SavedSearch destroy_status destroy_status(id) Parameters: id, trim_user, include_entities Required: id Destroys the status specified by the required ID parameter. The authenticating user must be the author of the specified status. Returns: Status direct_messages direct_messages(include_entities) Parameters: since_id, max_id, count, page, include_entities Required: include_entities Returns a list of the 20 most recent direct messages sent to the authenticating user including detailed information about the sending and recipient users. Returns: ArrayRef[DirectMessage] disable_notifications disable_notifications(id) Parameters: id, screen_name, include_entities Required: id Disables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful. Returns: BasicUser enable_notifications enable_notifications(id) Parameters: id, screen_name, include_entities Required: id Enables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful. Returns: BasicUser end_session Parameters: none Required: none Ends the session of the authenticating user, returning a null cookie. Use this method to sign users out of client-facing applications like widgets. Returns: Error favorites Parameters: id, page, include_entities Required: none Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter. Returns: ArrayRef[Status] followers_ids followers_ids(id) Parameters: id, user_id, screen_name, cursor Required: id Returns a reference to an array of numeric IDs for every user following the specified user. The order of the IDs may change from call to call. To obtain the screen names, pass the arrayref to "lookup_users". Use the optional cursor parameter to retrieve IDs in pages of 5000. When the cursor parameter is used, the return value is a reference to a hash with keys previous_cursor, next_cursor, and ids. The value of ids is a reference to an array of IDS of the user's followers. Set the optional cursor parameter to -1 to get the first page of IDs. Set it to the prior return's value of previous_cursor or next_cursor to page forward or backwards. When there are no prior pages, the value of previous_cursor will be 0. When there are no subsequent pages, the value of next_cursor will be 0. Returns: HashRef|ArrayRef[Int] friends_ids friends_ids(id) alias: following_ids Parameters: id, user_id, screen_name, cursor Required: id Returns a reference to an array of numeric IDs for every user followed by the specified user. The order of the IDs is reverse chronological. Use the optional cursor parameter to retrieve IDs in pages of 5000. When the cursor parameter is used, the return value is a reference to a hash with keys previous_cursor, next_cursor, and ids. The value of ids is a reference to an array of IDS of the user's friends. Set the optional cursor parameter to -1 to get the first page of IDs. Set it to the prior return's value of previous_cursor or next_cursor to page forward or backwards. When there are no prior pages, the value of previous_cursor will be 0. When there are no subsequent pages, the value of next_cursor will be 0. Returns: HashRef|ArrayRef[Int] friendship_exists friendship_exists(user_a, user_b) alias: relationship_exists alias: follows Parameters: user_id_a, user_id_b, screen_name_a, screen_name_b, user_a, user_b Required: user_a, user_b Tests for the existence of friendship between two users. Will return true if user_a follows user_b, otherwise will return false. Use of user_a and user_b is deprecated. It has been preserved for backwards compatibility, and is used for the two-argument positional form: $nt->friendship_exists($user_a, $user_b); Instead, you should use one of the named argument forms: $nt->friendship_exists({ user_id_a => $id1, user_id_b => $id2 }); $nt->friendship_exists({ screen_name_a => $name1, screen_name_b => $name2 }); Consider using show_friendship instead. Returns: Bool friendships_incoming friendships_incoming(cursor) Parameters: cursor Required: cursor Returns an HASH ref with an array of numeric IDs in the ids element for every user who has a pending request to follow the authenticating user. Returns: HashRef friendships_outgoing friendships_outgoing(cursor) Parameters: cursor Required: cursor Returns an HASH ref with an array of numeric IDs in the ids element for every protected user for whom the authenticating user has a pending follow request. Returns: HashRef geo_id geo_id(id) Parameters: id Required: id Returns details of a place returned from the reverse_geocode method. Returns: HashRef geo_search Parameters: lat, long, query, ip, granularity, accuracy, max_results, contained_within, attribute:street_address, callback Required: none Search for places that can be attached to a statuses/update. Given a latitude and a longitude pair, an IP address, or a name, this request will return a list of all the valid places that can be used as the place_id when updating a status. Conceptually, a query can be made from the user's location, retrieve a list of places, have the user validate the location he or she is at, and then send the ID of this location with a call to statuses/update. This is the recommended method to use find places that can be attached to statuses/update. Unlike geo/reverse_geocode which provides raw data access, this endpoint can potentially re-order places with regards to the user who is authenticated. This approach is also preferred for interactive place matching with the user. Returns: HashRef get_configuration Parameters: none Required: none Returns the current configuration used by Twitter including twitter.com slugs which are not usernames, maximum photo resolutions, and t.co URL lengths. It is recommended applications request this endpoint when they are loaded, but no more than once a day. Returns: HashRef get_languages Parameters: none Required: none Returns the list of languages supported by Twitter along with their ISO 639-1 code. The ISO 639-1 code is the two letter value to use if you include lang with any of your requests. Returns: ArrayRef[Lanugage] get_list Parameters: list_id, slug, owner_screen_name, owner_id Required: none Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. Returns: List get_lists alias: list_lists Parameters: user_id, screen_name, cursor Required: none Returns the lists of the specified (or authenticated) user. Private lists will be included if the authenticated user is the same as the user whose lists are being returned. Returns: Hashref get_privacy_policy Parameters: none Required: none Returns Twitter's privacy policy. Returns: HashRef get_tos Parameters: none Required: none Returns the Twitter Terms of Service. These are not the same as the Developer Rules of the Road. Returns: HashRef home_timeline Parameters: since_id, max_id, count, page, skip_user, exclude_replies, contributor_details, include_rts, include_entities, trim_user, include_my_retweet Required: none Returns the 20 most recent statuses, including retweets, posted by the authenticating user and that user's friends. This is the equivalent of /timeline/home on the Web. Returns: ArrayRef[Status] is_list_member Parameters: owner_screen_name, owner_id, list_id, slug, user_id, screen_name, include_entities, skip_status Required: none Check if the specified user is a member of the specified list. Returns the user or undef. Returns: Maybe[User] is_list_subscriber alias: is_subscribed_list Parameters: owner_screen_name, owner_id, list_id, slug, user_id, screen_name, include_entities, skip_status Required: none Check if the specified user is a subscriber of the specified list. Returns the user or undef. Returns: Maybe[User] list_members Parameters: list_id, slug, owner_screen_name, owner_id, cursor, include_entities, skip_status Required: none Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. Returns: Hashref list_memberships Parameters: user_id, screen_name, cursor, filter_to_owned_lists Required: none Returns the lists the specified user has been added to. If user_id or screen_name are not provided the memberships for the authenticating user are returned. Returns: Hashref list_statuses Parameters: list_id, slug, owner_screen_name, owner_id, since_id, max_id, per_page, page, include_entities, include_rts Required: none Returns tweet timeline for members of the specified list. Historically, retweets were not available in list timeline responses but you can now use the include_rts=true parameter to additionally receive retweet objects. Returns: ArrayRef[Status] list_subscribers Parameters: list_id, slug, owner_screen_name, owner_id, cursor, include_entities, skip_status Required: none Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. Returns: Hashref lookup_friendships Parameters: user_id, screen_name Required: none Returns the relationship of the authenticating user to the comma separated list or ARRAY ref of up to 100 screen_names or user_ids provided. Values for connections can be: following, following_requested, followed_by, none. Requires authentication. Returns: ArrayRef lookup_users Parameters: user_id, screen_name, include_entities Required: none Return up to 100 users worth of extended information, specified by either ID, screen name, or combination of the two. The author's most recent status (if the authenticating user has permission) will be returned inline. This method is rate limited to 1000 calls per hour. This method will accept user IDs or screen names as either a comma delimited string, or as an ARRAY ref. It will also accept arguments in the normal HASHREF form or as a simple list of named arguments. I.e., any of the following forms are acceptable: $nt->lookup_users({ user_id => '1234,6543,3333' }); $nt->lookup_users(user_id => '1234,6543,3333'); $nt->lookup_users({ user_id => [ 1234, 6543, 3333 ] }); $nt->lookup_users({ screen_name => 'fred,barney,wilma' }); $nt->lookup_users(screen_name => ['fred', 'barney', 'wilma']); $nt->lookup_users( screen_name => ['fred', 'barney' ], user_id => '4321,6789', ); Returns: ArrayRef[User] members_create_all alias: add_list_members Parameters: list_id, slug, owner_screen_name, owner_id Required: none Adds multiple members to a list, by specifying a reference to an array or a comma-separated list of member ids or screen names. The authenticated user must own the list to be able to add members to it. Note that lists can't have more than 500 members, and you are limited to adding up to 100 members to a list at a time with this method. Returns: List members_destroy_all alias: remove_list_members Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id Required: none Removes multiple members from a list, by specifying a reference to an array of member ids or screen names, or a string of comma separated user ids or screen names. The authenticated user must own the list to be able to remove members from it. Note that lists can't have more than 500 members, and you are limited to removing up to 100 members to a list at a time with this method. Please note that there can be issues with lists that rapidly remove and add memberships. Take care when using these methods such that you are not too rapidly switching between removals and adds on the same list. Returns: List mentions alias: replies Parameters: since_id, max_id, count, page, trim_user, include_rts, include_entities Required: none Returns the 20 most recent mentions (statuses containing @username) for the authenticating user. Returns: ArrayRef[Status] new_direct_message new_direct_message(user, text) Parameters: user, text, screen_name, user_id, include_entities Required: user, text Sends a new direct message to the specified user from the authenticating user. Requires both the user and text parameters. Returns the sent message when successful. In order to support numeric screen names, the screen_name or user_id parameters may be used instead of user. Returns: DirectMessage no_retweet_ids Parameters: none Required: none Returns an ARRAY ref of user IDs for which the authenticating user does not want to receive retweets. Returns: ArrayRef[UserIDs] public_timeline Parameters: skip_user, trim_user, include_entities Required: none Returns the 20 most recent statuses from non-protected users who have set a custom user icon. Does not require authentication. Note that the public timeline is cached for 60 seconds so requesting it more often than that is a waste of resources. If user credentials are provided, public_timeline calls are authenticated, so they count against the authenticated user's rate limit. Use ->public_timeline({ authenticate => 0 }) to make an unauthenticated call which will count against the calling IP address' rate limit, instead. Returns: ArrayRef[Status] rate_limit_status Parameters: none Required: none Returns the remaining number of API requests available to the authenticated user before the API limit is reached for the current hour. Use ->rate_limit_status({ authenticate => 0 }) to force an unauthenticated call, which will return the status for the IP address rather than the authenticated user. (Note: for a web application, this is the server's IP address.) Returns: RateLimitStatus related_results related_results(id) Parameters: id Required: id If available, returns an array of replies and mentions related to the specified status. There is no guarantee there will be any replies or mentions in the response. This method is only available to users who have access to #newtwitter. Requires authentication. Returns: ArrayRef[Status] report_spam report_spam(id) Parameters: id, user_id, screen_name, include_entities Required: id The user specified in the id is blocked by the authenticated user and reported as a spammer. Returns: User retweet retweet(id) Parameters: id, include_entities, trim_user Required: id Retweets a tweet. Requires the id parameter of the tweet you are retweeting. Returns the original tweet with retweet details embedded. Returns: Status retweeted_by retweeted_by(id) Parameters: id, count, page, trim_user, include_entities Required: id Returns up to 100 users who retweeted the status identified by id. Returns: ArrayRef[User] retweeted_by_ids retweeted_by_ids(id) Parameters: id, count, page, trim_user, include_entities Required: id Returns the IDs of up to 100 users who retweeted the status identified by id. Returns: ArrayRef[User] retweeted_by_me Parameters: since_id, max_id, count, page, trim_user, include_entities Required: none Returns the 20 most recent retweets posted by the authenticating user. Returns: ArrayRef[Status] retweeted_by_user retweeted_by_user(id) Parameters: id, user_id, screen_name Required: id Returns the 20 most recent retweets posted by the specified user. The user is specified using the user_id or screen_name parameters. This method is identical to retweeted_by_me except you can choose the user to view. Does not require authentication, unless the user is protected. Returns: ArrayRef retweeted_to_me Parameters: since_id, max_id, count, page Required: none Returns the 20 most recent retweets posted by the authenticating user's friends. Returns: ArrayRef[Status] retweeted_to_user retweeted_to_user(id) Parameters: id, user_id, screen_name Required: id Returns the 20 most recent retweets posted by users the specified user follows. The user is specified using the user_id or screen_name parameters. This method is identical to retweeted_to_me except you can choose the user to view. Does not require authentication, unless the user is protected. Returns: ArrayRef retweets retweets(id) Parameters: id, count, trim_user, include_entities Required: id Returns up to 100 of the first retweets of a given tweet. Returns: Arrayref[Status] retweets_of_me alias: retweeted_of_me Parameters: since_id, max_id, count, page, trim_user, include_entities Required: none Returns the 20 most recent tweets of the authenticated user that have been retweeted by others. Returns: ArrayRef[Status] reverse_geocode reverse_geocode(lat, long) Parameters: lat, long, accuracy, granularity, max_results Required: lat, long Search for places (cities and neighborhoods) that can be attached to a statuses/update. Given a latitude and a longitude, return a list of all the valid places that can be used as a place_id when updating a status. Conceptually, a query can be made from the user's location, retrieve a list of places, have the user validate the location he or she is at, and then send the ID of this location up with a call to statuses/update. There are multiple granularities of places that can be returned -- "neighborhoods", "cities", etc. At this time, only United States data is available through this method. lat Required. The latitude to query about. Valid ranges are -90.0 to +90.0 (North is positive) inclusive. long Required. The longitude to query about. Valid ranges are -180.0 to +180.0 (East is positive) inclusive. accuracy Optional. A hint on the "region" in which to search. If a number, then this is a radius in meters, but it can also take a string that is suffixed with ft to specify feet. If this is not passed in, then it is assumed to be 0m. If coming from a device, in practice, this value is whatever accuracy the device has measuring its location (whether it be coming from a GPS, WiFi triangulation, etc.). granularity Optional. The minimal granularity of data to return. If this is not passed in, then neighborhood is assumed. city can also be passed. max_results Optional. A hint as to the number of results to return. This does not guarantee that the number of results returned will equal max_results, but instead informs how many "nearby" results to return. Ideally, only pass in the number of places you intend to display to the user here. Returns: HashRef saved_searches Parameters: none Required: none Returns the authenticated user's saved search queries. Returns: ArrayRef[SavedSearch] sent_direct_messages Parameters: since_id, max_id, page, count, include_entities Required: none Returns a list of the 20 most recent direct messages sent by the authenticating user including detailed information about the sending and recipient users. Returns: ArrayRef[DirectMessage] show_direct_message show_direct_message(id) Parameters: id, include_entities Required: id Returns a single direct message, specified by an id parameter. Like the direct_messages request, this method will include the user objects of the sender and recipient. Requires authentication. Returns: HashRef show_friendship show_friendship(id) alias: show_relationship Parameters: source_id, source_screen_name, target_id, target_id_name Required: id Returns detailed information about the relationship between two users. Returns: Relationship show_saved_search show_saved_search(id) Parameters: id Required: id Retrieve the data for a saved search, by id, owned by the authenticating user. Returns: SavedSearch show_status show_status(id) Parameters: id, trim_user, include_entities Required: id Returns a single status, specified by the id parameter. The status's author will be returned inline. Returns: Status show_user show_user(id) Parameters: id, screen_name, include_entities Required: id Returns extended information of a given user, specified by ID or screen name as per the required id parameter. This information includes design settings, so third party developers can theme their widgets according to a given user's preferences. You must be properly authenticated to request the page of a protected user. Returns: ExtendedUser similar_places similar_places(lat, long, name) Parameters: lat, long, name, contained_within, attribute:street_address, callback Required: lat, long, name Locates places near the given coordinates which are similar in name. Conceptually you would use this method to get a list of known places to choose from first. Then, if the desired place doesn't exist, make a request to add_place to create a new one. The token contained in the response is the token needed to be able to create a new place. Returns: HashRef subscribe_list Parameters: owner_screen_name, owner_id, list_id, slug Required: none Subscribes the authenticated user to the specified list. Returns: List subscriptions Parameters: user_id, screen_name, count, cursor Required: none Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. Does not include the user's own lists. Returns: ArrayRef[List] suggestion_categories Parameters: none Required: none Returns the list of suggested user categories. The category slug can be used in the user_suggestions API method get the users in that category . Does not require authentication. Returns: ArrayRef test Parameters: none Required: none Returns the string "ok" status code. Returns: Str trends_available Parameters: lat, long Required: none Returns the locations with trending topic information. The response is an array of "locations" that encode the location's WOEID (a Yahoo! Where On Earth ID http://developer.yahoo.com/geo/geoplanet/) and some other human-readable information such as a the location's canonical name and country. When the optional lat and long parameters are passed, the available trend locations are sorted by distance from that location, nearest to farthest. Use the WOEID returned in the location object to query trends for a specific location. Returns: ArrayRef[Location] trends_current trends_current(exclude) Parameters: exclude Required: none Returns the current top ten trending topics on Twitter. The response includes the time of the request, the name of each trending topic, and query used on Twitter Search results page for that topic. Returns: HashRef trends_daily Parameters: date, exclude Required: none Returns the top 20 trending topics for each hour in a given day. Returns: HashRef trends_location trends_location(woeid) Parameters: woeid Required: woeid Returns the top 10 trending topics for a specific location. The response is an array of "trend" objects that encode the name of the trending topic, the query parameter that can be used to search for the topic on Search, and the direct URL that can be issued against Search. This information is cached for five minutes, and therefore users are discouraged from querying these endpoints faster than once every five minutes. Global trends information is also available from this API by using a WOEID of 1. Returns: ArrayRef[Trend] trends_weekly Parameters: date, exclude Required: none Returns the top 30 trending topics for each day in a given week. Returns: HashRef unsubscribe_list Parameters: list_id, slug, owner_screen_name, owner_id Required: none Unsubscribes the authenticated user from the specified list. Returns: List update update(status) Parameters: status, lat, long, place_id, display_coordinates, in_reply_to_status_id, trim_user, include_entities Required: status Updates the authenticating user's status. Requires the status parameter specified. A status update with text identical to the authenticating user's current status will be ignored. status Required. The text of your status update. URL encode as necessary. Statuses over 140 characters will cause a 403 error to be returned from the API. in_reply_to_status_id Optional. The ID of an existing status that the update is in reply to. o Note: This parameter will be ignored unless the author of the tweet this parameter references is mentioned within the status text. Therefore, you must include @username, where username is the author of the referenced tweet, within the update. lat Optional. The location's latitude that this tweet refers to. The valid ranges for latitude is -90.0 to +90.0 (North is positive) inclusive. This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding long parameter with this tweet. long Optional. The location's longitude that this tweet refers to. The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding lat parameter with this tweet. place_id Optional. The place to attach to this status update. Valid place_ids can be found by querying reverse_geocode. display_coordinates Optional. By default, geo-tweets will have their coordinates exposed in the status object (to remain backwards compatible with existing API applications). To turn off the display of the precise latitude and longitude (but keep the contextual location information), pass display_coordinates = 0> on the status update. Returns: Status update_delivery_device update_delivery_device(device) Parameters: device Required: device Sets which device Twitter delivers updates to for the authenticating user. Sending none as the device parameter will disable IM or SMS updates. Returns: BasicUser update_friendship update_friendship(id) Parameters: id, user_id, screen_name, device, retweets Required: id Allows you enable or disable retweets and device notifications from the specified user. All other values are assumed to be false. Requires authentication. Returns: HashRef update_list Parameters: list_id, slug, name, mode, description, owner_screen_name, owner_id Required: none Updates the specified list. The authenticated user must own the list to be able to update it. Returns: List update_profile Parameters: name, email, url, location, description, include_entities Required: none Sets values that users are able to set under the "Account" tab of their settings page. Only the parameters specified will be updated; to only update the "name" attribute, for example, only include that parameter in your request. Returns: ExtendedUser update_profile_background_image update_profile_background_image(image) Parameters: image, use Required: image Updates the authenticating user's profile background image. The image parameter must be an arrayref with the same interpretation as the image parameter in the update_profile_image method. The use parameter allows you to specify whether to use the uploaded profile background or not. See that method's documentation for details. Returns: ExtendedUser update_profile_colors Parameters: profile_background_color, profile_text_color, profile_link_color, profile_sidebar_fill_color, profile_sidebar_border_color Required: none Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com. These values are also returned in the /users/show API method. Returns: ExtendedUser update_profile_image update_profile_image(image) Parameters: image Required: image Updates the authenticating user's profile image. The image parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array ($file) is the name of a file to open. The second value ($filename) is the name given to Twitter for the file. If $filename is not provided, the basename portion of $file is used. If $mime_type is not provided, it will be provided automatically using LWP::MediaTypes::guess_media_type(). $raw_image_data can be provided, rather than opening a file, by passing undef as the first array value. Returns: ExtendedUser update_with_media update_with_media(status, media) Parameters: status, media[], possibly_sensitive, in_reply_to_status_id, lat, long, place_id, display_coordinates Required: status, media Updates the authenticating user's status and attaches media for upload. The media[] parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array ($file) is the name of a file to open. The second value ($filename) is the name given to Twitter for the file. If $filename is not provided, the basename portion of $file is used. If $mime_type is not provided, it will be provided automatically using LWP::MediaTypes::guess_media_type(). $raw_image_data can be provided, rather than opening a file, by passing undef as the first array value. The Tweet text will be rewritten to include the media URL(s), which will reduce the number of characters allowed in the Tweet text. If the URL(s) cannot be appended without text truncation, the tweet will be rejected and this method will return an HTTP 403 error. Returns: Status user_suggestions user_suggestions(category) alias: follow_suggestions Parameters: category, lang Required: category Access the users in a given category of the Twitter suggested user list and return their most recent status if they are not a protected user. Currently supported values for optional parameter lang are en, fr, de, es, it. Does not require authentication. Returns: ArrayRef user_timeline Parameters: id, user_id, screen_name, since_id, max_id, count, page, skip_user, trim_user, include_entities, include_rts Required: none Returns the 20 most recent statuses posted from the authenticating user. It's also possible to request another user's timeline via the id parameter. This is the equivalent of the Web /archive page for your own user, or the profile page for a third party. Returns: ArrayRef[Status] users_search users_search(q) alias: find_people alias: search_users Parameters: q, per_page, page, include_entities Required: q Run a search for users similar to Find People button on Twitter.com; the same results returned by people search on Twitter.com will be returned by using this API (about being listed in the People Search). It is only possible to retrieve the first 1000 matches from this API. Returns: ArrayRef[Users] verify_credentials verify_credentials(include_entities) Parameters: include_entities Required: none Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; returns a 401 status code and an error message if not. Use this method to test if supplied user credentials are valid. Returns: ExtendedUser Search API Methods search search(q) Parameters: q, callback, lang, locale, rpp, page, since_id, until, geocode, show_user, result_type Required: q Returns a HASH reference with some meta-data about the query including the next_page, refresh_url, and max_id. The statuses are returned in results. To iterate over the results, use something similar to: my $r = $nt->search($searh_term); for my $status ( @{$r->{results}} ) { print "$status->{text}\n"; } Returns: HashRef ERROR HANDLING When Net::Twitter::Lite encounters a Twitter API error or a network error, it throws a Net::Twitter::Lite::Error object. You can catch and process these exceptions by using eval blocks and testing $@: eval { my $statuses = $nt->friends_timeline(); # this might die! for my $status ( @$statuses ) { #... } }; if ( $@ ) { # friends_timeline encountered an error if ( blessed $@ && $@->isa('Net::Twitter::Lite::Error' ) { #... use the thrown error obj warn $@->error; } else { # something bad happened! die $@; } } Net::Twitter::Lite::Error stringifies to something reasonable, so if you don't need detailed error information, you can simply treat $@ as a string: eval { $nt->update($status) }; if ( $@ ) { warn "update failed because: $@\n"; } AUTHENTICATION Net::Twitter::Lite currently supports both Basic Authentication and OAuth. The choice of authentication strategies is determined by the options passed to new or the use of the credentials method. An error will be thrown if options for both strategies are provided. BASIC AUTHENTICATION To use Basic Authentication, pass the username and password options to new, or call credentials to set them. When Basic Authentication is used, the Authorization header is set on each authenticated API call. OAUTH AUTHENTICATION To use OAuth authentication, pass the consumer_key and consumer_secret options to new. Net::OAuth::Simple must be installed in order to use OAuth and an error will be thrown if OAuth is attempted without it. Net::Twitter::Lite does not require Net::OAuth::Simple, making OAuth an optional feature. OAUTH EXAMPLES See the examples directory included in this distribution for full working examples using OAuth. Here's how to authorize users as a desktop app mode: use Net::Twitter::Lite; my $nt = Net::Twitter::Lite->new( consumer_key => "YOUR-CONSUMER-KEY", consumer_secret => "YOUR-CONSUMER-SECRET", ); # You'll save the token and secret in cookie, config file or session database my($access_token, $access_token_secret) = restore_tokens(); if ($access_token && $access_token_secret) { $nt->access_token($access_token); $nt->access_token_secret($access_token_secret); } unless ( $nt->authorized ) { # The client is not yet authorized: Do it now print "Authorize this app at ", $nt->get_authorization_url, " and enter the PIN#\n"; my $pin = ; # wait for input chomp $pin; my($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $pin); save_tokens($access_token, $access_token_secret); # if necessary } # Everything's ready In a web application mode, you need to save the oauth_token and oauth_token_secret somewhere when you redirect the user to the OAuth authorization URL. sub twitter_authorize : Local { my($self, $c) = @_; my $nt = Net::Twitter::Lite->new(%param); my $url = $nt->get_authorization_url(callback => $callbackurl); $c->response->cookies->{oauth} = { value => { token => $nt->request_token, token_secret => $nt->request_token_secret, }, }; $c->response->redirect($url); } And when the user returns back, you'll reset those request token and secret to upgrade the request token to access token. sub twitter_auth_callback : Local { my($self, $c) = @_; my %cookie = $c->request->cookies->{oauth}->value; my $nt = Net::Twitter::Lite->new(%param); $nt->request_token($cookie{token}); $nt->request_token_secret($cookie{token_secret}); my $verifier = $c->req->param->{oauth_verifier}; my($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $verifier); # Save $access_token and $access_token_secret in the database associated with $c->user } Later on, you can retrieve and reset those access token and secret before calling any Twitter API methods. sub make_tweet : Local { my($self, $c) = @_; my($access_token, $access_token_secret) = ...; my $nt = Net::Twitter::Lite->new(%param); $nt->access_token($access_token); $nt->access_token_secret($access_token_secret); # Now you can call any Net::Twitter::Lite API methods on $nt my $status = $c->req->param('status'); my $res = $nt->update({ status => $status }); } SEE ALSO Net::Twitter::Lite::WithAPIv1_1 With support for Twitter API v1.1 Net::Twitter::Lite::Error The Net::Twitter::Lite exception object. http://apiwiki.twitter.com/Twitter-API-Documentation This is the official Twitter API documentation. It describes the methods and their parameters in more detail and may be more current than the documentation provided with this module. LWP::UserAgent::POE This LWP::UserAgent compatible class can be used in POE based application along with Net::Twitter::Lite to provide concurrent, non-blocking requests. SUPPORT Please report bugs to bug-net-twitter@rt.cpan.org, or through the web interface at https://rt.cpan.org/Dist/Display.html?Queue=Net-Twitter. Join the Net::Twitter IRC channel at irc://irc.perl.org/net-twitter. Follow perl_api: http://twitter.com/perl_api. Track Net::Twitter::Lite development at http://github.com/semifor/net-twitter-lite. AUTHOR Marc Mims CONTRIBUTORS Chris Page LICENSE Copyright (c) 2013 Marc Mims This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Net-Twitter-Lite-0.12008/t/000755 000766 000024 00000000000 13021411233 015264 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/t/00-compile.t000644 000766 000024 00000002621 13021411233 017317 0ustar00marcstaff000000 000000 use 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.054 use Test::More; plan tests => 6 + ($ENV{AUTHOR_TESTING} ? 1 : 0); my @module_files = ( 'Net/Twitter/Lite.pm', 'Net/Twitter/Lite/API/V1.pm', 'Net/Twitter/Lite/API/V1_1.pm', 'Net/Twitter/Lite/Error.pm', 'Net/Twitter/Lite/WithAPIv1_1.pm', 'Net/Twitter/Lite/WrapResult.pm' ); # no fake home requested my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib'; use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L my $stderr = IO::Handle->new; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { require blib; blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING}; Net-Twitter-Lite-0.12008/t/00_load.t000755 000766 000024 00000000241 13021411233 016667 0ustar00marcstaff000000 000000 #!perl use Test::More tests => 1; BEGIN { use_ok( 'Net::Twitter::Lite' ); } diag( "Testing Net::Twitter::Lite $Net::Twitter::Lite::VERSION, Perl $], $^X" ); Net-Twitter-Lite-0.12008/t/01_basic.t000644 000766 000024 00000014104 13021411233 017032 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; my $screen_name = 'net_twitter'; my $message_id = 1234; my $status = 'Hello, world!'; my @tests = ( [ create_block => [ $screen_name ], POST => "/blocks/create/$screen_name.json" ], [ create_favorite => [ $message_id ], POST => "/favorites/create/$message_id.json" ], [ create_favorite => [ { id => $message_id } ], POST => "/favorites/create/$message_id.json" ], [ create_friend => [ $screen_name ], POST => "/friendships/create/$screen_name.json" ], [ destroy_block => [ $screen_name ], POST => "/blocks/destroy/$screen_name.json" ], [ destroy_direct_message => [ $message_id ], POST => "/direct_messages/destroy/$message_id.json" ], [ destroy_favorite => [ $message_id ], POST => "/favorites/destroy/$message_id.json" ], [ destroy_favorite => [ { id => $message_id } ], POST => "/favorites/destroy/$message_id.json" ], [ destroy_friend => [ $screen_name ], POST => "/friendships/destroy/$screen_name.json" ], [ destroy_status => [ $message_id ], POST => "/statuses/destroy/$message_id.json" ], [ destroy_status => [ { id => $message_id } ], POST => "/statuses/destroy/$message_id.json" ], [ direct_messages => [], GET => "/direct_messages.json" ], [ disable_notifications => [ $screen_name ], POST => "/notifications/leave/$screen_name.json" ], [ disable_notifications => [ { id => $screen_name }], POST => "/notifications/leave/$screen_name.json" ], [ downtime_schedule => [], GET => "/help/downtime_schedule.json" ], [ enable_notifications => [ $screen_name ], POST => "/notifications/follow/$screen_name.json" ], [ enable_notifications => [ { id => $screen_name }], POST => "/notifications/follow/$screen_name.json" ], [ end_session => [], POST => "/account/end_session.json" ], [ favorites => [], GET => "/favorites.json" ], [ followers => [], GET => "/statuses/followers.json" ], [ friends => [], GET => "/statuses/friends.json" ], [ friends_timeline => [], GET => "/statuses/friends_timeline.json" ], [ new_direct_message => [ { user => $screen_name, text => $status } ], POST => "/direct_messages/new.json" ], [ public_timeline => [], GET => "/statuses/public_timeline.json" ], [ rate_limit_status => [], GET => "/account/rate_limit_status.json" ], [ relationship_exists => [ 'a', 'b' ], GET => "/friendships/exists.json" ], [ mentions => [], GET => "/statuses/mentions.json" ], [ sent_direct_messages => [], GET => "/direct_messages/sent.json" ], [ show_status => [ $screen_name ], GET => "/statuses/show/$screen_name.json" ], [ show_user => [ $screen_name ], GET => "/users/show/$screen_name.json" ], [ test => [], GET => "/help/test.json" ], [ update => [ $status ], POST => "/statuses/update.json" ], [ update_delivery_device => [ 'sms' ], POST => "/account/update_delivery_device.json" ], [ update_profile => [ { name => $screen_name } ], POST => "/account/update_profile.json" ], [ update_profile_background_image => [ { image => 'binary' } ], POST => "/account/update_profile_background_image.json" ], [ update_profile_colors => [ { profile_background_color => '#0000' } ], POST => "/account/update_profile_colors.json" ], [ update_profile_image => [ { image => 'binary data here' } ], POST => "/account/update_profile_image.json" ], [ user_timeline => [], GET => "/statuses/user_timeline.json" ], [ verify_credentials => [], GET => "/account/verify_credentials.json" ], ); plan tests => @tests * 4 + 2; use_ok 'Net::Twitter::Lite'; my $nt = Net::Twitter::Lite->new(legacy_lists_api => 0); isa_ok $nt, 'Net::Twitter::Lite'; my $ua = $nt->{ua}; my $http_response; $ua->add_handler(request_send => sub { my ($request, $ua, $h) = @_; $http_response = HTTP::Response->new(200, 'OK'); $http_response->request($request); $http_response->content('{"test":"success"}'); return $http_response; }); sub input_args { my $req = shift; my $uri = $req->uri->clone; my %args = $uri->query_form; if ( $uri->path =~ /\/($screen_name|$message_id)\.json$/ ) { $args{id} = $1; } $uri->query($req->content); return { %args, $uri->query_form }; } for my $test ( @tests ) { my ($api_call, $args, $method, $path) = @$test; my %args; if ( $api_call eq 'update' ) { %args = ( source => 'twitterpm', status => @$args ); } elsif ( $api_call eq 'relationship_exists' ) { @{args}{qw/user_a user_b/} = @$args; } elsif ( $api_call eq 'update_delivery_device' ) { %args = ( device => @$args ); } elsif ( @$args ) { %args = ref $args->[0] ? %{$args->[0]} : ( id => $args->[0] ); } ok $nt->$api_call(@$args), "$api_call call"; my $req = $http_response->request; (my $path_part = $req->uri->path) =~ s{^/1}{}; is_deeply input_args($req), \%args, " $api_call args"; is $path_part, $path, " $api_call path"; is $req->method, $method, " $api_call method"; } exit 0; Net-Twitter-Lite-0.12008/t/02_regression.t000644 000766 000024 00000002740 13021411233 020135 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; plan tests => 4; use Net::Twitter::Lite; my $nt = Net::Twitter::Lite->new(legacy_lists_api => 0); my $request; my %args; my $response = HTTP::Response->new(200, 'OK'); $response->content('{"test":"success"}'); my $cb = sub { $request = shift; $response->request($request); %args = $request->uri->query_form; return $response; }; sub mock_response { shift->{ua}->add_handler(request_send => $cb) } mock_response($nt); # additional args in a HASH ref my $search_term = "intelligent life"; my $r = $nt->search($search_term, { page => 2 }); is $args{q}, $search_term, "q as positional arg"; is $args{page}, 2, "page parameter set"; # Basic Auth $nt->credentials('barney','rubble'); $r = $nt->user_timeline; like $request->header('Authorization'), qr/^Basic /, 'Basic Auth header'; SKIP: { eval 'use Net::OAuth 0.25'; skip "Net::OAuth >= 0.25 required for this test", 1 if $@; # NTL fails on methods using HTTP DELETE with OAuth (reported 2011-03-28) my $nt = Net::Twitter::Lite->new( consumer_key => 'key', consumer_secret => 'secret', access_token => 'token', access_token_secret => 'token_secret', legacy_lists_api => 0, ); mock_response($nt); ok eval { $nt->delete_list(fred => 'pets', { -legacy_lists_api => 1}) }, 'HTTP DELETE'; } Net-Twitter-Lite-0.12008/t/03-v1_1.t000644 000766 000024 00000011702 13021411233 016440 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; my $screen_name = 'net_twitter'; my $message_id = 1234; my $status = 'Hello, world!'; my @tests = ( [ create_block => [ { screen_name => $screen_name } ], POST => "/blocks/create.json" ], [ create_favorite => [ $message_id ], POST => "/favorites/create.json" ], [ create_favorite => [ { id => $message_id } ], POST => "/favorites/create.json" ], [ create_friend => [ { screen_name => $screen_name } ], POST => "/friendships/create.json" ], [ destroy_block => [ { screen_name => $screen_name } ], POST => "/blocks/destroy.json" ], [ destroy_direct_message => [ $message_id ], POST => "/direct_messages/destroy.json" ], [ destroy_favorite => [ $message_id ], POST => "/favorites/destroy.json" ], [ destroy_favorite => [ { id => $message_id } ], POST => "/favorites/destroy.json" ], [ destroy_friend => [ { screen_name => $screen_name } ], POST => "/friendships/destroy.json" ], [ destroy_status => [ $message_id ], POST => "/statuses/destroy/$message_id.json" ], [ destroy_status => [ { id => $message_id } ], POST => "/statuses/destroy/$message_id.json" ], [ direct_messages => [], GET => "/direct_messages.json" ], [ favorites => [], GET => "/favorites/list.json" ], [ followers => [], GET => "/followers/list.json" ], [ friends => [], GET => "/friends/list.json" ], [ new_direct_message => [ { screen_name => $screen_name, text => $status } ], POST => "/direct_messages/new.json" ], [ rate_limit_status => [], GET => "/application/rate_limit_status.json" ], [ mentions => [], GET => "/statuses/mentions_timeline.json" ], [ sent_direct_messages => [], GET => "/direct_messages/sent.json" ], [ show_status => [ $message_id ], GET => "/statuses/show/$message_id.json" ], [ show_user => [ { screen_name => $screen_name } ], GET => "/users/show.json" ], [ update => [ $status ], POST => "/statuses/update.json" ], [ update_delivery_device => [ 'sms' ], POST => "/account/update_delivery_device.json" ], [ update_profile => [ { name => $screen_name } ], POST => "/account/update_profile.json" ], [ update_profile_background_image => [ { image => 'binary' } ], POST => "/account/update_profile_background_image.json" ], [ update_profile_colors => [ { profile_background_color => '#0000' } ], POST => "/account/update_profile_colors.json" ], [ update_profile_image => [ { image => 'binary data here' } ], POST => "/account/update_profile_image.json" ], [ user_timeline => [], GET => "/statuses/user_timeline.json" ], [ verify_credentials => [], GET => "/account/verify_credentials.json" ], ); plan tests => @tests * 4 + 2; use_ok 'Net::Twitter::Lite::WithAPIv1_1'; my $nt = Net::Twitter::Lite::WithAPIv1_1->new(ssl => 1); isa_ok $nt, 'Net::Twitter::Lite::WithAPIv1_1'; my $ua = $nt->{ua}; my $http_response; $ua->add_handler(request_send => sub { my ($request, $ua, $h) = @_; $http_response = HTTP::Response->new(200, 'OK'); $http_response->request($request); $http_response->content('{"test":"success"}'); return $http_response; }); sub input_args { my $req = shift; my $uri = $req->uri->clone; my %args = $uri->query_form; if ( $uri->path =~ /\/($screen_name|$message_id)\.json$/ ) { $args{id} = $1; } $uri->query($req->content); return { %args, $uri->query_form }; } for my $test ( @tests ) { my ($api_call, $args, $method, $path) = @$test; my %args; if ( $api_call eq 'update' ) { %args = ( source => 'twitterpm', status => @$args ); } elsif ( $api_call eq 'relationship_exists' ) { @{args}{qw/user_a user_b/} = @$args; } elsif ( $api_call eq 'update_delivery_device' ) { %args = ( device => @$args ); } elsif ( @$args ) { %args = ref $args->[0] ? %{$args->[0]} : ( id => $args->[0] ); } ok $nt->$api_call(@$args), "$api_call call"; my $req = $http_response->request; (my $path_part = $req->uri->path) =~ s{^/1\.1}{}; is_deeply input_args($req), \%args, " $api_call args"; is $path_part, $path, " $api_call path"; is $req->method, $method, " $api_call method"; } exit 0; Net-Twitter-Lite-0.12008/t/04-wrapresult.t000644 000766 000024 00000023045 13021411233 020106 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; my $screen_name = 'net_twitter'; my $message_id = 1234; my $status = 'Hello, world!'; my $now = time(); my @tests = ( # api call args method path lim rem reset [ create_block => [ { screen_name => $screen_name } ], POST => "/blocks/create.json" ], [ direct_messages => [ ] , GET => "/direct_messages.json", 15, 14, $now ], [ direct_messages => [ ] , GET => "/direct_messages.json", 15, 13, $now ], [ direct_messages => [ ] , GET => "/direct_messages.json", 15, 12, $now ], [ favorites => [ { screen_name => $screen_name } ], GET => "/favorites/list.json" , 15, 14, $now ], [ favorites => [ { screen_name => $screen_name } ], GET => "/favorites/list.json" , 15, 13, $now ], [ favorites => [ { screen_name => $screen_name } ], GET => "/favorites/list.json" , 15, 12, $now ], [ followers_list => [ { screen_name => $screen_name } ], GET => "/followers/list.json" , 15, 14, $now ], [ followers_list => [ { screen_name => $screen_name } ], GET => "/followers/list.json" , 15, 13, $now ], [ followers_list => [ { screen_name => $screen_name } ], GET => "/followers/list.json" , 15, 12, $now ], [ friends_list => [ { screen_name => $screen_name } ], GET => "/friends/list.json" , 15, 14, $now ], [ friends_list => [ { screen_name => $screen_name } ], GET => "/friends/list.json" , 15, 13, $now ], [ friends_list => [ { screen_name => $screen_name } ], GET => "/friends/list.json" , 15, 12, $now ], [ new_direct_message => [ { screen_name => $screen_name, text => $status } ], POST => "/direct_messages/new.json" ], [ users_search => [ { q => $screen_name } ], GET => "/users/search.json" , 180, 179, $now ], [ users_search => [ { q => $screen_name } ], GET => "/users/search.json" , 180, 178, $now ], [ users_search => [ { q => $screen_name } ], GET => "/users/search.json" , 180, 177, $now ], ); plan tests => @tests * 14 + 3; use_ok 'Net::Twitter::Lite::WithAPIv1_1'; my $nt = Net::Twitter::Lite::WithAPIv1_1->new(ssl => 1, wrap_result => 1); isa_ok $nt, 'Net::Twitter::Lite::WithAPIv1_1'; my $limits = { # Resource lim rem reset "/account/settings.json" => [ 15, 15, $now], "/account/verify_credentials.json" => [ 15, 15, $now], "/application/rate_limit_status.json" => [180, 180, $now], "/blocks/ids.json" => [ 15, 15, $now], "/blocks/list.json" => [ 15, 15, $now], "/direct_messages.json" => [ 15, 15, $now], "/direct_messages/sent.json" => [ 15, 15, $now], "/direct_messages/show.json" => [ 15, 15, $now], "/favorites/list.json" => [ 15, 15, $now], "/followers/ids.json" => [ 15, 15, $now], "/followers/list.json" => [ 15, 15, $now], "/friends/ids.json" => [ 15, 15, $now], "/friends/list.json" => [ 15, 15, $now], "/friendships/incoming.json" => [ 15, 15, $now], "/friendships/lookup.json" => [ 15, 15, $now], "/friendships/no_retweets/ids.json" => [ 15, 15, $now], "/friendships/outgoing.json" => [ 15, 15, $now], "/friendships/show.json" => [180, 180, $now], "/geo/reverse_geocode.json" => [ 15, 15, $now], "/geo/search.json" => [ 15, 15, $now], "/geo/similar_places.json" => [ 15, 15, $now], "/help/configuration.json" => [ 15, 15, $now], "/help/languages.json" => [ 15, 15, $now], "/help/privacy.json" => [ 15, 15, $now], "/help/tos.json" => [ 15, 15, $now], "/lists.json" => [ 15, 15, $now], "/lists/list.json" => [ 15, 15, $now], "/lists/members.json" => [180, 180, $now], "/lists/members/show.json" => [ 15, 15, $now], "/lists/memberships.json" => [ 15, 15, $now], "/lists/ownerships.json" => [ 15, 15, $now], "/lists/show.json" => [ 15, 15, $now], "/lists/statuses.json" => [180, 180, $now], "/lists/subscribers.json" => [180, 180, $now], "/lists/subscribers/show.json" => [ 15, 15, $now], "/lists/subscriptions.json" => [ 15, 15, $now], "/saved_searches/list.json" => [ 15, 15, $now], "/search/tweets.json" => [180, 180, $now], "/statuses/home_timeline.json" => [ 15, 15, $now], "/statuses/mentions_timeline.json" => [ 15, 15, $now], "/statuses/oembed.json" => [180, 180, $now], "/statuses/retweeters/ids.json" => [ 15, 15, $now], "/statuses/retweets_of_me.json" => [ 15, 15, $now], "/statuses/user_timeline.json" => [180, 180, $now], "/trends/available.json" => [ 15, 15, $now], "/trends/closest.json" => [ 15, 15, $now], "/trends/place.json" => [ 15, 15, $now], "/users/contributees.json" => [ 15, 15, $now], "/users/contributors.json" => [ 15, 15, $now], "/users/lookup.json" => [180, 180, $now], "/users/profile_banner.json" => [180, 180, $now], "/users/search.json" => [180, 180, $now], "/users/show.json" => [180, 180, $now], "/users/suggestions.json" => [ 15, 15, $now], }; my $ua = $nt->{ua}; my $http_response; $ua->add_handler(request_send => sub { my ($request, $ua, $h) = @_; $http_response = HTTP::Response->new(200, 'OK'); $http_response->request($request); $http_response->content('{"test":"success"}'); my ($resource) = $request->uri =~ m|^https?://api.twitter.com/1.1(.*?)(?:\?.*)?$|; if($resource && $limits -> {$resource}) { $http_response->header('x-rate-limit-limit' => $limits->{$resource}->[0]); $http_response->header('x-rate-limit-remaining' => --$limits->{$resource}->[1]); $http_response->header('x-rate-limit-reset' => $limits->{$resource}->[2]); } return $http_response; }); use Data::Dumper; my ($resp, $result, $http_resp); for my $test ( @tests ) { my ($api_call, $args, $method, $path, $limit, $remain, $reset) = @$test; my %args; if ( $api_call eq 'update' ) { %args = ( source => 'twitterpm', status => @$args ); } elsif ( $api_call eq 'relationship_exists' ) { @{args}{qw/user_a user_b/} = @$args; } elsif ( $api_call eq 'update_delivery_device' ) { %args = ( device => @$args ); } elsif ( @$args ) { %args = ref $args->[0] ? %{$args->[0]} : ( id => $args->[0] ); } ok $resp = $nt->$api_call(@$args), "$api_call call"; isa_ok $resp, 'Net::Twitter::Lite::WrapResult'; ok $resp->http_response, "http response available"; isa_ok $resp->http_response, 'HTTP::Response'; ok $result = $resp->result, "result is available"; isa_ok $result, "HASH"; ok $result->{"test"} eq "success", "test request success"; if(defined($limit)) { ok $limit == $resp->rate_limit, "$api_call limit = $limit"; ok $remain == $resp->rate_limit_remaining, "$api_call limit remaining = $remain"; ok $reset == $resp->rate_limit_reset, "$api_call limit reset = $reset"; } else { ok !defined($resp->rate_limit), "$api_call no limit"; ok !defined($resp->rate_limit_remaining), "$api_call no limit remaining"; ok !defined($resp->rate_limit_reset), "$api_call no reset"; } } $nt = Net::Twitter::Lite::WithAPIv1_1->new(ssl => 1); isa_ok $nt, 'Net::Twitter::Lite::WithAPIv1_1'; $ua = $nt->{ua}; $ua->add_handler(request_send => sub { my ($request, $ua, $h) = @_; $http_response = HTTP::Response->new(200, 'OK'); $http_response->request($request); $http_response->content('{"test":"success"}'); my ($resource) = $request->uri =~ m|^https?://api.twitter.com/1.1(.*?)(?:\?.*)?$|; if($resource && $limits -> {$resource}) { $http_response->header('x-rate-limit-limit' => $limits->{$resource}->[0]); $http_response->header('x-rate-limit-remaining' => --$limits->{$resource}->[1]); $http_response->header('x-rate-limit-reset' => $limits->{$resource}->[2]); } return $http_response; }); for my $test ( @tests ) { my ($api_call, $args, $method, $path, $limit, $remain, $reset) = @$test; my %args; if ( $api_call eq 'update' ) { %args = ( source => 'twitterpm', status => @$args ); } elsif ( $api_call eq 'relationship_exists' ) { @{args}{qw/user_a user_b/} = @$args; } elsif ( $api_call eq 'update_delivery_device' ) { %args = ( device => @$args ); } elsif ( @$args ) { %args = ref $args->[0] ? %{$args->[0]} : ( id => $args->[0] ); } ok $resp = $nt->$api_call(@$args), "$api_call call"; isa_ok $resp, "HASH"; ok(defined $resp && !UNIVERSAL::isa($resp, 'Net::Twitter::Lite::WrapResult'), "$api_call response not wrapped"); ok $result->{"test"} eq "success", "test request success"; } exit 0; Net-Twitter-Lite-0.12008/t/99-pod_spelling.t000644 000766 000024 00000001617 13021411233 020374 0ustar00marcstaff000000 000000 #!perl -w use strict; use warnings; use Test::More; plan skip_all => 'set TEST_POD to enable this test' unless ($ENV{TEST_POD} || -e 'MANIFEST.SKIP'); eval 'use Test::Spelling 0.11'; plan skip_all => 'Test::Spelling 0.11 not installed' if $@; set_spell_cmd('aspell list'); add_stopwords(); all_pod_files_spelling_ok(); __DATA__ API apirealm APIs apiurl BasicUser clientname clienturl clientver contributees cursored DirectMessage ExtendedUser favorited friended geo geocode GPS granularities Identi Identica identica IM inline IP ip IRC Laconica lang maxwidth Mims multipart netrc OAUTH OAuth oEmbed oembed ok RateLimitStatus requester's return's retweet retweeted retweeting Retweets retweets rpp RWD SavedSearch SMS spammer SSL ssl Str stringifies timeline Twitter's twitterpm twittervision TwitterVision Un un unfollow Unsubscribes url useragent username usernames WiFi WOEID woeid XAuth xauth Net-Twitter-Lite-0.12008/t/author-pod-coverage.t000644 000766 000024 00000000536 13021411233 021330 0ustar00marcstaff000000 000000 #!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { print qq{1..0 # SKIP these tests are for testing by the author\n}; exit } } # This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests. use Test::Pod::Coverage 1.08; use Pod::Coverage::TrustPod; all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); Net-Twitter-Lite-0.12008/t/author-pod-syntax.t000644 000766 000024 00000000454 13021411233 021062 0ustar00marcstaff000000 000000 #!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { print qq{1..0 # SKIP these tests are for testing by the author\n}; exit } } # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); Net-Twitter-Lite-0.12008/t/legacy_lists_api.t000644 000766 000024 00000010770 13021411233 020771 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; use Net::Twitter::Lite; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; my $nt = Net::Twitter::Lite->new(username => 'fred', password => 'secret', legacy_lists_api => 1); my $req; my $res = HTTP::Response->new(200); $res->content('{"response":"done"}'); $nt->{ua}->add_handler(request_send => sub { $req = shift; return $res }); my @tests = ( create_list => { args => [ 'owner', { name => 'Test list', description => 'Just a test', mode => 'private' } ], path => '/owner/lists', params => { name => 'Test list', description => 'Just a test', mode => 'private' }, method => 'POST', }, update_list => { args => [ 'owner', 'test-list', { mode => 'public' } ], path => '/owner/lists/test-list', params => { mode => 'public' }, method => 'POST', }, list_lists => { args =>[ 'owner' ], path => '/owner/lists', params => {}, method => 'GET', }, list_memberships => { args => [ 'owner' ], path => '/owner/lists/memberships', params => {}, method => 'GET', }, delete_list => { args => [ 'owner', 'test-list' ], path => '/owner/lists/test-list', params => {}, method => 'DELETE', }, list_statuses => { args => [ 'owner', 'test-list' ], path => '/owner/lists/test-list/statuses', params => {}, method => 'GET', }, get_list => { args => [ 'owner', 'test-list' ], path => '/owner/lists/test-list', params => {}, method => 'GET', }, add_list_member => { args => [ 'owner', 'test-list', 1234 ], path => '/owner/test-list/members', params => { id => 1234 }, method => 'POST', }, delete_list_member => { args => [ 'owner', 'test-list', 1234 ], path => '/owner/test-list/members', params => { id => 1234 }, method => 'DELETE', }, remove_list_member => { args => [ 'owner', 'test-list', 1234 ], path => '/owner/test-list/members', params => { id => 1234 }, method => 'DELETE', }, list_members => { args => [ 'owner', 'test-list' ], path => '/owner/test-list/members', params => {}, method => 'GET', }, is_list_member => { args => [ 'owner', 'test-list', 1234 ], path => '/owner/test-list/members/1234', params => {}, method => 'GET', }, subscribe_list => { args => [ 'owner', 'some-list' ], path => '/owner/some-list/subscribers', params => {}, method => 'POST', }, list_subscribers => { args => [ 'owner', 'some-list' ], path => '/owner/some-list/subscribers', params => {}, method => 'GET', }, list_subscriptions => { args => [ 'owner' ], path => '/owner/lists/subscriptions', params => {}, method => 'GET', }, unsubscribe_list => { args => [ 'owner', 'test-list' ], path => '/owner/test-list/subscribers', params => {}, method => 'DELETE', }, is_list_subscriber => { args => [ 'owner', 'test-list', 1234 ], path => '/owner/test-list/subscribers/1234', params => {}, method => 'GET', }, is_subscribed_list => { args => [ 'owner', 'test-list', 1234 ], path => '/owner/test-list/subscribers/1234', params => {}, method => 'GET', }, ); plan tests => scalar @tests / 2 * 3 + 2; while ( @tests ) { my $api_method = shift @tests; my $t = shift @tests; my $r = $nt->$api_method(@{ $t->{args} }); is $req->uri->path, "/1$t->{path}.json", "$api_method: path"; is $req->method, $t->{method}, "$api_method: HTTP method"; is_deeply extract_args($req), $t->{params}, "$api_method: parameters"; } { # unauthenticated call my $r = $nt->list_statuses(twitter => 'team', { authenticate => 0 }); ok !$req->header('authorization'), 'unauthenticated call'; # authenticated call (default) $r = $nt->list_statuses(twitter => 'team'); like $req->header('authorization'), qr/^Basic/, 'authenticated request (default)'; } sub extract_args { my $req = shift; my $uri; if ( $req->method eq 'POST' ) { $uri = URI->new; $uri->query($req->content); } else { $uri = $req->uri; } return { $uri->query_form }; } Net-Twitter-Lite-0.12008/t/new-lists.t000644 000766 000024 00000015437 13021411233 017410 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; use Net::Twitter::Lite; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; my $nt = Net::Twitter::Lite->new(username => 'fred', password => 'secret', legacy_lists_api => 0); my $req; my $res = HTTP::Response->new(200); $res->content('{"response":"done"}'); $nt->{ua}->add_handler(request_send => sub { $req = shift; return $res }); my @tests = ( create_list => { args => [ { name => 'Test list', description => 'Just a test', mode => 'private' } ], path => '/lists/create', params => { name => 'Test list', description => 'Just a test', mode => 'private' }, method => 'POST', }, update_list => { args => [ { owner_screen_name => 'owner', slug => 'test-list', mode => 'public' } ], path => '/lists/update', params => { owner_screen_name => 'owner', slug => 'test-list', mode => 'public' }, method => 'POST', }, list_lists => { args =>[ { owner_screen_name => 'owner' } ], path => '/lists', params => { owner_screen_name => 'owner' }, method => 'GET', }, list_memberships => { args => [], path => '/lists/memberships', params => {}, method => 'GET', }, delete_list => { args => [ { owner_screen_name => 'owner', slug => 'test-list' } ], path => '/lists/destroy', params => { owner_screen_name => 'owner', slug => 'test-list' }, method => 'POST', }, list_statuses => { args => [ { owner_screen_name => 'owner', slug => 'test-list' } ], path => '/lists/statuses', params => { owner_screen_name => 'owner', slug => 'test-list' }, method => 'GET', }, get_list => { args => [ { owner_srceen_name => 'owner', slug => 'test-list' } ], path => '/lists/show', params => { owner_srceen_name => 'owner', slug => 'test-list' }, method => 'GET', }, add_list_member => { args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ], path => '/lists/members/create', params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 }, method => 'POST', }, delete_list_member => { args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ], path => '/lists/members/destroy', params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 }, method => 'POST', }, remove_list_member => { args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ], path => '/lists/members/destroy', params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 }, method => 'POST', }, list_members => { args => [ { owner_screen_name => 'owner', slug => 'test-list' } ], path => '/lists/members', params => { owner_screen_name => 'owner', slug => 'test-list' }, method => 'GET', }, is_list_member => { args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ], path => '/lists/members/show', params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 }, method => 'GET', }, subscribe_list => { args => [ { owner_screen_name => 'owner', slug => 'some-list' } ], path => '/lists/subscribers/create', params => { owner_screen_name => 'owner', slug => 'some-list' }, method => 'POST', }, list_subscribers => { args => [ { owner_screen_name => 'owner', slug => 'some-list' } ], path => '/lists/subscribers', params => { owner_screen_name => 'owner', slug => 'some-list' }, method => 'GET', }, list_subscriptions => { args => [], path => '/lists/all', params => {}, method => 'GET', }, unsubscribe_list => { args => [ { owner_screen_name => 'owner', slug => 'test-list' } ], path => '/lists/subscribers/destroy', params => { owner_screen_name => 'owner', slug => 'test-list' }, method => 'POST', }, is_list_subscriber => { args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ], path => '/lists/subscribers/show', params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 }, method => 'GET', }, is_subscribed_list => { args => [ { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 } ], path => '/lists/subscribers/show', params => { owner_screen_name => 'owner', slug => 'test-list', user_id => 1234 }, method => 'GET', }, members_create_all => { args => [ { list_id => 9876, screen_name => [qw/bert barney fred/] }], path => '/lists/members/create_all', params => { list_id => 9876, screen_name => 'bert,barney,fred' }, method => 'POST', }, add_list_members => { args => [ { list_id => 9876, screen_name => [qw/bert barney fred/] }], path => '/lists/members/create_all', params => { list_id => 9876, screen_name => 'bert,barney,fred' }, method => 'POST', }, remove_list_members => { args => [ { list_id => 9876, screen_name => [qw/bert barney fred/] }], path => '/lists/members/destroy_all', params => { list_id => 9876, screen_name => 'bert,barney,fred' }, method => 'POST', }, get_lists => { args => [ { screen_name => 'owner' } ], path => '/lists', params => { screen_name => 'owner' }, method => 'GET', }, subscriptions => { args => [], path => '/lists/subscriptions', params => {}, method => 'GET', }, ); plan tests => scalar @tests / 2 * 3 + 2; while ( @tests ) { my $api_method = shift @tests; my $t = shift @tests; my $r = $nt->$api_method(@{ $t->{args} }); is $req->uri->path, "/1$t->{path}.json", "$api_method: path"; is $req->method, $t->{method}, "$api_method: HTTP method"; is_deeply extract_args($req), $t->{params}, "$api_method: parameters"; } { # unauthenticated call my $r = $nt->list_statuses({ owner_screen_name => 'twitter' => slug => 'team', authenticate => 0 }); ok !$req->header('authorization'), 'unauthenticated call'; # authenticated call (default) $r = $nt->list_statuses({ owner_screen_name => 'twitter' => slug => 'team' }); like $req->header('authorization'), qr/^Basic/, 'authenticated request (default)'; } sub extract_args { my $req = shift; my $uri; if ( $req->method eq 'POST' ) { $uri = URI->new; $uri->query($req->content); } else { $uri = $req->uri; } return { $uri->query_form }; } Net-Twitter-Lite-0.12008/t/ssl.t000644 000766 000024 00000001030 13021411233 016244 0ustar00marcstaff000000 000000 #!perl use Test::More; use Net::Twitter::Lite; eval 'use LWP::UserAgent 5.819'; plan skip_all => 'LWP::UserAgent 5.819 required' if $@; plan tests => 1; my $nt = Net::Twitter::Lite->new(ssl => 1, legacy_lists_api => 0); my $request; my $response = HTTP::Response->new(200, 'OK'); $response->content('{"test":"success"}'); $nt->{ua}->add_handler(request_send => sub { $request = shift; $response->request($request); return $response; }); my $r = $nt->search('perl'); like $request->uri, qr/^https:/, 'Search API URL'; Net-Twitter-Lite-0.12008/t/unicode.t000644 000766 000024 00000004275 13021411233 017107 0ustar00marcstaff000000 000000 #!perl use warnings; use strict; use Test::More; use Encode qw/decode encode_utf8 decode_utf8/; use Net::Twitter::Lite; eval "use LWP::UserAgent 5.819"; plan skip_all => 'LWP::UserAgent >= 5.819 required' if $@; plan tests => 9; my $req; my $ua = LWP::UserAgent->new; $ua->add_handler(request_send => sub { $req = shift; return HTTP::Response->new(200); }); sub raw_sent_status { my $uri = URI->new; $uri->query($req->content); my %params = $uri->query_form; return $params{status}; } sub sent_status { decode_utf8 raw_sent_status() } my $nt = Net::Twitter::Lite->new( username => 'key', password => 'secret', ua => $ua, legacy_lists_api => 0, ); $nt->access_token('token'); $nt->access_token_secret('secret'); # "Hello world!" in traditional Chinese if Google translate is correct my $status = "\x{4E16}\x{754C}\x{60A8}\x{597D}\x{FF01}"; ok utf8::is_utf8($status), 'status parameter is decoded'; eval { $nt->update($status) }; is sent_status(), $status, 'sent status matches update parameter'; # ISO-8859-1 my $latin1 = "\xabHello, world\xbb"; ok !utf8::is_utf8($latin1), "latin-1 string is not utf8 internally"; eval { $nt->update($latin1) }; is sent_status(), $latin1, "latin-1 matches"; ok !utf8::is_utf8($latin1), "latin-1 not promoted to utf8"; ### Net::Twitter expects decoded characters, not encoded bytes ### So, sending encoded utf8 to Net::Twitter will result in double ### encoded data. SKIP: { eval "use Encode::DoubleEncodedUTF8"; skip "requires Encode::DoubleEncodedUTF8", 2 if $@; eval { $nt->update(encode_utf8 $status) }; my $bytes = raw_sent_status(); isnt $bytes, encode_utf8($status), "encoded status does not match"; is decode('utf-8-de', $bytes), $status, "double encoded"; }; ############################################################ # Basic Auth ############################################################ $nt = Net::Twitter::Lite->new( username => 'fred', password => 'pebbles', ua => $ua, legacy_lists_api => 0, ); eval { $nt->update($status) }; is sent_status(), $status, 'basic auth'; eval { $nt->update($latin1) }; is sent_status(), $latin1, 'latin-1 basic auth'; Net-Twitter-Lite-0.12008/lib/Net/000755 000766 000024 00000000000 13021411233 016315 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/lib/Net/Twitter/000755 000766 000024 00000000000 13021411233 017757 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/000755 000766 000024 00000000000 13021411233 020654 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite.pm000644 000766 000024 00000046135 13021411233 021223 0ustar00marcstaff000000 000000 package Net::Twitter::Lite; our $VERSION = '0.12008'; use 5.005; use warnings; use strict; =head1 NAME Net::Twitter::Lite - A perl library for Twitter's API v1 =head1 VERSION version 0.12008 =cut use Carp; use URI::Escape; use JSON; use HTTP::Request::Common; use Net::Twitter::Lite::Error; use Encode qw/encode_utf8/; use Net::Twitter::Lite::WrapResult; sub twitter_api_def_from () { 'Net::Twitter::Lite::API::V1' } sub _default_api_url () { 'http://api.twitter.com/1' } sub _default_searchapiurl () { 'http://search.twitter.com' } sub _default_search_trends_api_url () { 'http://api.twitter.com/1' } sub _default_lists_api_url () { 'http://api.twitter.com/1' } my $json_handler = JSON->new->utf8; sub new { my ($class, %args) = @_; $class->can('verify_credentials') || $class->build_api_methods; my $netrc = delete $args{netrc}; my $new = bless { apiurl => $class->_default_api_url, searchapiurl => $class->_default_searchapiurl, search_trends_api_url => $class->_default_search_trends_api_url, lists_api_url => $class->_default_lists_api_url, apirealm => 'Twitter API', $args{identica} ? ( apiurl => 'http://identi.ca/api' ) : (), useragent => (ref $class || $class) . "/$VERSION (Perl)", clientname => (ref $class || $class), clientver => $VERSION, clienturl => 'http://search.cpan.org/dist/Net-Twitter-Lite/', source => 'twitterpm', useragent_class => 'LWP::UserAgent', useragent_args => {}, oauth_urls => { request_token_url => "https://api.twitter.com/oauth/request_token", authentication_url => "https://api.twitter.com/oauth/authenticate", authorization_url => "https://api.twitter.com/oauth/authorize", access_token_url => "https://api.twitter.com/oauth/access_token", xauth_url => "https://api.twitter.com/oauth/access_token", }, netrc_machine => 'api.twitter.com', %args }, $class; unless ( exists $new->{legacy_lists_api} ) { $new->{legacy_lists_api} = 1; carp "For backwards compatibility @{[ __PACKAGE__ ]} uses the deprecated Lists API endpoints and semantics. This default will be changed in a future version. Please update your code to use the new lists semantics and pass (legacy_lists_api => 0) to new. You can disable this warning, and keep backwards compatibility by passing (legacy_lists_api => 1) to new. Be warned, however, that support for the legacy endpoints will be removed in a future version and the default will change to (legacy_lists_api => 0)."; } if ( delete $args{ssl} ) { $new->{$_} =~ s/^http:/https:/ for qw/apiurl searchapiurl search_trends_api_url lists_api_url/; } # get username and password from .netrc if ( $netrc ) { eval { require Net::Netrc; 1 } || croak "Net::Netrc is required for the netrc option"; my $host = $netrc eq '1' ? $new->{netrc_machine} : $netrc; my $nrc = Net::Netrc->lookup($host) || croak "No .netrc entry for $host"; @{$new}{qw/username password/} = $nrc->lpa; } $new->{ua} ||= do { eval "use $new->{useragent_class}"; croak $@ if $@; $new->{useragent_class}->new(%{$new->{useragent_args}}); }; $new->{ua}->agent($new->{useragent}); $new->{ua}->default_header('X-Twitter-Client' => $new->{clientname}); $new->{ua}->default_header('X-Twitter-Client-Version' => $new->{clientver}); $new->{ua}->default_header('X-Twitter-Client-URL' => $new->{clienturl}); $new->{ua}->env_proxy; $new->{_authenticator} = exists $new->{consumer_key} ? '_oauth_authenticated_request' : '_basic_authenticated_request'; $new->credentials(@{$new}{qw/username password/}) if exists $new->{username} && exists $new->{password}; return $new; } sub credentials { my $self = shift; my ($username, $password) = @_; croak "exected a username and password" unless @_ == 2; croak "OAuth authentication is in use" if exists $self->{consumer_key}; $self->{username} = $username; $self->{password} = $password; my $uri = URI->new($self->{apiurl}); my $netloc = join ':', $uri->host, $uri->port; $self->{ua}->credentials($netloc, $self->{apirealm}, $username, $password); } # This is a hack. Rather than making Net::OAuth an install requirement for # Net::Twitter::Lite, require it at runtime if any OAuth methods are used. It # simply returns the string 'Net::OAuth' after successfully requiring # Net::OAuth. sub _oauth { my $self = shift; return $self->{_oauth} ||= do { eval "use Net::OAuth 0.25"; croak "Install Net::OAuth 0.25 or later for OAuth support" if $@; eval '$Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A'; die $@ if $@; 'Net::OAuth'; }; } # simple check to see if we have access tokens; does not check to see if they are valid sub authorized { my $self = shift; return defined $self->{access_token} && $self->{access_token_secret}; } # get the athorization or authentication url sub _get_auth_url { my ($self, $which_url, %params ) = @_; $self->_request_request_token(%params); my $uri = $self->$which_url; $uri->query_form(oauth_token => $self->request_token); return $uri; } # get the authentication URL from Twitter sub get_authentication_url { return shift->_get_auth_url(authentication_url => @_) } # get the authorization URL from Twitter sub get_authorization_url { return shift->_get_auth_url(authorization_url => @_) } # common portion of all oauth requests sub _make_oauth_request { my ($self, $type, %params) = @_; my $request = $self->_oauth->request($type)->new( version => '1.0', consumer_key => $self->{consumer_key}, consumer_secret => $self->{consumer_secret}, request_method => 'GET', signature_method => 'HMAC-SHA1', timestamp => time, nonce => time ^ $$ ^ int(rand 2**32), %params, ); $request->sign; return $request; } # called by get_authorization_url to obtain request tokens sub _request_request_token { my ($self, %params) = @_; my $uri = $self->request_token_url; $params{callback} ||= 'oob'; my $request = $self->_make_oauth_request( 'request token', request_url => $uri, %params, ); my $res = $self->{ua}->get($request->to_url); die "GET $uri failed: ".$res->status_line unless $res->is_success; # reuse $uri to extract parameters from the response content $uri->query($res->content); my %res_param = $uri->query_form; $self->request_token($res_param{oauth_token}); $self->request_token_secret($res_param{oauth_token_secret}); } # exchange request tokens for access tokens; call with (verifier => $verifier) sub request_access_token { my ($self, %params ) = @_; my $uri = $self->access_token_url; my $request = $self->_make_oauth_request( 'access token', request_url => $uri, token => $self->request_token, token_secret => $self->request_token_secret, %params, # verifier => $verifier ); my $res = $self->{ua}->get($request->to_url); die "GET $uri failed: ".$res->status_line unless $res->is_success; # discard request tokens, they're no longer valid delete $self->{request_token}; delete $self->{request_token_secret}; # reuse $uri to extract parameters from content $uri->query($res->content); my %res_param = $uri->query_form; return ( $self->access_token($res_param{oauth_token}), $self->access_token_secret($res_param{oauth_token_secret}), $res_param{user_id}, $res_param{screen_name}, ); } # exchange username and password for access tokens sub xauth { my ( $self, $username, $password ) = @_; my $uri = $self->xauth_url; my $request = $self->_make_oauth_request( 'XauthAccessToken', request_url => $uri, x_auth_username => $username, x_auth_password => $password, x_auth_mode => 'client_auth', ); my $res = $self->{ua}->get($request->to_url); die "GET $uri failed: ".$res->status_line unless $res->is_success; # reuse $uri to extract parameters from content $uri->query($res->content); my %res_param = $uri->query_form; return ( $self->access_token($res_param{oauth_token}), $self->access_token_secret($res_param{oauth_token_secret}), $res_param{user_id}, $res_param{screen_name}, ); } # common call for both Basic Auth and OAuth sub _authenticated_request { my $self = shift; my $authenticator = $self->{_authenticator}; $self->$authenticator(@_); } sub _encode_args { my $args = shift; # Values need to be utf-8 encoded. Because of a perl bug, exposed when # client code does "use utf8", keys must also be encoded. # see: http://www.perlmonks.org/?node_id=668987 # and: http://perl5.git.perl.org/perl.git/commit/eaf7a4d2 return { map { utf8::upgrade($_) unless ref($_); $_ } %$args }; } sub _oauth_authenticated_request { my ($self, $http_method, $uri, $args, $authenticate) = @_; delete $args->{source}; # not necessary with OAuth requests my $content_type = delete $args->{-content_type} || ''; my $is_multipart = $content_type eq 'form-data' || grep { ref } %$args; my $msg; if ( $authenticate && $self->authorized ) { local $Net::OAuth::SKIP_UTF8_DOUBLE_ENCODE_CHECK = 1; my $request = $self->_make_oauth_request( 'protected resource', request_url => $uri, request_method => $http_method, token => $self->access_token, token_secret => $self->access_token_secret, extra_params => $is_multipart ? {} : $args, ); if ( $http_method =~ /^(?:GET|DELETE)$/ ) { $msg = HTTP::Request->new($http_method, $request->to_url); } elsif ( $http_method eq 'POST' ) { $msg = $is_multipart ? POST($request->request_url, Authorization => $request->to_authorization_header, Content_Type => 'form-data', Content => [ %$args ], ) : POST($$uri, Content => $request->to_post_body) ; } else { croak "unexpected http_method: $http_method"; } } elsif ( $http_method eq 'GET' ) { $uri->query_form($args); $args = {}; $msg = GET($uri); } elsif ( $http_method eq 'POST' ) { my $encoded_args = { %$args }; _encode_args($encoded_args); $msg = $self->_mk_post_msg($uri, $args); } else { croak "unexpected http_method: $http_method"; } return $self->{ua}->request($msg); } sub _basic_authenticated_request { my ($self, $http_method, $uri, $args, $authenticate) = @_; _encode_args($args); my $msg; if ( $http_method =~ /^(?:GET|DELETE)$/ ) { $uri->query_form($args); $msg = HTTP::Request->new($http_method, $uri); } elsif ( $http_method eq 'POST' ) { $msg = $self->_mk_post_msg($uri, $args); } else { croak "unexpected HTTP method: $http_method"; } if ( $authenticate && $self->{username} && $self->{password} ) { $msg->headers->authorization_basic(@{$self}{qw/username password/}); } return $self->{ua}->request($msg); } sub _mk_post_msg { my ($self, $uri, $args) = @_; if ( grep { ref } values %$args ) { # if any of the arguments are (array) refs, use form-data return POST($uri, Content_Type => 'form-data', Content => [ %$args ]); } else { # There seems to be a bug introduced by Twitter about 2013-02-25: If # post arguments are uri encoded exactly the same way the OAuth spec # requires base signature string encoding, Twitter chokes and throws a # 401. This seems to be a violation of the OAuth spec on Twitter's # part. The specifically states the more stringent URI encoding is for # consistent signature generation and *only* applies to encoding the # base signature string and Authorization header. my @pairs; while ( my ($k, $v) = each %$args ) { push @pairs, join '=', map URI::Escape::uri_escape_utf8($_, '^A-Za-z0-9\-\._~'), $k, $v; } my $content = join '&', @pairs; return POST($uri, Content => $content); } } sub build_api_methods { my $class = shift; my $api_def_module = $class->twitter_api_def_from; eval "require $api_def_module" or die $@; my $api_def = $api_def_module->api_def; my $with_url_arg = sub { my ($path, $args) = @_; if ( defined(my $id = delete $args->{id}) ) { $path .= uri_escape($id); } else { chop($path); } return $path; }; while ( @$api_def ) { my $api = shift @$api_def; my $api_name = shift @$api; my $methods = shift @$api; for my $method ( @$methods ) { my $name = shift @$method; my %options = %{ shift @$method }; my ($arg_names, $path) = @options{qw/required path/}; $arg_names = $options{params} if @$arg_names == 0 && @{$options{params}} == 1; my $modify_path = $path =~ s,/id$,/, ? $with_url_arg : sub { $_[0] }; my $code = sub { my $self = shift; # copy callers args since we may add ->{source} my $args = ref $_[-1] eq 'HASH' ? { %{pop @_} } : {}; if ( my $content_type = $options{content_type} ) { $args->{-content_type} = $options{content_type}; } if ( (my $legacy_method = $self->can("legacy_$name")) && ( exists $$args{-legacy_lists_api} ? delete $$args{-legacy_lists_api} : $self->{legacy_lists_api} ) ) { return $self->$legacy_method(@_, $args); } # just in case it's included where it shouldn't be: delete $args->{-legacy_lists_api}; croak sprintf "$name expected %d args", scalar @$arg_names if @_ > @$arg_names; # promote positional args to named args for ( my $i = 0; @_; ++$i ) { my $param = $arg_names->[$i]; croak "duplicate param $param: both positional and named" if exists $args->{$param}; $args->{$param} = shift; } $args->{source} ||= $self->{source} if $options{add_source}; my $authenticate = exists $args->{authenticate} ? delete $args->{authenticate} : $options{authenticate}; # promote boolean parameters for my $boolean_arg ( @{ $options{booleans} } ) { if ( exists $args->{$boolean_arg} ) { next if $args->{$boolean_arg} =~ /^true|false$/; $args->{$boolean_arg} = $args->{$boolean_arg} ? 'true' : 'false'; } } # Workaround Twitter bug: any value passed for skip_user is treated as true. # The only way to get 'false' is to not pass the skip_user at all. delete $args->{skip_user} if exists $args->{skip_user} && $args->{skip_user} eq 'false'; # replace placeholder arguments my $local_path = $path; # remove optional trailing id $local_path =~ s,/:id$,, unless exists $args->{id}; $local_path =~ s/:(\w+)/delete $args->{$1} or croak "required arg '$1' missing"/eg; # stringify lists for ( qw/screen_name user_id/ ) { $args->{$_} = join(',' => @{ $args->{$_} }) if ref $args->{$_} eq 'ARRAY'; } my $uri = URI->new($self->{$options{base_url_method}} . "/$local_path.json"); return $self->_parse_result( $self->_authenticated_request( $options{method}, $uri, $args, $authenticate ) ); }; no strict 'refs'; $name = $_, *{"$class\::$_"} = $code for $name, @{$options{aliases}}; } } # catch expected error and promote it to an undef for ( qw/list_members is_list_member list_subscribers is_list_subscriber legacy_list_members legacy_is_list_member legacy_list_subscribers legacy_is_list_subscriber/ ) { my $orig = $class->can($_) or next; my $code = sub { my $r = eval { $orig->(@_) }; if ( $@ ) { return if $@ =~ /The specified user is not a (?:memb|subscrib)er of this list/; die $@; } return $r; }; no strict 'refs'; no warnings 'redefine'; *{"$class\::$_"} = $code; } # OAuth token accessors for my $method ( qw/ access_token access_token_secret request_token request_token_secret / ) { no strict 'refs'; *{"$class\::$method"} = sub { my $self = shift; $self->{$method} = shift if @_; return $self->{$method}; }; } # OAuth url accessors for my $method ( qw/ request_token_url authentication_url authorization_url access_token_url xauth_url / ) { no strict 'refs'; *{"$class\::$method"} = sub { my $self = shift; $self->{oauth_urls}{$method} = shift if @_; return URI->new($self->{oauth_urls}{$method}); }; } } sub _from_json { my ($self, $json) = @_; return eval { $json_handler->decode($json) }; } sub _parse_result { my ($self, $res) = @_; # workaround for Laconica API returning bools as strings # (Fixed in Laconi.ca 0.7.4) my $content = $res->content; $content =~ s/^"(true|false)"$/$1/; my $obj = $self->_from_json($content); # Twitter sometimes returns an error with status code 200 if ( $obj && ref $obj eq 'HASH' && exists $obj->{error} ) { die Net::Twitter::Lite::Error->new(twitter_error => $obj, http_response => $res); } if ( $res->is_success && defined $obj ) { if ( $self->{wrap_result} ) { $obj = Net::Twitter::Lite::WrapResult->new($obj, $res); } return $obj; } my $error = Net::Twitter::Lite::Error->new(http_response => $res); $error->twitter_error($obj) if ref $obj; die $error; } 1; Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite.pod000644 000766 000024 00000200606 13021411233 021364 0ustar00marcstaff000000 000000 =head1 NAME Net::Twitter::Lite - A perl interface to the Twitter API =head1 VERSION version 0.12008 =head1 STOP! You probably want L which has support for Twitter API v1.1. If you're using a service with an API compatible with Twitter's deprecated API v1, then you're in the right place. =head1 SYNOPSIS use Net::Twitter::Lite; my $nt = Net::Twitter::Lite->new( username => $user, password => $password legacy_lists_api => 0, ); my $result = eval { $nt->update('Hello, world!') }; eval { my $statuses = $nt->friends_timeline({ since_id => $high_water, count => 100 }); for my $status ( @$statuses ) { print "$status->{created_at} <$status->{user}{screen_name}> $status->{text}\n"; } }; warn "$@\n" if $@; =head1 DESCRIPTION This module provides a perl interface to the Twitter API v1. It uses the same API definitions as L, but without the extra bells and whistles and without the additional dependencies. Same great taste, less filling. This module is related to, but is not part of the C distribution. It's API methods and API method documentation are generated from C's internals. It exists for those who cannot, or prefer not to install L and its dependencies. You should consider upgrading to C for additional functionality, finer grained control over features, backwards compatibility with older versions of C, and additional error handling options. =head1 CLIENT CODE CHANGES REQUIRED =head2 Legacy Lists API Twitter re-implemented the Lists API using new endpoints and semantics. For backwards compatibility, this version of C defaults to the deprecated, legacy endpoints and semantics. It issues a warning if the C option to new is not provided. To enable the new Lists endpoints and semantics, pass C<(legacy_lists_api => 0)> to C. To disable the warning, and keep the backwards compatible endpoints and semantics, pass C<(legacy_lists_api => 1)> to C. The C option to C sets the default for all lists API method calls. You can override the default an each API call by passing a C<-legacy_lists_api> option set to 1 or 0. Support for C option will be removed in a future version and the option to C will be silently ignored. =head2 netrc option The default C changed in version 0.08006. The change should be transparent to client code, unless you're using the C option. If so, you'll need to either update the C<.netrc> entry and change the C value from C to C, or set either the C or C options to C. $nt = Net::Twitter::Lite->new(netrc_machine => 'twitter.com', netrc => 1); # -or- $nt = Net::Twitter::Lite->new(netrc => 'twitter.com'); =head2 OAuth requires callback parameter Beginning with version 0.03, it is necessary for web applications using OAuth authentication to pass the C parameter to C. In the absence of a callback parameter, when the user authorizes the application a PIN number is displayed rather than redirecting the user back to your site. =head1 MIGRATING FROM NET::TWITTER 2.x If you are migrating from Net::Twitter 2.12 (or an earlier version), you may need to make some minor changes to your application code in order to user Net::Twitter::Lite successfully. The primary difference is in error handling. Net::Twitter::Lite throws exceptions on error. It does not support the C, C, and C methods used in Net::Twitter 2.12 and prior versions. Instead of # DON'T! my $friends = $nt->friends(); if ( $friends ) { # process $friends } wrap the API call in an eval block: # DO! my $friends = eval { $nt->friends() }; if ( $friends ) { # process $friends } Here's a much more complex example taken from application code using Net::Twitter 2.12: # DON'T! my $friends = $nt->friends(); if ( $friends ) { # process $friends } else { my $error = $nt->get_error; if ( ref $error ) { if ( ref($error) eq 'HASH' && exists $error->{error} ) { $error = $error->{error}; } else { $error = 'Unexpected error type ' . ref($error); } } else { $error = $nt->http_code() . ": " . $nt->http_message; } warn "$error\n"; } The Net::Twitter::Lite equivalent is: # DO! eval { my $friends = $nt->friends(); # process $friends }; warn "$@\n" if $@; return; In Net::Twitter::Lite, an error can always be treated as a string. See L. The HTTP Status Code and HTTP Message are both available. Rather than accessing them via the Net::Twitter::Lite instance, you access them via the Net::Twitter::Lite::Error instance thrown as an error. For example: # DO! eval { my $friends = $nt->friends(); # process $friends }; if ( my $error = $@ ) { if ( blessed $error && $error->isa("Net::Twitter::Lite::Error) && $error->code() == 502 ) { $error = "Fail Whale!"; } warn "$error\n"; } =head2 Unsupported Net::Twitter 2.12 options to C Net::Twitter::Lite does not support the following Net::Twitter 2.12 options to C. It silently ignores them: =over 4 =item no_fallback If Net::Twitter::Lite is unable to create an instance of the class specified in the C option to C, it dies, rather than falling back to an LWP::UserAgent object. You really don't want a failure to create the C you specified to go unnoticed. =item twittervision Net::Twitter::Lite does not support the TwitterVision API. Use Net::Twitter, instead, if you need it. =item skip_arg_validation Net::Twitter::Lite does not API parameter validation. This is a feature. If Twitter adds a new option to an API method, you can use it immediately by passing it in the HASH ref to the API call. Net::Twitter::Lite relies on Twitter to validate its own parameters. An appropriate exception will be thrown if Twitter reports a parameter error. =item die_on_validation See L. If Twitter returns an bad parameter error, an appropriate exception will be thrown. =item arrayref_on_error This option allowed the following idiom in Net::Twitter 2.12: # DON'T! for my $friend ( @{ $nt->friends() } ) { # process $friend } The equivalent Net::Twitter::Lite code is: # DO! eval { for my $friend ( @{ $nt->friends() } ) { # process $friend } }; =back =head2 Unsupported Net::Twitter 2.12 methods =over 4 =item clone The C method was added to Net::Twitter 2.x to allow safe error handling in an environment where concurrent requests are handled, for example, when using LWP::UserAgent::POE as the C. Since Net::Twitter::Lite throws exceptions instead of stashing them in the Net::Twitter::Lite instance, it is safe in a current request environment, obviating the need for C. =item get_error =item http_code =item http_message These methods are replaced by Net::Twitter::Lite::Error. An instance of that class is thrown errors are encountered. =back =head1 METHODS AND ARGUMENTS =over 4 =item new This constructs a C object. It takes several named parameters, all of them optional: =over 4 =item username This is the screen name or email used to authenticate with Twitter. Use this option for Basic Authentication, only. =item password This is the password used to authenticate with Twitter. Use this option for Basic Authentication, only. =item consumer_key A string containing the OAuth consumer key provided by Twitter when an application is registered. Use this option for OAuth authentication, only. =item consumer_secret A string containing the OAuth consumer secret. Use this option for OAuth authentication, only. the C trait is included. =item oauth_urls A HASH ref of URLs to be used with OAuth authentication. Defaults to: { request_token_url => "http://twitter.com/oauth/request_token", authorization_url => "http://twitter.com/oauth/authorize", access_token_url => "http://twitter.com/oauth/access_token", xauth_url => "https://twitter.com/oauth/access_token", } =item clientname The value for the C HTTP header. It defaults to "Perl Net::Twitter::Lite". =item clientver The value for the C HTTP header. It defaults to current version of the C module. =item clienturl The value for the C HTTP header. It defaults to the search.cpan.org page for the C distribution. =item useragent_class The C compatible class used internally by C. It defaults to "LWP::UserAgent". For L based applications, consider using "LWP::UserAgent::POE". =item useragent_args An HASH ref of arguments to pass to constructor of the class specified with C, above. It defaults to {} (an empty HASH ref). =item useragent The value for C HTTP header. It defaults to "Net::Twitter::Lite/0.11002 (Perl)". =item source The value used in the C parameter of API method calls. It is currently only used in the C method in the REST API. It defaults to "twitterpm". This results in the text "from Net::Twitter" rather than "from web" for status messages posted from C when displayed via the Twitter web interface. The value for this parameter is provided by Twitter when a Twitter application is registered. See L. =item apiurl The URL for the Twitter API. This defaults to "http://twitter.com". =item identica If set to 1 (or any value that evaluates to true), apiurl defaults to "http://identi.ca/api". =item ssl If set to 1, an SSL connection will be used for all API calls. Defaults to 0. =item netrc (Optional) Sets the I key to look up in C<.netrc> to obtain credentials. If set to 1, Net::Twitter::Lite will use the value of the C option (below). # in .netrc machine api.twitter.com login YOUR_TWITTER_USER_NAME password YOUR_TWITTER_PASSWORD machine semifor.twitter.com login semifor password SUPERSECRET # in your perl program $nt = Net::Twitter::Lite->new(netrc => 1); $nt = Net::Twitter::Lite->new(netrc => 'semifor.twitter.com'); =item netrc_machine (Optional) Sets the C entry to look up in C<.netrc> when C< 1>> is used. Defaults to C. =item legacy_lists_api If set to 1, this option enables backwards compatibility by using the now deprecated endpoints and semantics for lists API methods. If set to 0, the new endpoints and semantics will be used. Only the new lists API methods are documented here. If you do not provide this option to C a warning is issued. Support for this option and the legacy lists API methods will be removed in a future version. =item wrap_result (Optional) If set to 1, this option will return an L object, which provides both the Twitter API result and the L object for the API call. See L for details. =back =back =head2 BASIC AUTHENTICATION METHODS =over 4 =item credentials($username, $password) Set the credentials for Basic Authentication. This is helpful for managing multiple accounts. =back =head2 OAUTH METHODS =over 4 =item authorized Whether the client has the necessary credentials to be authorized. Note that the credentials may be wrong and so the request may fail. =item request_access_token Returns list including the access token, access token secret, user_id, and screen_name for this user. Takes a HASH of arguments. The C argument is required. See L. The user must have authorized this app at the url given by C first. For desktop applications, the Twitter authorization page will present the user with a PIN number. Prompt the user for the PIN number, and pass it as the C argument to request_access_token. Returns the access token and access token secret but also sets them internally so that after calling this method, you can immediately call API methods requiring authentication. =item get_authorization_url(callback => $callback_url) Get the URL used to authorize the user. Returns a C object. For web applications, pass your applications callback URL as the C parameter. No arguments are required for desktop applications (C defaults to C, out-of-band). =item get_authentication_url(callback => $callback_url) Get the URL used to authenticate the user with "Sign in with Twitter" authentication flow. Returns a C object. For web applications, pass your applications callback URL as the C parameter. No arguments are required for desktop applications (C defaults to C, out-of-band). =item xauth($username, $password) Exchanges a username and password for OAuth tokens. Your application must be approved for XAuth access by Twitter for this method to work. Twitter does not grant XAuth access for web applications except for a brief period of time to allow them to switch form Basic authentication to OAuth authentication. =item access_token Get or set the access token. =item access_token_secret Get or set the access token secret. =item request_token Get or set the request token. =item request_token_secret Get or set the request token secret. =item access_token_url Get or set the access_token URL. =item authentication_url Get or set the authentication URL. =item authorization_url Get or set the authorization URL. =item request_token_url Get or set the request_token URL. =item xauth_url Get or set the XAuth access token request URL. =back =head1 API METHODS AND ARGUMENTS Most Twitter API methods take parameters. All Net::Twitter::Lite API methods will accept a HASH ref of named parameters as specified in the Twitter API documentation. For convenience, many Net::Twitter::Lite methods accept simple positional arguments as documented, below. The positional parameter passing style is optional; you can always use the named parameters in a hash ref if you prefer. For example, the REST API method C has one required parameter, C. You can call C with a HASH ref argument: $nt->update({ status => 'Hello world!' }); Or, you can use the convenient form: $nt->update('Hello world!'); The C method also has an optional parameter, C. To use it, you B use the HASH ref form: $nt->update({ status => 'Hello world!', in_reply_to_status_id => $reply_to }); Convenience form is provided for the required parameters of all API methods. So, these two calls are equivalent: $nt->friendship_exists({ user_a => $fred, user_b => $barney }); $nt->friendship_exists($fred, $barney); Many API methods have aliases. You can use the API method name, or any of its aliases, as you prefer. For example, these calls are all equivalent: $nt->friendship_exists($fred, $barney); $nt->relationship_exists($fred, $barney); $nt->follows($fred, $barney); Aliases support both the HASH ref and convenient forms: $nt->follows({ user_a => $fred, user_b => $barney }); Methods that support the C parameter expect page numbers E 0. Twitter silently ignores invalid C values. So C<< { page => 0 } >> produces the same result as C<< { page => 1 } >>. In addition to the arguments specified for each API method described below, an additional C parameter can be passed. To request an C header, pass C<< authenticated => 1 >>; to suppress an authentication header, pass C<< authentication => 0 >>. Even if requested, an Authorization header will not be added if there are no user credentials (username and password for Basic Authentication; access tokens for OAuth). This is probably only useful for the L method in the REST API, since it returns different values for an authenticated and a non-authenticated call. =head1 REST API Methods Several of these methods accept a user ID as the C parameter. The user ID can be either a screen name, or the users numeric ID. To disambiguate, use the C or C parameters, instead. For example, These calls are equivalent: $nt->create_friend('perl_api'); # screen name $nt->create_friend(1564061); # numeric ID $nt->create_friend({ id => 'perl_api' }); $nt->create_friend({ screen_name => 'perl_api' }); $nt->create_friend({ user_id => 1564061 }); However user_id 911 and screen_name 911 are separate Twitter accounts. These calls are NOT equivalent: $nt->create_friend(911); # interpreted as screen name $nt->create_friend({ user_id => 911 }); # screen name: richellis Whenever the C parameter is required and C and C are also parameters, using any one of them satisfies the requirement. =over 4 =item B =over 4 =item Parameters: I =item Required: I =back Returns the current trend, geo and sleep time information for the authenticating user. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the current count of friends, followers, updates (statuses) and favorites of the authenticating user. Returns: HashRef =item B =over 4 =item Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id =item Required: I =back Add a member to a list. The authenticated user must own the list to be able to add members to it. Note that lists can't have more than 500 members. Returns: User =item B =item B =over 4 =item Parameters: name, contained_within, token, lat, long, attribute:street_address, callback =item Required: name, contained_within, token, lat, long =back Creates a new place object at the given latitude and longitude. Before creating a place you need to query C with the latitude, longitude and name of the place you wish to create. The query will return an array of places which are similar to the one you wish to create, and a token. If the place you wish to create isn't in the returned array you can use the token with this method to create a new one. Returns: Place =item B =item alias: all_lists =item alias: list_subscriptions =over 4 =item Parameters: user_id, screen_name, count, cursor =item Required: I =back Returns all lists the authenticating or specified user subscribes to, including their own. The user is specified using the user_id or screen_name parameters. If no user is given, the authenticating user is used. Returns: ArrayRef[List] =item B =item B =over 4 =item Parameters: id, user_id, screen_name, include_entities =item Required: id =back Returns if the authenticating user is blocking a target user. Will return the blocked user's object if a block exists, and error with HTTP 404 response code otherwise. Returns: BasicUser =item B =over 4 =item Parameters: page, include_entities =item Required: I =back Returns an array of user objects that the authenticating user is blocking. Returns: ArrayRef[BasicUser] =item B =over 4 =item Parameters: I =item Required: I =back Returns an array of numeric user ids the authenticating user is blocking. Returns: ArrayRef[Int] =item B =over 4 =item Parameters: user_id, screen_name, include_entities, skip_satus =item Required: I =back Returns an array of users that the specified user can contribute to. Returns: ArrayRef[User] =item B =over 4 =item Parameters: user_id, screen_name, include_entities, skip_satus =item Required: I =back Returns an array of users who can contribute to the specified account. Returns: ArrayRef[User] =item B =item B =over 4 =item Parameters: id, user_id, screen_name, include_entities =item Required: id =back Blocks the user specified in the ID parameter as the authenticating user. Returns the blocked user when successful. You can find out more about blocking in the Twitter Support Knowledge Base. Returns: BasicUser =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Favorites the status specified in the ID parameter as the authenticating user. Returns the favorite status when successful. Returns: Status =item B =item B =item alias: follow_new =over 4 =item Parameters: id, user_id, screen_name, follow, include_entities =item Required: id =back Befriends the user specified in the ID parameter as the authenticating user. Returns the befriended user when successful. Returns a string describing the failure condition when unsuccessful. Returns: BasicUser =item B =over 4 =item Parameters: list_id, slug, name, mode, description, owner_screen_name, owner_id =item Required: I =back Creates a new list for the authenticated user. Note that you can't create more than 20 lists per account. Returns: List =item B =item B =over 4 =item Parameters: query =item Required: query =back Creates a saved search for the authenticated user. Returns: SavedSearch =item B =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug =item Required: I =back Deletes the specified list. The authenticated user must own the list to be able to destroy it. Returns: List =item B =item alias: remove_list_member =over 4 =item Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id =item Required: I =back Removes the specified member from the list. The authenticated user must be the list's owner to remove members from the list. Returns: User =item B =item B =over 4 =item Parameters: id, user_id, screen_name =item Required: id =back Un-blocks the user specified in the ID parameter as the authenticating user. Returns the un-blocked user when successful. Returns: BasicUser =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Destroys the direct message specified in the required ID parameter. The authenticating user must be the recipient of the specified direct message. Returns: DirectMessage =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Un-favorites the status specified in the ID parameter as the authenticating user. Returns the un-favorited status. Returns: Status =item B =item B =item alias: unfollow =over 4 =item Parameters: id, user_id, screen_name, include_entities =item Required: id =back Discontinues friendship with the user specified in the ID parameter as the authenticating user. Returns the un-friended user when successful. Returns a string describing the failure condition when unsuccessful. Returns: BasicUser =item B =item B =over 4 =item Parameters: id =item Required: id =back Destroys a saved search. The search, specified by C, must be owned by the authenticating user. Returns: SavedSearch =item B =item B =over 4 =item Parameters: id, trim_user, include_entities =item Required: id =back Destroys the status specified by the required ID parameter. The authenticating user must be the author of the specified status. Returns: Status =item B =item B =over 4 =item Parameters: since_id, max_id, count, page, include_entities =item Required: include_entities =back Returns a list of the 20 most recent direct messages sent to the authenticating user including detailed information about the sending and recipient users. Returns: ArrayRef[DirectMessage] =item B =item B =over 4 =item Parameters: id, screen_name, include_entities =item Required: id =back Disables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful. Returns: BasicUser =item B =item B =over 4 =item Parameters: id, screen_name, include_entities =item Required: id =back Enables notifications for updates from the specified user to the authenticating user. Returns the specified user when successful. Returns: BasicUser =item B =over 4 =item Parameters: I =item Required: I =back Ends the session of the authenticating user, returning a null cookie. Use this method to sign users out of client-facing applications like widgets. Returns: Error =item B =over 4 =item Parameters: id, page, include_entities =item Required: I =back Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: id, user_id, screen_name, cursor =item Required: id =back Returns a reference to an array of numeric IDs for every user following the specified user. The order of the IDs may change from call to call. To obtain the screen names, pass the arrayref to L. Use the optional C parameter to retrieve IDs in pages of 5000. When the C parameter is used, the return value is a reference to a hash with keys C, C, and C. The value of C is a reference to an array of IDS of the user's followers. Set the optional C parameter to -1 to get the first page of IDs. Set it to the prior return's value of C or C to page forward or backwards. When there are no prior pages, the value of C will be 0. When there are no subsequent pages, the value of C will be 0. Returns: HashRef|ArrayRef[Int] =item B =item B =item alias: following_ids =over 4 =item Parameters: id, user_id, screen_name, cursor =item Required: id =back Returns a reference to an array of numeric IDs for every user followed by the specified user. The order of the IDs is reverse chronological. Use the optional C parameter to retrieve IDs in pages of 5000. When the C parameter is used, the return value is a reference to a hash with keys C, C, and C. The value of C is a reference to an array of IDS of the user's friends. Set the optional C parameter to -1 to get the first page of IDs. Set it to the prior return's value of C or C to page forward or backwards. When there are no prior pages, the value of C will be 0. When there are no subsequent pages, the value of C will be 0. Returns: HashRef|ArrayRef[Int] =item B =item B =item alias: relationship_exists =item alias: follows =over 4 =item Parameters: user_id_a, user_id_b, screen_name_a, screen_name_b, user_a, user_b =item Required: user_a, user_b =back Tests for the existence of friendship between two users. Will return true if user_a follows user_b, otherwise will return false. Use of C and C is deprecated. It has been preserved for backwards compatibility, and is used for the two-argument positional form: $nt->friendship_exists($user_a, $user_b); Instead, you should use one of the named argument forms: $nt->friendship_exists({ user_id_a => $id1, user_id_b => $id2 }); $nt->friendship_exists({ screen_name_a => $name1, screen_name_b => $name2 }); Consider using C instead. Returns: Bool =item B =item B =over 4 =item Parameters: cursor =item Required: cursor =back Returns an HASH ref with an array of numeric IDs in the C element for every user who has a pending request to follow the authenticating user. Returns: HashRef =item B =item B =over 4 =item Parameters: cursor =item Required: cursor =back Returns an HASH ref with an array of numeric IDs in the C element for every protected user for whom the authenticating user has a pending follow request. Returns: HashRef =item B =item B =over 4 =item Parameters: id =item Required: id =back Returns details of a place returned from the C method. Returns: HashRef =item B =over 4 =item Parameters: lat, long, query, ip, granularity, accuracy, max_results, contained_within, attribute:street_address, callback =item Required: I =back Search for places that can be attached to a statuses/update. Given a latitude and a longitude pair, an IP address, or a name, this request will return a list of all the valid places that can be used as the place_id when updating a status. Conceptually, a query can be made from the user's location, retrieve a list of places, have the user validate the location he or she is at, and then send the ID of this location with a call to statuses/update. This is the recommended method to use find places that can be attached to statuses/update. Unlike geo/reverse_geocode which provides raw data access, this endpoint can potentially re-order places with regards to the user who is authenticated. This approach is also preferred for interactive place matching with the user. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the current configuration used by Twitter including twitter.com slugs which are not usernames, maximum photo resolutions, and t.co URL lengths. It is recommended applications request this endpoint when they are loaded, but no more than once a day. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the list of languages supported by Twitter along with their ISO 639-1 code. The ISO 639-1 code is the two letter value to use if you include lang with any of your requests. Returns: ArrayRef[Lanugage] =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id =item Required: I =back Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. Returns: List =item B =item alias: list_lists =over 4 =item Parameters: user_id, screen_name, cursor =item Required: I =back Returns the lists of the specified (or authenticated) user. Private lists will be included if the authenticated user is the same as the user whose lists are being returned. Returns: Hashref =item B =over 4 =item Parameters: I =item Required: I =back Returns Twitter's privacy policy. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the Twitter Terms of Service. These are not the same as the Developer Rules of the Road. Returns: HashRef =item B =over 4 =item Parameters: since_id, max_id, count, page, skip_user, exclude_replies, contributor_details, include_rts, include_entities, trim_user, include_my_retweet =item Required: I =back Returns the 20 most recent statuses, including retweets, posted by the authenticating user and that user's friends. This is the equivalent of /timeline/home on the Web. Returns: ArrayRef[Status] =item B =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug, user_id, screen_name, include_entities, skip_status =item Required: I =back Check if the specified user is a member of the specified list. Returns the user or undef. Returns: Maybe[User] =item B =item alias: is_subscribed_list =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug, user_id, screen_name, include_entities, skip_status =item Required: I =back Check if the specified user is a subscriber of the specified list. Returns the user or undef. Returns: Maybe[User] =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id, cursor, include_entities, skip_status =item Required: I =back Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. Returns: Hashref =item B =over 4 =item Parameters: user_id, screen_name, cursor, filter_to_owned_lists =item Required: I =back Returns the lists the specified user has been added to. If user_id or screen_name are not provided the memberships for the authenticating user are returned. Returns: Hashref =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id, since_id, max_id, per_page, page, include_entities, include_rts =item Required: I =back Returns tweet timeline for members of the specified list. Historically, retweets were not available in list timeline responses but you can now use the include_rts=true parameter to additionally receive retweet objects. Returns: ArrayRef[Status] =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id, cursor, include_entities, skip_status =item Required: I =back Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. Returns: Hashref =item B =over 4 =item Parameters: user_id, screen_name =item Required: I =back Returns the relationship of the authenticating user to the comma separated list or ARRAY ref of up to 100 screen_names or user_ids provided. Values for connections can be: following, following_requested, followed_by, none. Requires authentication. Returns: ArrayRef =item B =over 4 =item Parameters: user_id, screen_name, include_entities =item Required: I =back Return up to 100 users worth of extended information, specified by either ID, screen name, or combination of the two. The author's most recent status (if the authenticating user has permission) will be returned inline. This method is rate limited to 1000 calls per hour. This method will accept user IDs or screen names as either a comma delimited string, or as an ARRAY ref. It will also accept arguments in the normal HASHREF form or as a simple list of named arguments. I.e., any of the following forms are acceptable: $nt->lookup_users({ user_id => '1234,6543,3333' }); $nt->lookup_users(user_id => '1234,6543,3333'); $nt->lookup_users({ user_id => [ 1234, 6543, 3333 ] }); $nt->lookup_users({ screen_name => 'fred,barney,wilma' }); $nt->lookup_users(screen_name => ['fred', 'barney', 'wilma']); $nt->lookup_users( screen_name => ['fred', 'barney' ], user_id => '4321,6789', ); Returns: ArrayRef[User] =item B =item alias: add_list_members =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id =item Required: I =back Adds multiple members to a list, by specifying a reference to an array or a comma-separated list of member ids or screen names. The authenticated user must own the list to be able to add members to it. Note that lists can't have more than 500 members, and you are limited to adding up to 100 members to a list at a time with this method. Returns: List =item B =item alias: remove_list_members =over 4 =item Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id =item Required: I =back Removes multiple members from a list, by specifying a reference to an array of member ids or screen names, or a string of comma separated user ids or screen names. The authenticated user must own the list to be able to remove members from it. Note that lists can't have more than 500 members, and you are limited to removing up to 100 members to a list at a time with this method. Please note that there can be issues with lists that rapidly remove and add memberships. Take care when using these methods such that you are not too rapidly switching between removals and adds on the same list. Returns: List =item B =item alias: replies =over 4 =item Parameters: since_id, max_id, count, page, trim_user, include_rts, include_entities =item Required: I =back Returns the 20 most recent mentions (statuses containing @username) for the authenticating user. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: user, text, screen_name, user_id, include_entities =item Required: user, text =back Sends a new direct message to the specified user from the authenticating user. Requires both the user and text parameters. Returns the sent message when successful. In order to support numeric screen names, the C or C parameters may be used instead of C. Returns: DirectMessage =item B =over 4 =item Parameters: I =item Required: I =back Returns an ARRAY ref of user IDs for which the authenticating user does not want to receive retweets. Returns: ArrayRef[UserIDs] =item B =over 4 =item Parameters: skip_user, trim_user, include_entities =item Required: I =back Returns the 20 most recent statuses from non-protected users who have set a custom user icon. Does not require authentication. Note that the public timeline is cached for 60 seconds so requesting it more often than that is a waste of resources. If user credentials are provided, C calls are authenticated, so they count against the authenticated user's rate limit. Use C<< ->public_timeline({ authenticate => 0 }) >> to make an unauthenticated call which will count against the calling IP address' rate limit, instead. Returns: ArrayRef[Status] =item B =over 4 =item Parameters: I =item Required: I =back Returns the remaining number of API requests available to the authenticated user before the API limit is reached for the current hour. Use C<< ->rate_limit_status({ authenticate => 0 }) >> to force an unauthenticated call, which will return the status for the IP address rather than the authenticated user. (Note: for a web application, this is the server's IP address.) Returns: RateLimitStatus =item B =item B =over 4 =item Parameters: id =item Required: id =back If available, returns an array of replies and mentions related to the specified status. There is no guarantee there will be any replies or mentions in the response. This method is only available to users who have access to #newtwitter. Requires authentication. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: id, user_id, screen_name, include_entities =item Required: id =back The user specified in the id is blocked by the authenticated user and reported as a spammer. Returns: User =item B =item B =over 4 =item Parameters: id, include_entities, trim_user =item Required: id =back Retweets a tweet. Requires the id parameter of the tweet you are retweeting. Returns the original tweet with retweet details embedded. Returns: Status =item B =item B =over 4 =item Parameters: id, count, page, trim_user, include_entities =item Required: id =back Returns up to 100 users who retweeted the status identified by C. Returns: ArrayRef[User] =item B =item B =over 4 =item Parameters: id, count, page, trim_user, include_entities =item Required: id =back Returns the IDs of up to 100 users who retweeted the status identified by C. Returns: ArrayRef[User] =item B =over 4 =item Parameters: since_id, max_id, count, page, trim_user, include_entities =item Required: I =back Returns the 20 most recent retweets posted by the authenticating user. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: id, user_id, screen_name =item Required: id =back Returns the 20 most recent retweets posted by the specified user. The user is specified using the user_id or screen_name parameters. This method is identical to C except you can choose the user to view. Does not require authentication, unless the user is protected. Returns: ArrayRef =item B =over 4 =item Parameters: since_id, max_id, count, page =item Required: I =back Returns the 20 most recent retweets posted by the authenticating user's friends. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: id, user_id, screen_name =item Required: id =back Returns the 20 most recent retweets posted by users the specified user follows. The user is specified using the user_id or screen_name parameters. This method is identical to C except you can choose the user to view. Does not require authentication, unless the user is protected. Returns: ArrayRef =item B =item B =over 4 =item Parameters: id, count, trim_user, include_entities =item Required: id =back Returns up to 100 of the first retweets of a given tweet. Returns: Arrayref[Status] =item B =item alias: retweeted_of_me =over 4 =item Parameters: since_id, max_id, count, page, trim_user, include_entities =item Required: I =back Returns the 20 most recent tweets of the authenticated user that have been retweeted by others. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: lat, long, accuracy, granularity, max_results =item Required: lat, long =back Search for places (cities and neighborhoods) that can be attached to a statuses/update. Given a latitude and a longitude, return a list of all the valid places that can be used as a place_id when updating a status. Conceptually, a query can be made from the user's location, retrieve a list of places, have the user validate the location he or she is at, and then send the ID of this location up with a call to statuses/update. There are multiple granularities of places that can be returned -- "neighborhoods", "cities", etc. At this time, only United States data is available through this method. =over 4 =item lat Required. The latitude to query about. Valid ranges are -90.0 to +90.0 (North is positive) inclusive. =item long Required. The longitude to query about. Valid ranges are -180.0 to +180.0 (East is positive) inclusive. =item accuracy Optional. A hint on the "region" in which to search. If a number, then this is a radius in meters, but it can also take a string that is suffixed with ft to specify feet. If this is not passed in, then it is assumed to be 0m. If coming from a device, in practice, this value is whatever accuracy the device has measuring its location (whether it be coming from a GPS, WiFi triangulation, etc.). =item granularity Optional. The minimal granularity of data to return. If this is not passed in, then C is assumed. C can also be passed. =item max_results Optional. A hint as to the number of results to return. This does not guarantee that the number of results returned will equal max_results, but instead informs how many "nearby" results to return. Ideally, only pass in the number of places you intend to display to the user here. =back Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the authenticated user's saved search queries. Returns: ArrayRef[SavedSearch] =item B =over 4 =item Parameters: since_id, max_id, page, count, include_entities =item Required: I =back Returns a list of the 20 most recent direct messages sent by the authenticating user including detailed information about the sending and recipient users. Returns: ArrayRef[DirectMessage] =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Returns a single direct message, specified by an id parameter. Like the C request, this method will include the user objects of the sender and recipient. Requires authentication. Returns: HashRef =item B =item B =item alias: show_relationship =over 4 =item Parameters: source_id, source_screen_name, target_id, target_id_name =item Required: id =back Returns detailed information about the relationship between two users. Returns: Relationship =item B =item B =over 4 =item Parameters: id =item Required: id =back Retrieve the data for a saved search, by C, owned by the authenticating user. Returns: SavedSearch =item B =item B =over 4 =item Parameters: id, trim_user, include_entities =item Required: id =back Returns a single status, specified by the id parameter. The status's author will be returned inline. Returns: Status =item B =item B =over 4 =item Parameters: id, screen_name, include_entities =item Required: id =back Returns extended information of a given user, specified by ID or screen name as per the required id parameter. This information includes design settings, so third party developers can theme their widgets according to a given user's preferences. You must be properly authenticated to request the page of a protected user. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: lat, long, name, contained_within, attribute:street_address, callback =item Required: lat, long, name =back Locates places near the given coordinates which are similar in name. Conceptually you would use this method to get a list of known places to choose from first. Then, if the desired place doesn't exist, make a request to C to create a new one. The token contained in the response is the token needed to be able to create a new place. Returns: HashRef =item B =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug =item Required: I =back Subscribes the authenticated user to the specified list. Returns: List =item B =over 4 =item Parameters: user_id, screen_name, count, cursor =item Required: I =back Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. Does not include the user's own lists. Returns: ArrayRef[List] =item B =over 4 =item Parameters: I =item Required: I =back Returns the list of suggested user categories. The category slug can be used in the C API method get the users in that category . Does not require authentication. Returns: ArrayRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the string "ok" status code. Returns: Str =item B =over 4 =item Parameters: lat, long =item Required: I =back Returns the locations with trending topic information. The response is an array of "locations" that encode the location's WOEID (a Yahoo! Where On Earth ID L) and some other human-readable information such as a the location's canonical name and country. When the optional C and C parameters are passed, the available trend locations are sorted by distance from that location, nearest to farthest. Use the WOEID returned in the location object to query trends for a specific location. Returns: ArrayRef[Location] =item B =item B =over 4 =item Parameters: exclude =item Required: I =back Returns the current top ten trending topics on Twitter. The response includes the time of the request, the name of each trending topic, and query used on Twitter Search results page for that topic. Returns: HashRef =item B =over 4 =item Parameters: date, exclude =item Required: I =back Returns the top 20 trending topics for each hour in a given day. Returns: HashRef =item B =item B =over 4 =item Parameters: woeid =item Required: woeid =back Returns the top 10 trending topics for a specific location. The response is an array of "trend" objects that encode the name of the trending topic, the query parameter that can be used to search for the topic on Search, and the direct URL that can be issued against Search. This information is cached for five minutes, and therefore users are discouraged from querying these endpoints faster than once every five minutes. Global trends information is also available from this API by using a WOEID of 1. Returns: ArrayRef[Trend] =item B =over 4 =item Parameters: date, exclude =item Required: I =back Returns the top 30 trending topics for each day in a given week. Returns: HashRef =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id =item Required: I =back Unsubscribes the authenticated user from the specified list. Returns: List =item B =item B =over 4 =item Parameters: status, lat, long, place_id, display_coordinates, in_reply_to_status_id, trim_user, include_entities =item Required: status =back Updates the authenticating user's status. Requires the status parameter specified. A status update with text identical to the authenticating user's current status will be ignored. =over 4 =item status Required. The text of your status update. URL encode as necessary. Statuses over 140 characters will cause a 403 error to be returned from the API. =item in_reply_to_status_id Optional. The ID of an existing status that the update is in reply to. o Note: This parameter will be ignored unless the author of the tweet this parameter references is mentioned within the status text. Therefore, you must include @username, where username is the author of the referenced tweet, within the update. =item lat Optional. The location's latitude that this tweet refers to. The valid ranges for latitude is -90.0 to +90.0 (North is positive) inclusive. This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding long parameter with this tweet. =item long Optional. The location's longitude that this tweet refers to. The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding lat parameter with this tweet. =item place_id Optional. The place to attach to this status update. Valid place_ids can be found by querying C. =item display_coordinates Optional. By default, geo-tweets will have their coordinates exposed in the status object (to remain backwards compatible with existing API applications). To turn off the display of the precise latitude and longitude (but keep the contextual location information), pass C 0> on the status update. =back Returns: Status =item B =item B =over 4 =item Parameters: device =item Required: device =back Sets which device Twitter delivers updates to for the authenticating user. Sending none as the device parameter will disable IM or SMS updates. Returns: BasicUser =item B =item B =over 4 =item Parameters: id, user_id, screen_name, device, retweets =item Required: id =back Allows you enable or disable retweets and device notifications from the specified user. All other values are assumed to be false. Requires authentication. Returns: HashRef =item B =over 4 =item Parameters: list_id, slug, name, mode, description, owner_screen_name, owner_id =item Required: I =back Updates the specified list. The authenticated user must own the list to be able to update it. Returns: List =item B =over 4 =item Parameters: name, email, url, location, description, include_entities =item Required: I =back Sets values that users are able to set under the "Account" tab of their settings page. Only the parameters specified will be updated; to only update the "name" attribute, for example, only include that parameter in your request. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: image, use =item Required: image =back Updates the authenticating user's profile background image. The C parameter must be an arrayref with the same interpretation as the C parameter in the C method. The C parameter allows you to specify whether to use the uploaded profile background or not. See that method's documentation for details. Returns: ExtendedUser =item B =over 4 =item Parameters: profile_background_color, profile_text_color, profile_link_color, profile_sidebar_fill_color, profile_sidebar_border_color =item Required: I =back Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com. These values are also returned in the /users/show API method. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: image =item Required: image =back Updates the authenticating user's profile image. The C parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array (C<$file>) is the name of a file to open. The second value (C<$filename>) is the name given to Twitter for the file. If C<$filename> is not provided, the basename portion of C<$file> is used. If C<$mime_type> is not provided, it will be provided automatically using L. C<$raw_image_data> can be provided, rather than opening a file, by passing C as the first array value. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: status, media[], possibly_sensitive, in_reply_to_status_id, lat, long, place_id, display_coordinates =item Required: status, media =back Updates the authenticating user's status and attaches media for upload. The C parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array (C<$file>) is the name of a file to open. The second value (C<$filename>) is the name given to Twitter for the file. If C<$filename> is not provided, the basename portion of C<$file> is used. If C<$mime_type> is not provided, it will be provided automatically using L. C<$raw_image_data> can be provided, rather than opening a file, by passing C as the first array value. The Tweet text will be rewritten to include the media URL(s), which will reduce the number of characters allowed in the Tweet text. If the URL(s) cannot be appended without text truncation, the tweet will be rejected and this method will return an HTTP 403 error. Returns: Status =item B =item B =item alias: follow_suggestions =over 4 =item Parameters: category, lang =item Required: category =back Access the users in a given category of the Twitter suggested user list and return their most recent status if they are not a protected user. Currently supported values for optional parameter C are C, C, C, C, C. Does not require authentication. Returns: ArrayRef =item B =over 4 =item Parameters: id, user_id, screen_name, since_id, max_id, count, page, skip_user, trim_user, include_entities, include_rts =item Required: I =back Returns the 20 most recent statuses posted from the authenticating user. It's also possible to request another user's timeline via the id parameter. This is the equivalent of the Web /archive page for your own user, or the profile page for a third party. Returns: ArrayRef[Status] =item B =item B =item alias: find_people =item alias: search_users =over 4 =item Parameters: q, per_page, page, include_entities =item Required: q =back Run a search for users similar to Find People button on Twitter.com; the same results returned by people search on Twitter.com will be returned by using this API (about being listed in the People Search). It is only possible to retrieve the first 1000 matches from this API. Returns: ArrayRef[Users] =item B =item B =over 4 =item Parameters: include_entities =item Required: I =back Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; returns a 401 status code and an error message if not. Use this method to test if supplied user credentials are valid. Returns: ExtendedUser =back =head1 Search API Methods =over 4 =item B =item B =over 4 =item Parameters: q, callback, lang, locale, rpp, page, since_id, until, geocode, show_user, result_type =item Required: q =back Returns a HASH reference with some meta-data about the query including the C, C, and C. The statuses are returned in C. To iterate over the results, use something similar to: my $r = $nt->search($searh_term); for my $status ( @{$r->{results}} ) { print "$status->{text}\n"; } Returns: HashRef =back =head1 ERROR HANDLING When C encounters a Twitter API error or a network error, it throws a C object. You can catch and process these exceptions by using C blocks and testing $@: eval { my $statuses = $nt->friends_timeline(); # this might die! for my $status ( @$statuses ) { #... } }; if ( $@ ) { # friends_timeline encountered an error if ( blessed $@ && $@->isa('Net::Twitter::Lite::Error' ) { #... use the thrown error obj warn $@->error; } else { # something bad happened! die $@; } } C stringifies to something reasonable, so if you don't need detailed error information, you can simply treat $@ as a string: eval { $nt->update($status) }; if ( $@ ) { warn "update failed because: $@\n"; } =head1 AUTHENTICATION Net::Twitter::Lite currently supports both Basic Authentication and OAuth. The choice of authentication strategies is determined by the options passed to C or the use of the C method. An error will be thrown if options for both strategies are provided. =head2 BASIC AUTHENTICATION To use Basic Authentication, pass the C and C options to C, or call C to set them. When Basic Authentication is used, the C header is set on each authenticated API call. =head2 OAUTH AUTHENTICATION To use OAuth authentication, pass the C and C options to new. L must be installed in order to use OAuth and an error will be thrown if OAuth is attempted without it. Net::Twitter::Lite does not I Net::OAuth::Simple, making OAuth an optional feature. =head2 OAUTH EXAMPLES See the C directory included in this distribution for full working examples using OAuth. Here's how to authorize users as a desktop app mode: use Net::Twitter::Lite; my $nt = Net::Twitter::Lite->new( consumer_key => "YOUR-CONSUMER-KEY", consumer_secret => "YOUR-CONSUMER-SECRET", ); # You'll save the token and secret in cookie, config file or session database my($access_token, $access_token_secret) = restore_tokens(); if ($access_token && $access_token_secret) { $nt->access_token($access_token); $nt->access_token_secret($access_token_secret); } unless ( $nt->authorized ) { # The client is not yet authorized: Do it now print "Authorize this app at ", $nt->get_authorization_url, " and enter the PIN#\n"; my $pin = ; # wait for input chomp $pin; my($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $pin); save_tokens($access_token, $access_token_secret); # if necessary } # Everything's ready In a web application mode, you need to save the oauth_token and oauth_token_secret somewhere when you redirect the user to the OAuth authorization URL. sub twitter_authorize : Local { my($self, $c) = @_; my $nt = Net::Twitter::Lite->new(%param); my $url = $nt->get_authorization_url(callback => $callbackurl); $c->response->cookies->{oauth} = { value => { token => $nt->request_token, token_secret => $nt->request_token_secret, }, }; $c->response->redirect($url); } And when the user returns back, you'll reset those request token and secret to upgrade the request token to access token. sub twitter_auth_callback : Local { my($self, $c) = @_; my %cookie = $c->request->cookies->{oauth}->value; my $nt = Net::Twitter::Lite->new(%param); $nt->request_token($cookie{token}); $nt->request_token_secret($cookie{token_secret}); my $verifier = $c->req->param->{oauth_verifier}; my($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $verifier); # Save $access_token and $access_token_secret in the database associated with $c->user } Later on, you can retrieve and reset those access token and secret before calling any Twitter API methods. sub make_tweet : Local { my($self, $c) = @_; my($access_token, $access_token_secret) = ...; my $nt = Net::Twitter::Lite->new(%param); $nt->access_token($access_token); $nt->access_token_secret($access_token_secret); # Now you can call any Net::Twitter::Lite API methods on $nt my $status = $c->req->param('status'); my $res = $nt->update({ status => $status }); } =head1 SEE ALSO =over 4 =item L With support for Twitter API v1.1 =item L The C exception object. =item L This is the official Twitter API documentation. It describes the methods and their parameters in more detail and may be more current than the documentation provided with this module. =item L This LWP::UserAgent compatible class can be used in L based application along with Net::Twitter::Lite to provide concurrent, non-blocking requests. =back =head1 SUPPORT Please report bugs to C, or through the web interface at L. Join the Net::Twitter IRC channel at L. Follow perl_api: L. Track Net::Twitter::Lite development at L. =head1 AUTHOR Marc Mims =head1 CONTRIBUTORS Chris Page =head1 LICENSE Copyright (c) 2013 Marc Mims This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =for Pod::Coverage build_api_methods twitter_api_def_from =cut Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/API/000755 000766 000024 00000000000 13021411233 021265 5ustar00marcstaff000000 000000 Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/Error.pm000644 000766 000024 00000006455 13021411233 022315 0ustar00marcstaff000000 000000 package Net::Twitter::Lite::Error; $Net::Twitter::Lite::Error::VERSION = '0.12008'; use warnings; use strict; use overload '""' => \&error, 'fallback' => 1; # This is basically a duplicate of Net::Twitter::Lite::Error, only without Moose. I # considered creating a new Net-Twitter-Error distribution so that it could be # shared by both Net::Twitter and Net::Twitter::Lite. But there's a strong # argument for making Net::Twitter::Lite depend upon as few modules as # possible. =head1 NAME Net::Twitter::Lite::Error - Encapsulates errors thrown by Net::Twitter::Lite =head1 VERSION version 0.12008 =head1 SYNOPSIS use Net::Twitter::Lite; my $nt = Net::Twitter::Lite->new; my $r = eval { $nt->friends_timeline }; warn "$@\n" if $@; =head1 DESCRIPTION B encapsulates errors thrown by C. A C object will contain an C, and a HASHREF containing Twitter API error information if one was returned by Twitter. =head1 METHODS =over 4 =cut =item new Constructs an C object with an HTTP::Response and optionally a Twitter error HASH ref. It takes HASH of arguments. Examples: my $e = Net::Twitter::Lite::Error->new(http_response => $res, twitter_error => $te); my $e = Net::Twitter::Lite::Error->new(http_response => $res); =cut sub new { my ($class, %args) = @_; return bless \%args, $class; } =item twitter_error Get or set the encapsulated Twitter API error HASH ref. =cut sub twitter_error { my $self = shift; $self->{twitter_error} = shift if @_; return $self->{twitter_error}; } =item http_response Get or set the encapsulated HTTP::Response instance. =cut sub http_response { my $self = shift; $self->{http_response} = shift if @_; return $self->{http_response}; } =item code Returns the HTTP Status Code from the encapsulated HTTP::Response =cut sub code { my $self = shift; return exists $self->{http_response} && $self->{http_response}->code; } =item message Returns the HTTP Status Message from the encapsulated HTTP::Response =cut sub message { my $self = shift; return exists $self->{http_response} && $self->{http_response}->message; } =item error Returns an error message as a string. The message be the C element of the encapsulated Twitter API HASH ref, if there is one. Otherwise it will return a string containing the HTTP Status Code and Message. If the C instance does not contain either an HTTP::Response or a Twitter Error HASH ref, or the HTTP::Response has no status code or message, C returns the string '[unknown]'. A Net::Twitter::Lite::Error stringifies to the C message. =cut sub error { my $self = shift; # We MUST stringyfy to something that evaluates to true, or testing $@ will fail! exists $self->{twitter_error} && $self->{twitter_error}{error} || ( exists $self->{http_response} && ($self->code . ": " . $self->message ) ) || '[unknown]'; } 1; __END__ =back =head1 SEE ALSO L =head1 AUTHOR Marc Mims =head1 LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. =cut Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/WithAPIv1_1.pm000644 000766 000024 00000001753 13021411233 023154 0ustar00marcstaff000000 000000 package Net::Twitter::Lite::WithAPIv1_1; $Net::Twitter::Lite::WithAPIv1_1::VERSION = '0.12008'; use warnings; use strict; use parent 'Net::Twitter::Lite'; =head1 NAME Net::Twitter::Lite::WithAPIv1_1 - A perl API library for Twitter's API v1.1 =head1 VERSION version 0.12008 =cut sub twitter_api_def_from () { 'Net::Twitter::Lite::API::V1_1' } sub _default_api_url () { 'http://api.twitter.com/1.1' } sub _default_searchapiurl () { 'http://search.twitter.com' } sub _default_search_trends_api_url () { 'http://api.twitter.com/1.1' } sub _default_lists_api_url () { 'http://api.twitter.com/1.1' } sub new { my $class = shift; my %options = @_; # Twitter now requires SSL connections. Make it the default. unless ( exists $options{ssl} ) { $options{ssl} = 1; } return $class->SUPER::new( legacy_lists_api => 0, upload_url => 'https://upload.twitter.com/1.1', %options ); } 1; Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/WithAPIv1_1.pod000644 000766 000024 00000153147 13021411233 023327 0ustar00marcstaff000000 000000 =head1 NAME Net::Twitter::Lite::WithAPIv1_1 - A perl interface to the Twitter API v1.1 =head1 VERSION version 0.12008 =head1 SYNOPSIS use Net::Twitter::Lite::WithAPIv1_1; use Scalar::Util 'blessed'; my $nt = Net::Twitter::Lite::WithAPIv1_1->new( consumer_key => $consumer_key, consumer_secret => $consumer_secret, access_token => $token, access_token_secret => $token_secret, ); my $result = $nt->update('Hello, world!'); eval { my $statuses = $nt->home_timeline({ since_id => $high_water, count => 100 }); for my $status ( @$statuses ) { print "$status->{created_at} <$status->{user}{screen_name}> $status->{text}\n"; } }; if ( my $err = $@ ) { die $@ unless blessed $err && $err->isa('Net::Twitter::Lite::Error'); warn "HTTP Response Code: ", $err->code, "\n", "HTTP Message......: ", $err->message, "\n", "Twitter error.....: ", $err->error, "\n"; } =head1 DESCRIPTION This module provides a perl interface to the Twitter APIs. See L for a full description of the Twitter APIs. =head1 RETURN VALUES Net::Twitter::Lite decodes the data structures returned by the Twitter API into native perl data structures (HASH references and ARRAY references). The full layout of those data structures are not documented, here. They change often, usually with the addition of new elements, and documenting all of those changes would be a significant challenge. Instead, rely on the online Twitter API documentation and inspection of the returned data. The Twitter API online documentation is located at L. To inspect the data, use L or similar module of your choice. Here's a simple example using Data::Dumper: use Data::Dumper; my $r = $nt->search($search_term); print Dumper $r; For more information on perl data structures, see L, L, and L. =head1 METHODS AND ARGUMENTS =over 4 =item new This constructs a C object. It takes several named parameters, all of them optional: =over 4 =item clientname The value for the C HTTP header. It defaults to "Perl Net::Twitter::Lite::WithAPIv1_1". Note: This option has nothing to do with the "via" application byline. =item clientver The value for the C HTTP header. It defaults to current version of this module. =item clienturl The value for the C HTTP header. It defaults to the search.cpan.org page for the C distribution. =item useragent_class The C compatible class used internally to make HTTP requests. It defaults to "LWP::UserAgent". For L based applications, consider using "LWP::UserAgent::POE". =item useragent_args An HASH ref of arguments to pass to constructor of the class specified with C, above. It defaults to {} (an empty HASH ref). =item useragent The value for C HTTP header. It defaults to "Net::Twitter::Lite::WithAPIv1_1/$VERSION (Perl)", where C<$VERSION> is the current version of this module. =item source Twitter on longer uses the C parameter. Support for it remains in this module for any compatible services that may use it. It was originally used by Twitter to provide an "via" application byline. =item apiurl The URL for the Twitter API. This defaults to "http://api.twitter.com/1.1". This option is available when the C trait is included. =item upload_url Base URL for media uploads. Defaults to "https://upload.twitter.com/1.1". =item apirealm A string containing the Twitter API realm used for Basic Authentication. It defaults to "Twitter API". This option is available when the C trait is included. =item identica If set to 1, C overrides the defaults for C, C, and C to "http://identi.ca/api", "identi.ca:80", and "Laconica API" respectively. It defaults to 0. =item consumer_key A string containing the OAuth consumer key provided by Twitter when an application is registered. This option is available when the C trait is included. =item consumer_secret A string containing the OAuth consumer secret. This option is available when the C trait is included. =item ssl If set to 1, an SSL connection will be used for all API calls. Defaults to 1. =item netrc (Optional) Sets the I key to look up in C<.netrc> to obtain credentials. If set to 1, will use the value of the C option (below). # in .netrc machine api.twitter.com login YOUR_TWITTER_USER_NAME password YOUR_TWITTER_PASSWORD machine semifor.twitter.com login semifor password SUPERSECRET # in your perl program $nt = Net::Twitter::Lite::WithAPIv1_1->new(netrc => 1); $nt = Net::Twitter::Lite::WithAPIv1_1->new(netrc => 'semifor.twitter.com'); =item netrc_machine (Optional) Sets the C entry to look up in C<.netrc> when C< 1>> is used. Defaults to C. =item wrap_result (Optional) If set to 1, this option will return an L object, which provides both the Twitter API result and the L object for the API call. See L for details. =back =item credentials($username, $password) Set the credentials for Basic Authentication. This is helpful for managing multiple accounts. =back =head1 AUTHENTICATION With Twitter API version 1.1, all API calls require OAuth. Other Twitter compatible services, like Identi.ca, accept Basic Authentication. So, this module provides support for both. For OAuth authentication, provide C and C arguments to C. Set C and C for each call, or provide them as arguments to C. For Basic Authentication, provide the C and C options to L or call the L method. In addition to the arguments specified for each API method described below, an additional C parameter can be passed. To request an C header, pass C<< authenticate => 1 >>; to suppress an authentication header, pass C<< authenticate => 0 >>. Even if requested, an Authorization header will not be added if there are no user credentials (username and password for Basic Authentication; access tokens for OAuth). This is probably only useful for non-Twitter sites that use the Twitter API and support unauthenticated calls. =head1 API METHODS AND ARGUMENTS Most Twitter API methods take parameters. All API methods will accept a HASH ref of named parameters as specified in the Twitter API documentation. For convenience, many methods accept simple positional arguments. The positional parameter passing style is optional; you can always use the named parameters in a HASH reference if you prefer. You may pass any number of required parameters as positional parameters. You must pass them in the order specified in the documentation for each method. Optional parameters must be passed as named parameters in a HASH reference. The HASH reference containing the named parameters must be the final parameter to the method call. Any required parameters not passed as positional parameters, must be included in the named parameter HASH reference. For example, the REST API method C has one required parameter, C. You can call C with a HASH ref argument: $nt->update({ status => 'Hello world!' }); Or, you can use the convenient, positional parameter form: $nt->update('Hello world!'); The C method also has an optional parameter, C. To use it, you B use the HASH ref form: $nt->update({ status => 'Hello world!', in_reply_to_status_id => $reply_to }); You may use the convenient positional form for the required C parameter with the optional parameters specified in the named parameter HASH reference: $nt->update('Hello world!', { in_reply_to_status_id => $reply_to }); Convenience form is provided for the required parameters of all API methods. So, these two calls are equivalent: $nt->friendship_exists({ user_a => $fred, user_b => $barney }); $nt->friendship_exists($fred, $barney); Many API methods have aliases. You can use the API method name, or any of its aliases, as you prefer. For example, these calls are all equivalent: $nt->friendship_exists($fred, $barney); $nt->relationship_exists($fred, $barney); $nt->follows($fred, $barney); Aliases support both the HASH ref and convenient forms: $nt->follows({ user_a => $fred, user_b => $barney }); =head2 Synthetic Arguments In addition to the arguments described in the Twitter API Documentation for each API method, these additional I arguments are supported. =over 4 =item authenticate When set to 1, an Authorization header for the API call will be provided; when set to 0, it will suppress the Authentication header. This argument overrides the defined authentication behavior for the API method. It is probably only useful for the C method which returns different values for authenticated and unauthenticated calls. See L for more details. =back =head1 API Methods =over 4 =item B =over 4 =item Parameters: I =item Required: I =back Returns the current trend, geo and sleep time information for the authenticating user. Returns: HashRef =item B =over 4 =item Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id =item Required: I =back Add a member to a list. The authenticated user must own the list to be able to add members to it. Note that lists can't have more than 500 members. Returns: User =item B =item B =over 4 =item Parameters: name, contained_within, token, lat, long, attribute:street_address, callback =item Required: name, contained_within, token, lat, long =back Creates a new place object at the given latitude and longitude. Before creating a place you need to query C with the latitude, longitude and name of the place you wish to create. The query will return an array of places which are similar to the one you wish to create, and a token. If the place you wish to create isn't in the returned array you can use the token with this method to create a new one. Returns: Place =item B =item alias: blocks_list =over 4 =item Parameters: cursor, include_entities, skip_status =item Required: I =back Returns an array of user objects that the authenticating user is blocking. Returns: ArrayRef[BasicUser] =item B =item alias: blocks_ids =over 4 =item Parameters: cursor, stringify_ids =item Required: I =back Returns an array of numeric user ids the authenticating user is blocking. Returns: ArrayRef[Int] =item B =over 4 =item Parameters: user_id, screen_name, include_entities, skip_satus =item Required: I =back Returns an array of users that the specified user can contribute to. Returns: ArrayRef[User] =item B =over 4 =item Parameters: user_id, screen_name, include_entities, skip_satus =item Required: I =back Returns an array of users who can contribute to the specified account. Returns: ArrayRef[User] =item B =item B =over 4 =item Parameters: user_id, screen_name, include_entities, skip_status =item Required: id =back Blocks the user specified in the C or C parameter as the authenticating user. Returns the blocked user when successful. You can find out more about blocking in the Twitter Support Knowledge Base. Returns: BasicUser =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Favorites the status specified in the ID parameter as the authenticating user. Returns the favorite status when successful. Returns: Status =item B =item alias: follow =item alias: follow_new =item alias: create_friendship =over 4 =item Parameters: user_id, screen_name, follow =item Required: I =back Follows the user specified in the C or C parameter as the authenticating user. Returns the befriended user when successful. Returns a string describing the failure condition when unsuccessful. Returns: BasicUser =item B =item B =over 4 =item Parameters: list_id, slug, name, mode, description, owner_screen_name, owner_id =item Required: name =back Creates a new list for the authenticated user. Note that you can't create more than 20 lists per account. Returns: List =item B =item B =over 4 =item Parameters: query =item Required: query =back Creates a saved search for the authenticated user. Returns: SavedSearch =item B =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug =item Required: I =back Deletes the specified list. The authenticated user must own the list to be able to destroy it. Returns: List =item B =item alias: remove_list_member =over 4 =item Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id =item Required: I =back Removes the specified member from the list. The authenticated user must be the list's owner to remove members from the list. Returns: User =item B =item B =over 4 =item Parameters: user_id, screen_name, include_entities, skip_status =item Required: id =back Un-blocks the user specified in the C or C parameter as the authenticating user. Returns the un-blocked user when successful. Returns: BasicUser =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Destroys the direct message specified in the required ID parameter. The authenticating user must be the recipient of the specified direct message. Important: this method requires an access token with RWD (read, write, and direct message) permissions. Returns: DirectMessage =item B =item B =over 4 =item Parameters: id, include_entities =item Required: id =back Un-favorites the status specified in the ID parameter as the authenticating user. Returns the un-favorited status. Returns: Status =item B =item B =item alias: unfollow =item alias: destroy_friendship =over 4 =item Parameters: user_id, screen_name =item Required: id =back Discontinues friendship with the user specified in the C or C parameter as the authenticating user. Returns the un-friended user when successful. Returns a string describing the failure condition when unsuccessful. Returns: BasicUser =item B =item B =item alias: delete_saved_search =over 4 =item Parameters: id =item Required: id =back Destroys a saved search. The search, specified by C, must be owned by the authenticating user. Returns: SavedSearch =item B =item B =over 4 =item Parameters: id, trim_user =item Required: id =back Destroys the status specified by the required ID parameter. The authenticating user must be the author of the specified status. Returns: Status =item B =over 4 =item Parameters: since_id, max_id, count, page, include_entities, skip_status =item Required: I =back Returns a list of the 20 most recent direct messages sent to the authenticating user including detailed information about the sending and recipient users. Important: this method requires an access token with RWD (read, write, and direct message) permissions. Returns: ArrayRef[DirectMessage] =item B =over 4 =item Parameters: user_id, screen_name, count, since_id, max_id, include_entities =item Required: I =back Returns the 20 most recent favorite statuses for the authenticating user or user specified by the ID parameter. Returns: ArrayRef[Status] =item B =item alias: followers_list =over 4 =item Parameters: user_id, screen_name, cursor =item Required: I =back Returns a cursored collection of user objects for users following the specified user. Returns: HashRef =item B =over 4 =item Parameters: user_id, screen_name, cursor, stringify_ids =item Required: I =back Returns a reference to an array of numeric IDs for every user following the specified user. The order of the IDs may change from call to call. To obtain the screen names, pass the arrayref to L. Use the optional C parameter to retrieve IDs in pages of 5000. When the C parameter is used, the return value is a reference to a hash with keys C, C, and C. The value of C is a reference to an array of IDS of the user's followers. Set the optional C parameter to -1 to get the first page of IDs. Set it to the prior return's value of C or C to page forward or backwards. When there are no prior pages, the value of C will be 0. When there are no subsequent pages, the value of C will be 0. Returns: HashRef|ArrayRef[Int] =item B =item alias: friends_list =over 4 =item Parameters: user_id, screen_name, cursor =item Required: I =back Returns a cursored collection of user objects for users followed by the specified user. Returns: HashRef =item B =item alias: following_ids =over 4 =item Parameters: user_id, screen_name, cursor, stringify_ids =item Required: I =back Returns a reference to an array of numeric IDs for every user followed by the specified user. The order of the IDs is reverse chronological. Use the optional C parameter to retrieve IDs in pages of 5000. When the C parameter is used, the return value is a reference to a hash with keys C, C, and C. The value of C is a reference to an array of IDS of the user's friends. Set the optional C parameter to -1 to get the first page of IDs. Set it to the prior return's value of C or C to page forward or backwards. When there are no prior pages, the value of C will be 0. When there are no subsequent pages, the value of C will be 0. Returns: HashRef|ArrayRef[Int] =item B =item alias: incoming_friendships =over 4 =item Parameters: cursor, stringify_ids =item Required: I =back Returns an HASH ref with an array of numeric IDs in the C element for every user who has a pending request to follow the authenticating user. Returns: HashRef =item B =item alias: outgoing_friendships =over 4 =item Parameters: cursor, stringify_ids =item Required: I =back Returns an HASH ref with an array of numeric IDs in the C element for every protected user for whom the authenticating user has a pending follow request. Returns: HashRef =item B =item B =over 4 =item Parameters: id =item Required: id =back Returns details of a place returned from the C method. Returns: HashRef =item B =over 4 =item Parameters: lat, long, query, ip, granularity, accuracy, max_results, contained_within, attribute:street_address, callback =item Required: I =back Search for places that can be attached to a statuses/update. Given a latitude and a longitude pair, an IP address, or a name, this request will return a list of all the valid places that can be used as the place_id when updating a status. Conceptually, a query can be made from the user's location, retrieve a list of places, have the user validate the location he or she is at, and then send the ID of this location with a call to statuses/update. This is the recommended method to use find places that can be attached to statuses/update. Unlike geo/reverse_geocode which provides raw data access, this endpoint can potentially re-order places with regards to the user who is authenticated. This approach is also preferred for interactive place matching with the user. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the current configuration used by Twitter including twitter.com slugs which are not usernames, maximum photo resolutions, and t.co URL lengths. It is recommended applications request this endpoint when they are loaded, but no more than once a day. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the list of languages supported by Twitter along with their ISO 639-1 code. The ISO 639-1 code is the two letter value to use if you include lang with any of your requests. Returns: ArrayRef[Lanugage] =item B =item alias: show_list =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id =item Required: I =back Returns the specified list. Private lists will only be shown if the authenticated user owns the specified list. Returns: List =item B =item alias: all_subscriptions =item alias: list_lists all_subscriptions =over 4 =item Parameters: user_id, screen_name reverse =item Required: I =back Returns all lists the authenticating or specified user subscribes to, including their own. The user is specified using the user_id or screen_name parameters. If no user is given, the authenticating user is used. A maximum of 100 results will be returned by this call. Subscribed lists are returned first, followed by owned lists. This means that if a user subscribes to 90 lists and owns 20 lists, this method returns 90 subscriptions and 10 owned lists. The reverse method returns owned lists first, so with C 1>, 20 owned lists and 80 subscriptions would be returned. If your goal is to obtain every list a user owns or subscribes to, use and/or C instead. Returns: ArrayRef[Lists] =item B =over 4 =item Parameters: I =item Required: I =back Returns Twitter's privacy policy. Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the Twitter Terms of Service. These are not the same as the Developer Rules of the Road. Returns: HashRef =item B =over 4 =item Parameters: since_id, max_id, count, exclude_replies, contributor_details, include_entities, trim_user =item Required: I =back Returns the 20 most recent statuses, including retweets, posted by the authenticating user and that user's friends. Returns: ArrayRef[Status] =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id, cursor, include_entities, skip_status =item Required: I =back Returns the members of the specified list. Private list members will only be shown if the authenticated user owns the specified list. Returns: Hashref =item B =over 4 =item Parameters: user_id, screen_name, cursor, filter_to_owned_lists =item Required: I =back Returns the lists the specified user has been added to. If user_id or screen_name are not provided the memberships for the authenticating user are returned. Returns: Hashref =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id, since_id, max_id, count, include_entities, include_rts =item Required: I =back Returns tweet timeline for members of the specified list. Historically, retweets were not available in list timeline responses but you can now use the include_rts=true parameter to additionally receive retweet objects. Returns: ArrayRef[Status] =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id, cursor, include_entities, skip_status =item Required: I =back Returns the subscribers of the specified list. Private list subscribers will only be shown if the authenticated user owns the specified list. Returns: Hashref =item B =over 4 =item Parameters: user_id, screen_name =item Required: I =back Returns the relationship of the authenticating user to the comma separated list or ARRAY ref of up to 100 screen_names or user_ids provided. Values for connections can be: following, following_requested, followed_by, none. Requires authentication. Returns: ArrayRef =item B =over 4 =item Parameters: user_id, screen_name, include_entities =item Required: I =back Return up to 100 users worth of extended information, specified by either ID, screen name, or combination of the two. The author's most recent status (if the authenticating user has permission) will be returned inline. This method is rate limited to 1000 calls per hour. This method will accept user IDs or screen names as either a comma delimited string, or as an ARRAY ref. It will also accept arguments in the normal HASHREF form or as a simple list of named arguments. I.e., any of the following forms are acceptable: $nt->lookup_users({ user_id => '1234,6543,3333' }); $nt->lookup_users(user_id => '1234,6543,3333'); $nt->lookup_users({ user_id => [ 1234, 6543, 3333 ] }); $nt->lookup_users({ screen_name => 'fred,barney,wilma' }); $nt->lookup_users(screen_name => ['fred', 'barney', 'wilma']); $nt->lookup_users( screen_name => ['fred', 'barney' ], user_id => '4321,6789', ); Returns: ArrayRef[User] =item B =item alias: add_list_members =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id =item Required: I =back Adds multiple members to a list, by specifying a reference to an array or a comma-separated list of member ids or screen names. The authenticated user must own the list to be able to add members to it. Note that lists can't have more than 500 members, and you are limited to adding up to 100 members to a list at a time with this method. Returns: List =item B =item alias: remove_list_members =over 4 =item Parameters: list_id, slug, user_id, screen_name, owner_screen_name, owner_id =item Required: I =back Removes multiple members from a list, by specifying a reference to an array of member ids or screen names, or a string of comma separated user ids or screen names. The authenticated user must own the list to be able to remove members from it. Note that lists can't have more than 500 members, and you are limited to removing up to 100 members to a list at a time with this method. Please note that there can be issues with lists that rapidly remove and add memberships. Take care when using these methods such that you are not too rapidly switching between removals and adds on the same list. Returns: List =item B =item alias: replies =item alias: mentions_timeline =over 4 =item Parameters: since_id, max_id, count, trim_user, include_entities, contributor_details =item Required: I =back Returns the 20 most recent mentions (statuses containing @username) for the authenticating user. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: user_id, screen_name, text =item Required: text =back Sends a new direct message to the specified user from the authenticating user. Requires both the user and text parameters. Returns the sent message when successful. In order to support numeric screen names, the C or C parameters may be used instead of C. Important: this method requires an access token with RWD (read, write, and direct message) permissions. Returns: DirectMessage =item B =over 4 =item Parameters: I =item Required: I =back Returns an ARRAY ref of user IDs for which the authenticating user does not want to receive retweets. Returns: ArrayRef[UserIDs] =item B =over 4 =item Parameters: id, url, maxwidth, hide_media, hide_thread, omit_script, align, related, lang =item Required: I =back Returns information allowing the creation of an embedded representation of a Tweet on third party sites. See the L specification for information about the response format. While this endpoint allows a bit of customization for the final appearance of the embedded Tweet, be aware that the appearance of the rendered Tweet may change over time to be consistent with Twitter's L. Do not rely on any class or id parameters to stay constant in the returned markup. Returns: Status =item B =over 4 =item Parameters: user_id, screen_name =item Required: I =back Returns a hash reference mapping available size variations to URLs that can be used to retrieve each variation of the banner. Returns: HashRef =item B =item B =over 4 =item Parameters: resources =item Required: I =back Returns the remaining number of API requests available to the authenticated user before the API limit is reached for the current hour. Use C<< ->rate_limit_status({ authenticate => 0 }) >> to force an unauthenticated call, which will return the status for the IP address rather than the authenticated user. (Note: for a web application, this is the server's IP address.) Returns: RateLimitStatus =item B =over 4 =item Parameters: I =item Required: I =back Removes the uploaded profile banner for the authenticating user. Returns: Nothing =item B =item B =over 4 =item Parameters: user_id, screen_name =item Required: id =back The user specified in the id is blocked by the authenticated user and reported as a spammer. Returns: User =item B =item B =over 4 =item Parameters: idtrim_user =item Required: id =back Retweets a tweet. Returns: Status =item B =item B =over 4 =item Parameters: id, count, trim_user =item Required: id =back Returns up to 100 of the first retweets of a given tweet. Returns: Arrayref[Status] =item B =item alias: retweeted_of_me =over 4 =item Parameters: since_id, max_id, count, trim_user, include_entities, include_user_entities =item Required: I =back Returns the 20 most recent tweets of the authenticated user that have been retweeted by others. Returns: ArrayRef[Status] =item B =item B =over 4 =item Parameters: lat, long, accuracy, granularity, max_results, callback =item Required: lat, long =back Search for places (cities and neighborhoods) that can be attached to a statuses/update. Given a latitude and a longitude, return a list of all the valid places that can be used as a place_id when updating a status. Conceptually, a query can be made from the user's location, retrieve a list of places, have the user validate the location he or she is at, and then send the ID of this location up with a call to statuses/update. There are multiple granularities of places that can be returned -- "neighborhoods", "cities", etc. At this time, only United States data is available through this method. =over 4 =item lat Required. The latitude to query about. Valid ranges are -90.0 to +90.0 (North is positive) inclusive. =item long Required. The longitude to query about. Valid ranges are -180.0 to +180.0 (East is positive) inclusive. =item accuracy Optional. A hint on the "region" in which to search. If a number, then this is a radius in meters, but it can also take a string that is suffixed with ft to specify feet. If this is not passed in, then it is assumed to be 0m. If coming from a device, in practice, this value is whatever accuracy the device has measuring its location (whether it be coming from a GPS, WiFi triangulation, etc.). =item granularity Optional. The minimal granularity of data to return. If this is not passed in, then C is assumed. C can also be passed. =item max_results Optional. A hint as to the number of results to return. This does not guarantee that the number of results returned will equal max_results, but instead informs how many "nearby" results to return. Ideally, only pass in the number of places you intend to display to the user here. =back Returns: HashRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the authenticated user's saved search queries. Returns: ArrayRef[SavedSearch] =item B =item B =over 4 =item Parameters: q, count, callback, lang, locale, rpp, since_id, max_id, until, geocode, result_type, include_entities =item Required: q =back Returns a HASH reference with some meta-data about the query including the C, C, and C. The statuses are returned in C. To iterate over the results, use something similar to: my $r = $nt->search($searh_term); for my $status ( @{$r->{statuses}} ) { print "$status->{text}\n"; } Returns: HashRef =item B =item alias: direct_messages_sent =over 4 =item Parameters: since_id, max_id, page, count, include_entities =item Required: I =back Returns a list of the 20 most recent direct messages sent by the authenticating user including detailed information about the sending and recipient users. Important: this method requires an access token with RWD (read, write, and direct message) permissions. Returns: ArrayRef[DirectMessage] =item B =item B =over 4 =item Parameters: id =item Required: id =back Returns a single direct message, specified by an id parameter. Like the C request, this method will include the user objects of the sender and recipient. Requires authentication. Important: this method requires an access token with RWD (read, write, and direct message) permissions. Returns: HashRef =item B =item alias: show_relationship =over 4 =item Parameters: source_id, source_screen_name, target_id, target_screen_name =item Required: I =back Returns detailed information about the relationship between two users. Returns: Relationship =item B =item alias: is_list_member =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug, user_id, screen_name, include_entities, skip_status =item Required: I =back Check if the specified user is a member of the specified list. Returns the user or undef. Returns: Maybe[User] =item B =item alias: is_list_subscriber =item alias: is_subscriber_lists =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug, user_id, screen_name, include_entities, skip_status =item Required: I =back Returns the user if they are a subscriber. Returns: User =item B =item B =over 4 =item Parameters: id =item Required: id =back Retrieve the data for a saved search, by C, owned by the authenticating user. Returns: SavedSearch =item B =item B =over 4 =item Parameters: id, trim_user, include_entities, include_my_retweet =item Required: id =back Returns a single status, specified by the id parameter. The status's author will be returned inline. Returns: Status =item B =over 4 =item Parameters: user_id, screen_name, include_entities =item Required: I =back Returns extended information of a given user, specified by ID or screen name as per the required id parameter. This information includes design settings, so third party developers can theme their widgets according to a given user's preferences. You must be properly authenticated to request the page of a protected user. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: lat, long, name, contained_within, attribute:street_address, callback =item Required: lat, long, name =back Locates places near the given coordinates which are similar in name. Conceptually you would use this method to get a list of known places to choose from first. Then, if the desired place doesn't exist, make a request to C to create a new one. The token contained in the response is the token needed to be able to create a new place. Returns: HashRef =item B =over 4 =item Parameters: owner_screen_name, owner_id, list_id, slug =item Required: I =back Subscribes the authenticated user to the specified list. Returns: List =item B =over 4 =item Parameters: user_id, screen_name, count, cursor =item Required: I =item Aliases: subscriptions =back Obtain a collection of the lists the specified user is subscribed to, 20 lists per page by default. Does not include the user's own lists. Returns: ArrayRef[List] =item B =over 4 =item Parameters: user_id screen_name count cursor =back Obtain a collection of the lists owned by the specified Twitter user. Private lists will only be shown if the authenticated user is also the owner of the lists. Returns: Hashref =item B =over 4 =item Parameters: I =item Required: I =back Returns the list of suggested user categories. The category slug can be used in the C API method get the users in that category . Does not require authentication. Returns: ArrayRef =item B =over 4 =item Parameters: I =item Required: I =back Returns the locations with trending topic information. The response is an array of "locations" that encode the location's WOEID (a Yahoo! Where On Earth ID L) and some other human-readable information such as a the location's canonical name and country. For backwards compatibility, this method accepts optional C and C parameters. You should call C directly, instead. Use the WOEID returned in the location object to query trends for a specific location. Returns: ArrayRef[Location] =item B =over 4 =item Parameters: lat, long =item Required: I =back Returns the locations with trending topic information. The response is an array of "locations" that encode the location's WOEID (a Yahoo! Where On Earth ID L) and some other human-readable information such as a the location's canonical name and country. The results are sorted by distance from that location, nearest to farthest. Use the WOEID returned in the location object to query trends for a specific location. Returns: ArrayRef[Location] =item B =item B =item alias: trends_location =over 4 =item Parameters: id, exclude =item Required: id =back Returns the top 10 trending topics for a specific WOEID. The response is an array of "trend" objects that encode the name of the trending topic, the query parameter that can be used to search for the topic on Search, and the direct URL that can be issued against Search. This information is cached for five minutes, and therefore users are discouraged from querying these endpoints faster than once every five minutes. Global trends information is also available from this API by using a WOEID of 1. Returns: ArrayRef[Trend] =item B =over 4 =item Parameters: list_id, slug, owner_screen_name, owner_id =item Required: I =back Unsubscribes the authenticated user from the specified list. Returns: List =item B =item B =over 4 =item Parameters: status, lat, long, place_id, display_coordinates, in_reply_to_status_id, trim_user =item Required: status =back Updates the authenticating user's status. Requires the status parameter specified. A status update with text identical to the authenticating user's current status will be ignored. =over 4 =item status Required. The text of your status update. URL encode as necessary. Statuses over 140 characters will cause a 403 error to be returned from the API. =item in_reply_to_status_id Optional. The ID of an existing status that the update is in reply to. o Note: This parameter will be ignored unless the author of the tweet this parameter references is mentioned within the status text. Therefore, you must include @username, where username is the author of the referenced tweet, within the update. =item lat Optional. The location's latitude that this tweet refers to. The valid ranges for latitude is -90.0 to +90.0 (North is positive) inclusive. This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding long parameter with this tweet. =item long Optional. The location's longitude that this tweet refers to. The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. This parameter will be ignored if outside that range, if it is not a number, if geo_enabled is disabled, or if there not a corresponding lat parameter with this tweet. =item place_id Optional. The place to attach to this status update. Valid place_ids can be found by querying C. =item display_coordinates Optional. By default, geo-tweets will have their coordinates exposed in the status object (to remain backwards compatible with existing API applications). To turn off the display of the precise latitude and longitude (but keep the contextual location information), pass C 0> on the status update. =back Returns: Status =item B =over 4 =item Parameters: trend_location_woid, sleep_time_enabled, start_sleep_time, end_sleep_time, time_zone, lang =item Required: I =back Updates the authenticating user's settings. Returns: HashRef =item B =item B =over 4 =item Parameters: device, include_entities =item Required: device =back Sets which device Twitter delivers updates to for the authenticating user. Sending none as the device parameter will disable SMS updates. Returns: BasicUser =item B =over 4 =item Parameters: user_id, screen_name, device, retweets =item Required: I =back Allows you enable or disable retweets and device notifications from the specified user. All other values are assumed to be false. Requires authentication. Returns: HashRef =item B =over 4 =item Parameters: list_id, slug, name, mode, description, owner_screen_name, owner_id =item Required: I =back Updates the specified list. The authenticated user must own the list to be able to update it. Returns: List =item B =over 4 =item Parameters: name, url, location, description, include_entities, skip_status =item Required: I =back Sets values that users are able to set under the "Account" tab of their settings page. Only the parameters specified will be updated; to only update the "name" attribute, for example, only include that parameter in your request. Returns: ExtendedUser =item B =over 4 =item Parameters: image, tile, include_entities, skip_status, use =item Required: I =back Updates the authenticating user's profile background image. The C parameter must be an arrayref with the same interpretation as the C parameter in the C method. See that method's documentation for details. The C parameter allows you to specify whether to use the uploaded profile background or not. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: banner, width, height, offset_left, offset_top =item Required: banner =back Uploads a profile banner on behalf of the authenticating user. The C parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array (C<$file>) is the name of a file to open. The second value (C<$filename>) is the name given to Twitter for the file. If C<$filename> is not provided, the basename portion of C<$file> is used. If C<$mime_type> is not provided, it will be provided automatically using L. C<$raw_image_data> can be provided, rather than opening a file, by passing C as the first array value. Returns: Nothing =item B =over 4 =item Parameters: profile_background_color, profile_text_color, profile_link_color, profile_sidebar_fill_color, profile_sidebar_border_color, include_entities, skip_status =item Required: I =back Sets one or more hex values that control the color scheme of the authenticating user's profile page on twitter.com. These values are also returned in the /users/show API method. Returns: ExtendedUser =item B =item B =over 4 =item Parameters: image, include_entities, skip_status =item Required: image =back Updates the authenticating user's profile image. The C parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array (C<$file>) is the name of a file to open. The second value (C<$filename>) is the name given to Twitter for the file. If C<$filename> is not provided, the basename portion of C<$file> is used. If C<$mime_type> is not provided, it will be provided automatically using L. C<$raw_image_data> can be provided, rather than opening a file, by passing C as the first array value. Returns: ExtendedUser =item B =item alias: upload =over 4 =item Parameters: media, media_data, additional_owners =item Required: media or media_data =back The C parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array (C<$file>) is the name of a file to open. The second value (C<$filename>) is the name given to Twitter for the file. If C<$filename> is not provided, the basename portion of C<$file> is used. If C<$mime_type> is not provided, it will be provided automatically using L. C<$raw_image_data> can be provided, rather than opening a file, by passing C as the first array value. Or, pass base64-encoded data with the C parameter. Returns: Hashref with media_id. =item B =item B =item alias: follow_suggestions =over 4 =item Parameters: category, lang =item Required: category =back Access the users in a given category of the Twitter suggested user list and return their most recent status if they are not a protected user. Currently supported values for optional parameter C are C, C, C, C, C. Does not require authentication. Returns: ArrayRef =item B =item B =item alias: follow_suggestions =over 4 =item Parameters: category, lang =item Required: category =back Access the users in a given category of the Twitter suggested user list. Returns: ArrayRef =item B =over 4 =item Parameters: user_id, screen_name, since_id, max_id, count, trim_user, exclude_replies, include_rts, contributor_details =item Required: I =back Returns the 20 most recent statuses posted by the authenticating user, or the user specified by C or C. Returns: ArrayRef[Status] =item B =item B =item alias: find_people =item alias: search_users =over 4 =item Parameters: q, per_page, page, count, include_entities =item Required: q =back Run a search for users similar to Find People button on Twitter.com; the same results returned by people search on Twitter.com will be returned by using this API (about being listed in the People Search). It is only possible to retrieve the first 1000 matches from this API. Returns: ArrayRef[Users] =item B =over 4 =item Parameters: include_entities, skip_status =item Required: I =back Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful; returns a 401 status code and an error message if not. Use this method to test if supplied user credentials are valid. Returns: ExtendedUser =back =over 4 =item B =item B =over 4 =item Parameters: status, media[], possibly_sensitive, in_reply_to_status_id, lat, long, place_id, display_coordinates =item Required: status, media =back Updates the authenticating user's status and attaches media for upload. The C parameter is an arrayref with the following interpretation: [ $file ] [ $file, $filename ] [ $file, $filename, Content_Type => $mime_type ] [ undef, $filename, Content_Type => $mime_type, Content => $raw_image_data ] The first value of the array (C<$file>) is the name of a file to open. The second value (C<$filename>) is the name given to Twitter for the file. If C<$filename> is not provided, the basename portion of C<$file> is used. If C<$mime_type> is not provided, it will be provided automatically using L. C<$raw_image_data> can be provided, rather than opening a file, by passing C as the first array value. The Tweet text will be rewritten to include the media URL(s), which will reduce the number of characters allowed in the Tweet text. If the URL(s) cannot be appended without text truncation, the tweet will be rejected and this method will return an HTTP 403 error. Returns: Status =back =head1 Search API Methods These methods are provided when trait C is included in the C option to C. =over 4 =item B =item B =over 4 =item Parameters: q, callback, lang, locale, rpp, page, since_id, until, geocode, show_user, result_type =item Required: q =back Returns a HASH reference with some meta-data about the query including the C, C, and C. The statuses are returned in C. To iterate over the results, use something similar to: my $r = $nt->search($searh_term); for my $status ( @{$r->{results}} ) { print "$status->{text}\n"; } Returns: HashRef =back =head1 TwitterVision API Methods These methods are provided when trait C is included in the C option to C. =over 4 =item B =item B =over 4 =item Parameters: id, callback =item Required: id =back Get the current location and status of a user. Returns: HashRef =item B =item B =over 4 =item Parameters: location =item Required: location =back Updates the location for the authenticated user. Returns: HashRef =back =head1 ERROR HANDLING When a Twitter API error or a network error is encountered, C object is thrown. You can catch and process these exceptions by using C blocks and testing $@: eval { my $statuses = $nt->friends_timeline(); # this might die! for my $status ( @$statuses ) { #... } }; if ( $@ ) { # friends_timeline encountered an error if ( blessed $@ && $@->isa('Net::Twitter::Lite::Error') ) { #... use the thrown error obj warn $@->error; } else { # something bad happened! die $@; } } C stringifies to something reasonable, so if you don't need detailed error information, you can simply treat $@ as a string: eval { $nt->update($status) }; if ( $@ ) { warn "update failed because: $@\n"; } =head1 SEE ALSO =over 4 =item L The C exception object. =item L This is the official Twitter API documentation. It describes the methods and their parameters in more detail and may be more current than the documentation provided with this module. =item L This LWP::UserAgent compatible class can be used in L based application along with Net::Twitter::Lite to provide concurrent, non-blocking requests. =item L This module, by Jesse Stay, provides Twitter OAuth authentication support for the popular L web application framework. =item L An excellent module for Twitter Streaming API support. =back =head1 SUPPORT Please report bugs at L. Join the #net-twitter IRC channel on irc.perl.org. Follow perl_api: L. Track development at L. =head1 AUTHOR Marc Mims (@semifor on Twitter) =head1 CONTRIBUTORS Marek Foss (@f055) =head1 LICENSE Copyright (c) 2013 Marc Mims This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/WrapResult.pm000644 000766 000024 00000005555 13021411233 023334 0ustar00marcstaff000000 000000 package Net::Twitter::Lite::WrapResult; $Net::Twitter::Lite::WrapResult::VERSION = '0.12008'; use strict; =head1 NAME Net::Twitter::Lite::WrapResult - Wrap the HTTP response and Twitter result =head1 VERSION version 0.12008 =head1 SYNOPSIS use Net::Twitter::Lite::WithAPIv1_1; my $nt = Net::Twitter::Lite::WithAPIv1_1->new( consumer_key => $consumer_key, consumer_secret => $consumer_secret, access_token => $access_token, access_token_secret => $access_token_secret, wrap_result => 1, ); my $r = $nt->verify_credentials; my $http_response = $r->http_response; my $twitter_result = $r->result; my $rate_limit_remaining = $r->rate_limit_remaining; =head1 DESCRIPTION Often, the result of a Twitter API call, inflated from the JSON body of the HTTP response does not contain all the information you need. Twitter includes meta data, such as rate limiting information, in HTTP response headers. This object wraps both the inflated Twitter result and the HTTP response giving the caller full access to all the meta data. It also provides accessors for the rate limit information. =head1 METHODS =over 4 =item new($twitter_result, $http_response) Constructs an object wrapping the Twitter result and HTTP response. =cut sub new { my ( $class, $twitter_result, $http_response ) = @_; return bless { result => $twitter_result, http_response => $http_response, }, ref $class || $class; } =item result Returns the inflated Twitter API result. =cut sub result { shift->{result} } =item http_response Returns the L object for the API call. =cut sub http_response { shift->{http_response} } # private method my $limit = sub { my ( $self, $which ) = @_; my $res = $self->http_response; $res->header("X-Rate-Limit-$which") || $res->header("X-FeatureRateLimit-$which"); }; =item rate_limit Returns the rate limit, per 15 minute window, for the API endpoint called. Returns undef if no suitable rate limit header is available. =cut sub rate_limit { shift->$limit('Limit') } =item rate_limit_remaining Returns the calls remaining in the current 15 minute window for the API endpoint called. Returns undef if no suitable header is available. =cut sub rate_limit_remaining { shift->$limit('Remaining') } =item rate_limit_reset Returns the unix epoch time time of the next 15 minute window, i.e., when the rate limit will be reset, for the API endpoint called. Returns undef if no suitable header is available. =cut sub rate_limit_reset { shift->$limit('Reset') } 1; __END__ =back =head1 AUTHOR Marc Mims =head1 COPYRIGHT & LICENSE Copyright (c) 2014 Marc Mims This program is free software; you can redistribute it and/or modify it under the same terms as perl itself. Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/API/V1.pm000644 000766 000024 00000170222 13021411233 022115 0ustar00marcstaff000000 000000 package Net::Twitter::Lite::API::V1; $Net::Twitter::Lite::API::V1::VERSION = '0.12008'; use warnings; use strict; =head1 NAME Net::Twitter::Lite::API::V1 - Method definitions for Twitter's deprecated API v1 =head1 VERSION version 0.12008 =cut sub api_def () { +[ [ Lists => [ [ 'legacy_add_list_member', { aliases => [ qw// ], path => ':user/:list_id/members', method => 'POST', params => [ qw/user list_id id/ ], required => [ qw/user list_id id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_create_list', { aliases => [ qw// ], path => ':user/lists', method => 'POST', params => [ qw/user name mode description/ ], required => [ qw/user name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_delete_list', { aliases => [ qw// ], path => ':user/lists/:list_id', method => 'DELETE', params => [ qw/user list_id/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_delete_list_member', { aliases => [ qw/legacy_remove_list_member/ ], path => ':user/:list_id/members', method => 'DELETE', params => [ qw/user list_id id/ ], required => [ qw/user list_id id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_get_list', { aliases => [ qw// ], path => ':user/lists/:list_id', method => 'GET', params => [ qw/user list_id/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_get_lists', { aliases => [ qw/legacy_list_lists/ ], path => ':user/lists', method => 'GET', params => [ qw/user cursor/ ], required => [ qw/user/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_is_list_member', { aliases => [ qw// ], path => ':user/:list_id/members/:id', method => 'GET', params => [ qw/user list_id id/ ], required => [ qw/user list_id id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_is_list_subscriber', { aliases => [ qw/legacy_is_subscribed_list/ ], path => ':user/:list_id/subscribers/:id', method => 'GET', params => [ qw/user list_id id/ ], required => [ qw/user list_id id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_list_members', { aliases => [ qw// ], path => ':user/:list_id/members', method => 'GET', params => [ qw/user list_id id cursor/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_list_memberships', { aliases => [ qw// ], path => ':user/lists/memberships', method => 'GET', params => [ qw/user cursor/ ], required => [ qw/user/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_list_statuses', { aliases => [ qw// ], path => ':user/lists/:list_id/statuses', method => 'GET', params => [ qw/user list_id since_id max_id per_page page/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_list_subscribers', { aliases => [ qw// ], path => ':user/:list_id/subscribers', method => 'GET', params => [ qw/user list_id id cursor/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_list_subscriptions', { aliases => [ qw// ], path => ':user/lists/subscriptions', method => 'GET', params => [ qw/user cursor/ ], required => [ qw/user/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_members_create_all', { aliases => [ qw/legacy_add_list_members/ ], path => ':user/:list_id/members/create_all', method => 'POST', params => [ qw/user list_id screen_name user_id/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_subscribe_list', { aliases => [ qw// ], path => ':user/:list_id/subscribers', method => 'POST', params => [ qw/user list_id/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_unsubscribe_list', { aliases => [ qw// ], path => ':user/:list_id/subscribers', method => 'DELETE', params => [ qw/user list_id/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], [ 'legacy_update_list', { aliases => [ qw// ], path => ':user/lists/:list_id', method => 'POST', params => [ qw/user list_id name mode description/ ], required => [ qw/user list_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'lists_api_url', } ], ] ], [ REST => [ [ 'account_settings', { aliases => [ qw// ], path => 'account/settings', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'account_totals', { aliases => [ qw// ], path => 'account/totals', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'add_list_member', { aliases => [ qw// ], path => 'lists/members/create', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'add_place', { aliases => [ qw// ], path => 'geo/place', method => 'POST', params => [ qw/name contained_within token lat long attribute:street_address callback/ ], required => [ qw/name contained_within token lat long/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'all_subscriptions', { aliases => [ qw/all_lists list_subscriptions/ ], path => 'lists/all', method => 'GET', params => [ qw/user_id screen_name count cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'block_exists', { aliases => [ qw// ], path => 'blocks/exists/:id', method => 'GET', params => [ qw/id user_id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'blocking', { aliases => [ qw// ], path => 'blocks/blocking', method => 'GET', params => [ qw/page include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'blocking_ids', { aliases => [ qw// ], path => 'blocks/blocking/ids', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'contributees', { aliases => [ qw// ], path => 'users/contributees', method => 'GET', params => [ qw/user_id screen_name include_entities skip_satus/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_satus/ ], base_url_method => 'apiurl', } ], [ 'contributors', { aliases => [ qw// ], path => 'users/contributors', method => 'GET', params => [ qw/user_id screen_name include_entities skip_satus/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_satus/ ], base_url_method => 'apiurl', } ], [ 'create_block', { aliases => [ qw// ], path => 'blocks/create/:id', method => 'POST', params => [ qw/id user_id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'create_favorite', { aliases => [ qw// ], path => 'favorites/create/:id', method => 'POST', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'create_friend', { aliases => [ qw/follow_new/ ], path => 'friendships/create/:id', method => 'POST', params => [ qw/id user_id screen_name follow include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities follow/ ], base_url_method => 'apiurl', } ], [ 'create_list', { aliases => [ qw// ], path => 'lists/create', method => 'POST', params => [ qw/list_id slug name mode description owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'create_saved_search', { aliases => [ qw// ], path => 'saved_searches/create', method => 'POST', params => [ qw/query/ ], required => [ qw/query/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'delete_list', { aliases => [ qw// ], path => 'lists/destroy', method => 'POST', params => [ qw/owner_screen_name owner_id list_id slug/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'delete_list_member', { aliases => [ qw/remove_list_member/ ], path => 'lists/members/destroy', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'destroy_block', { aliases => [ qw// ], path => 'blocks/destroy/:id', method => 'POST', params => [ qw/id user_id screen_name/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_direct_message', { aliases => [ qw// ], path => 'direct_messages/destroy/:id', method => 'POST', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_favorite', { aliases => [ qw// ], path => 'favorites/destroy/:id', method => 'POST', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_friend', { aliases => [ qw/unfollow/ ], path => 'friendships/destroy/:id', method => 'POST', params => [ qw/id user_id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_saved_search', { aliases => [ qw// ], path => 'saved_searches/destroy/:id', method => 'POST', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'destroy_status', { aliases => [ qw// ], path => 'statuses/destroy/:id', method => 'POST', params => [ qw/id trim_user include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'direct_messages', { aliases => [ qw// ], path => 'direct_messages', method => 'GET', params => [ qw/since_id max_id count page include_entities/ ], required => [ qw/include_entities/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'disable_notifications', { aliases => [ qw// ], path => 'notifications/leave/:id', method => 'POST', params => [ qw/id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'downtime_schedule', { aliases => [ qw// ], path => 'help/downtime_schedule', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 1, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'enable_notifications', { aliases => [ qw// ], path => 'notifications/follow/:id', method => 'POST', params => [ qw/id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'end_session', { aliases => [ qw// ], path => 'account/end_session', method => 'POST', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'favorites', { aliases => [ qw// ], path => 'favorites/:id', method => 'GET', params => [ qw/id page include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'followers', { aliases => [ qw// ], path => 'statuses/followers/:id', method => 'GET', params => [ qw/id user_id screen_name cursor include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 1, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'followers_ids', { aliases => [ qw// ], path => 'followers/ids/:id', method => 'GET', params => [ qw/id user_id screen_name cursor/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'friends', { aliases => [ qw/following/ ], path => 'statuses/friends/:id', method => 'GET', params => [ qw/id user_id screen_name cursor include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 1, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'friends_ids', { aliases => [ qw/following_ids/ ], path => 'friends/ids/:id', method => 'GET', params => [ qw/id user_id screen_name cursor/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'friends_timeline', { aliases => [ qw/following_timeline/ ], path => 'statuses/friends_timeline', method => 'GET', params => [ qw/since_id max_id count page skip_user trim_user include_entities include_rts/ ], required => [ qw// ], add_source => 0, deprecated => 1, authenticate => 1, booleans => [ qw/skip_user trim_user include_entities include_rts/ ], base_url_method => 'apiurl', } ], [ 'friendship_exists', { aliases => [ qw/relationship_exists follows/ ], path => 'friendships/exists', method => 'GET', params => [ qw/user_id_a user_id_b screen_name_a screen_name_b user_a user_b/ ], required => [ qw/user_a user_b/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'friendships_incoming', { aliases => [ qw// ], path => 'friendships/incoming', method => 'GET', params => [ qw/cursor/ ], required => [ qw/cursor/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'friendships_outgoing', { aliases => [ qw// ], path => 'friendships/outgoing', method => 'GET', params => [ qw/cursor/ ], required => [ qw/cursor/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'geo_id', { aliases => [ qw// ], path => 'geo/id/:id', method => 'GET', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'geo_search', { aliases => [ qw// ], path => 'geo/search', method => 'GET', params => [ qw/lat long query ip granularity accuracy max_results contained_within attribute:street_address callback/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_configuration', { aliases => [ qw// ], path => 'help/configuration', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_languages', { aliases => [ qw// ], path => 'help/languages', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_list', { aliases => [ qw// ], path => 'lists/show', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_lists', { aliases => [ qw/list_lists/ ], path => 'lists', method => 'GET', params => [ qw/user_id screen_name cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_privacy_policy', { aliases => [ qw// ], path => 'legal/privacy', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_tos', { aliases => [ qw// ], path => 'legal/tos', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'home_timeline', { aliases => [ qw// ], path => 'statuses/home_timeline', method => 'GET', params => [ qw/since_id max_id count page skip_user exclude_replies contributor_details include_rts include_entities trim_user include_my_retweet/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/skip_user exclude_replies contributor_details include_rts include_entities trim_user include_my_retweet/ ], base_url_method => 'apiurl', } ], [ 'is_list_member', { aliases => [ qw// ], path => 'lists/members/show', method => 'GET', params => [ qw/owner_screen_name owner_id list_id slug user_id screen_name include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_status/ ], base_url_method => 'apiurl', } ], [ 'is_list_subscriber', { aliases => [ qw/is_subscribed_list/ ], path => 'lists/subscribers/show', method => 'GET', params => [ qw/owner_screen_name owner_id list_id slug user_id screen_name include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_status/ ], base_url_method => 'apiurl', } ], [ 'list_members', { aliases => [ qw// ], path => 'lists/members', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id cursor include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_status/ ], base_url_method => 'apiurl', } ], [ 'list_memberships', { aliases => [ qw// ], path => 'lists/memberships', method => 'GET', params => [ qw/user_id screen_name cursor filter_to_owned_lists/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/filter_to_owned_lists/ ], base_url_method => 'apiurl', } ], [ 'list_statuses', { aliases => [ qw// ], path => 'lists/statuses', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id since_id max_id per_page page include_entities include_rts/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities include_rts/ ], base_url_method => 'apiurl', } ], [ 'list_subscribers', { aliases => [ qw// ], path => 'lists/subscribers', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id cursor include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_status/ ], base_url_method => 'apiurl', } ], [ 'lookup_friendships', { aliases => [ qw// ], path => 'friendships/lookup', method => 'GET', params => [ qw/user_id screen_name/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'lookup_users', { aliases => [ qw// ], path => 'users/lookup', method => 'GET', params => [ qw/user_id screen_name include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'members_create_all', { aliases => [ qw/add_list_members/ ], path => 'lists/members/create_all', method => 'POST', params => [ qw/list_id slug owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'members_destroy_all', { aliases => [ qw/remove_list_members/ ], path => 'lists/members/destroy_all', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'mentions', { aliases => [ qw/replies/ ], path => 'statuses/mentions', method => 'GET', params => [ qw/since_id max_id count page trim_user include_rts include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_rts include_entities/ ], base_url_method => 'apiurl', } ], [ 'new_direct_message', { aliases => [ qw// ], path => 'direct_messages/new', method => 'POST', params => [ qw/user text screen_name user_id include_entities/ ], required => [ qw/user text/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'no_retweet_ids', { aliases => [ qw// ], path => 'friendships/no_retweet_ids', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'public_timeline', { aliases => [ qw// ], path => 'statuses/public_timeline', method => 'GET', params => [ qw/skip_user trim_user include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/skip_user trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'rate_limit_status', { aliases => [ qw// ], path => 'account/rate_limit_status', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'related_results', { aliases => [ qw// ], path => 'related_results/show/:id', method => 'GET', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'report_spam', { aliases => [ qw// ], path => 'report_spam', method => 'POST', params => [ qw/id user_id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'retweet', { aliases => [ qw// ], path => 'statuses/retweet/:id', method => 'POST', params => [ qw/id include_entities trim_user/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities trim_user/ ], base_url_method => 'apiurl', } ], [ 'retweeted_by', { aliases => [ qw// ], path => 'statuses/:id/retweeted_by', method => 'GET', params => [ qw/id count page trim_user include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities trim_user/ ], base_url_method => 'apiurl', } ], [ 'retweeted_by_ids', { aliases => [ qw// ], path => 'statuses/:id/retweeted_by/ids', method => 'GET', params => [ qw/id count page trim_user include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities trim_user/ ], base_url_method => 'apiurl', } ], [ 'retweeted_by_me', { aliases => [ qw// ], path => 'statuses/retweeted_by_me', method => 'GET', params => [ qw/since_id max_id count page trim_user include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'retweeted_by_user', { aliases => [ qw// ], path => 'statuses/retweeted_by_user', method => 'GET', params => [ qw/id user_id screen_name/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'retweeted_to_me', { aliases => [ qw// ], path => 'statuses/retweeted_to_me', method => 'GET', params => [ qw/since_id max_id count page/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'retweeted_to_user', { aliases => [ qw// ], path => 'statuses/retweeted_to_user', method => 'GET', params => [ qw/id user_id screen_name/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'retweets', { aliases => [ qw// ], path => 'statuses/retweets/:id', method => 'GET', params => [ qw/id count trim_user include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'retweets_of_me', { aliases => [ qw/retweeted_of_me/ ], path => 'statuses/retweets_of_me', method => 'GET', params => [ qw/since_id max_id count page trim_user include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'reverse_geocode', { aliases => [ qw// ], path => 'geo/reverse_geocode', method => 'GET', params => [ qw/lat long accuracy granularity max_results/ ], required => [ qw/lat long/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'saved_searches', { aliases => [ qw// ], path => 'saved_searches', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'sent_direct_messages', { aliases => [ qw// ], path => 'direct_messages/sent', method => 'GET', params => [ qw/since_id max_id page count include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'show_direct_message', { aliases => [ qw// ], path => 'direct_messages/show/:id', method => 'GET', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'show_friendship', { aliases => [ qw/show_relationship/ ], path => 'friendships/show', method => 'GET', params => [ qw/source_id source_screen_name target_id target_id_name/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'show_saved_search', { aliases => [ qw// ], path => 'saved_searches/show/:id', method => 'GET', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'show_status', { aliases => [ qw// ], path => 'statuses/show/:id', method => 'GET', params => [ qw/id trim_user include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'show_user', { aliases => [ qw// ], path => 'users/show/:id', method => 'GET', params => [ qw/id screen_name include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'similar_places', { aliases => [ qw// ], path => 'geo/similar_places', method => 'GET', params => [ qw/lat long name contained_within attribute:street_address callback/ ], required => [ qw/lat long name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'subscribe_list', { aliases => [ qw// ], path => 'lists/subscribers/create', method => 'POST', params => [ qw/owner_screen_name owner_id list_id slug/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'subscriptions', { aliases => [ qw// ], path => 'lists/subscriptions', method => 'GET', params => [ qw/user_id screen_name count cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'suggestion_categories', { aliases => [ qw// ], path => 'users/suggestions', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'test', { aliases => [ qw// ], path => 'help/test', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends', { aliases => [ qw// ], path => 'trends', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 1, authenticate => 0, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_available', { aliases => [ qw// ], path => 'trends/available', method => 'GET', params => [ qw/lat long/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 0, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_current', { aliases => [ qw// ], path => 'trends/current', method => 'GET', params => [ qw/exclude/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 0, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_daily', { aliases => [ qw// ], path => 'trends/daily', method => 'GET', params => [ qw/date exclude/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 0, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_location', { aliases => [ qw// ], path => 'trends/:woeid', method => 'GET', params => [ qw/woeid/ ], required => [ qw/woeid/ ], add_source => 0, deprecated => 0, authenticate => 0, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_weekly', { aliases => [ qw// ], path => 'trends/weekly', method => 'GET', params => [ qw/date exclude/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 0, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'unsubscribe_list', { aliases => [ qw// ], path => 'lists/subscribers/destroy', method => 'POST', params => [ qw/list_id slug owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update', { aliases => [ qw// ], path => 'statuses/update', method => 'POST', params => [ qw/status lat long place_id display_coordinates in_reply_to_status_id trim_user include_entities/ ], required => [ qw/status/ ], add_source => 1, deprecated => 0, authenticate => 1, booleans => [ qw/display_coordinates trim_user include_entities/ ], base_url_method => 'apiurl', } ], [ 'update_delivery_device', { aliases => [ qw// ], path => 'account/update_delivery_device', method => 'POST', params => [ qw/device/ ], required => [ qw/device/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_friendship', { aliases => [ qw// ], path => 'friendships/update', method => 'POST', params => [ qw/id user_id screen_name device retweets/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/device retweets/ ], base_url_method => 'apiurl', } ], [ 'update_list', { aliases => [ qw// ], path => 'lists/update', method => 'POST', params => [ qw/list_id slug name mode description owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_location', { aliases => [ qw// ], path => 'account/update_location', method => 'POST', params => [ qw/location/ ], required => [ qw/location/ ], add_source => 0, deprecated => 1, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_profile', { aliases => [ qw// ], path => 'account/update_profile', method => 'POST', params => [ qw/name email url location description include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'update_profile_background_image', { aliases => [ qw// ], path => 'account/update_profile_background_image', method => 'POST', params => [ qw/image use/ ], required => [ qw/image/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/use/ ], base_url_method => 'apiurl', } ], [ 'update_profile_colors', { aliases => [ qw// ], path => 'account/update_profile_colors', method => 'POST', params => [ qw/profile_background_color profile_text_color profile_link_color profile_sidebar_fill_color profile_sidebar_border_color/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_profile_image', { aliases => [ qw// ], path => 'account/update_profile_image', method => 'POST', params => [ qw/image/ ], required => [ qw/image/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_with_media', { aliases => [ qw// ], path => 'statuses/update_with_media', method => 'POST', params => [ qw/status media[] possibly_sensitive in_reply_to_status_id lat long place_id display_coordinates/ ], required => [ qw/status media/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/possibly_sensitive display_coordinates/ ], base_url_method => 'upload_url', } ], [ 'user_suggestions', { aliases => [ qw/follow_suggestions/ ], path => 'users/suggestions/:category/members', method => 'GET', params => [ qw/category lang/ ], required => [ qw/category/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'user_timeline', { aliases => [ qw// ], path => 'statuses/user_timeline/:id', method => 'GET', params => [ qw/id user_id screen_name since_id max_id count page skip_user trim_user include_entities include_rts/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/skip_user trim_user include_entities include_rts/ ], base_url_method => 'apiurl', } ], [ 'users_search', { aliases => [ qw/find_people search_users/ ], path => 'users/search', method => 'GET', params => [ qw/q per_page page include_entities/ ], required => [ qw/q/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'verify_credentials', { aliases => [ qw// ], path => 'account/verify_credentials', method => 'GET', params => [ qw/include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], ] ], [ Search => [ [ 'search', { aliases => [ qw// ], path => 'search', method => 'GET', params => [ qw/q callback lang locale rpp page since_id until geocode show_user result_type/ ], required => [ qw/q/ ], add_source => 0, deprecated => 0, authenticate => 0, booleans => [ qw// ], base_url_method => 'searchapiurl', } ], ] ], ]} 1; __END__ =for Pod::Coverage api_def =cut Net-Twitter-Lite-0.12008/lib/Net/Twitter/Lite/API/V1_1.pm000644 000766 000024 00000133442 13021411233 022340 0ustar00marcstaff000000 000000 package Net::Twitter::Lite::API::V1_1; $Net::Twitter::Lite::API::V1_1::VERSION = '0.12008'; use warnings; use strict; =head1 NAME Net::Twitter::Lite::API::V1_1 - Twitter API v1.1 method definitions =head1 VERSION version 0.12008 =cut sub api_def () { +[ [ REST => [ # Timelines [ 'mentions', { aliases => [ qw/replies/ ], path => 'statuses/mentions_timeline', method => 'GET', params => [ qw/count since_id max_id trim_user contributor_details include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user contributor_details include_entities/ ], base_url_method => 'apiurl', } ], [ 'user_timeline', { aliases => [ qw// ], path => 'statuses/user_timeline', method => 'GET', params => [ qw/user_id screen_name since_id count max_id trim_user exclude_replies contributor_details include_rts/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user exclude_replies contributor_details include_rts/ ], base_url_method => 'apiurl', } ], [ 'home_timeline', { aliases => [ qw// ], path => 'statuses/home_timeline', method => 'GET', params => [ qw/count since_id max_id trim_user exclude_replies contributor_details include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user exclude_replies contributor_details include_entities/ ], base_url_method => 'apiurl', } ], [ 'retweets_of_me', { aliases => [ qw/retweeted_of_me/ ], path => 'statuses/retweets_of_me', method => 'GET', params => [ qw/count since_id max_id trim_user include_entities include_user_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_entities include_user_entities/ ], base_url_method => 'apiurl', } ], # Tweets [ 'retweets', { aliases => [ qw// ], path => 'statuses/retweets/:id', method => 'GET', params => [ qw/id count trim_user/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user/ ], base_url_method => 'apiurl', } ], [ 'show_status', { aliases => [ qw// ], path => 'statuses/show/:id', method => 'GET', params => [ qw/id trim_user include_my_retweet include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user include_my_retweet include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_status', { aliases => [ qw// ], path => 'statuses/destroy/:id', method => 'POST', params => [ qw/id trim_user/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user/ ], base_url_method => 'apiurl', } ], [ 'update', { aliases => [ qw// ], path => 'statuses/update', method => 'POST', params => [ qw/status in_reply_to_status_id lat long place_id display_coordinates trim_user/ ], required => [ qw/status/ ], add_source => 1, deprecated => 0, authenticate => 1, booleans => [ qw/display_coordinates trim_user/ ], base_url_method => 'apiurl', } ], [ 'retweet', { aliases => [ qw// ], path => 'statuses/retweet/:id', method => 'POST', params => [ qw/id trim_user/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/trim_user/ ], base_url_method => 'apiurl', } ], [ 'update_with_media', { aliases => [ qw// ], path => 'statuses/update_with_media', method => 'POST', params => [ qw/status media[] possibly_sensitive in_reply_to_status_id lat long place_id display_coordinates/ ], required => [ qw/status media/ ], add_source => 0, deprecated => 1, authenticate => 1, booleans => [ qw/possibly_sensitive display_coordinates/ ], base_url_method => 'apiurl', } ], [ 'upload_media', { aliases => [ qw/upload/ ], path => 'media/upload', method => 'POST', content_type => 'form-data', params => [qw/media media_data additional_owners/], required => [qw//], add_source => 0, deprecated => 0, authenticate => 1, booleans => [], base_url_method => 'upload_url', } ], [ 'get_oembed', { aliases => [ qw// ], path => 'statuses/oembed', method => 'GET', params => [ qw/id url maxwidth hide_media hide_thread omit_script align related lang/ ], required => [ qw/id url/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/hide_media hide_thread omit_script/ ], base_url_method => 'apiurl', } ], # Search [ 'search', { aliases => [ qw// ], path => 'search/tweets', method => 'GET', params => [ qw/q geocode lang locale result_type count until since_id max_id include_entities callback/ ], required => [ qw/q/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], # Direct Messages [ 'direct_messages', { aliases => [ qw// ], path => 'direct_messages', method => 'GET', params => [ qw/since_id max_id count include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'sent_direct_messages', { aliases => [ qw// ], path => 'direct_messages/sent', method => 'GET', params => [ qw/since_id max_id count page include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'show_direct_message', { aliases => [ qw// ], path => 'direct_messages/show', method => 'GET', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'destroy_direct_message', { aliases => [ qw// ], path => 'direct_messages/destroy', method => 'POST', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'new_direct_message', { aliases => [ qw// ], path => 'direct_messages/new', method => 'POST', params => [ qw/user_id screen_name text/ ], required => [ qw/text/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Friends & Followers [ 'no_retweet_ids', { aliases => [ qw// ], path => 'friendships/no_retweets/ids', method => 'GET', params => [ qw/stringify_ids/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/stringify_ids/ ], base_url_method => 'apiurl', } ], [ 'friends_ids', { aliases => [ qw/following_ids/ ], path => 'friends/ids', method => 'GET', params => [ qw/user_id screen_name cursor stringify_ids count/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/stringify_ids/ ], base_url_method => 'apiurl', } ], [ 'followers_ids', { aliases => [ qw// ], path => 'followers/ids', method => 'GET', params => [ qw/user_id screen_name cursor stringify_ids count/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/stringify_ids/ ], base_url_method => 'apiurl', } ], [ 'lookup_friendships', { aliases => [ qw// ], path => 'friendships/lookup', method => 'GET', params => [ qw/screen_name user_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'friendships_incoming', { aliases => [ qw// ], path => 'friendships/incoming', method => 'GET', params => [ qw/cursor stringify_ids/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/stringify_ids/ ], base_url_method => 'apiurl', } ], [ 'friendships_outgoing', { aliases => [ qw// ], path => 'friendships/outgoing', method => 'GET', params => [ qw/cursor stringify_ids/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/stringify_ids/ ], base_url_method => 'apiurl', } ], [ 'create_friend', { aliases => [ qw/follow_new/ ], path => 'friendships/create', method => 'POST', params => [ qw/screen_name user_id follow/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/follow/ ], base_url_method => 'apiurl', } ], [ 'destroy_friend', { aliases => [ qw/unfollow/ ], path => 'friendships/destroy', method => 'POST', params => [ qw/screen_name user_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_friendship', { aliases => [ qw// ], path => 'friendships/update', method => 'POST', params => [ qw/screen_name user_id device retweets/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/device retweets/ ], base_url_method => 'apiurl', } ], [ 'show_friendship', { aliases => [ qw/show_relationship/ ], path => 'friendships/show', method => 'GET', params => [ qw/source_id source_screen_name target_id target_screen_name/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'friends', { aliases => [ qw/friends_list/ ], path => 'friends/list', method => 'GET', params => [ qw/user_id screen_name cursor skip_status include_user_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/skip_status include_user_entities/ ], base_url_method => 'apiurl', } ], [ 'followers', { aliases => [ qw/followers_list/ ], path => 'followers/list', method => 'GET', params => [ qw/user_id screen_name cursor skip_status include_user_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/skip_status include_user_entities/ ], base_url_method => 'apiurl', } ], # Users [ 'account_settings', { aliases => [ qw// ], path => 'account/settings', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'verify_credentials', { aliases => [ qw// ], path => 'account/verify_credentials', method => 'GET', params => [ qw/include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities skip_status/ ], base_url_method => 'apiurl', } ], [ 'update_account_settings', { aliases => [ qw// ], path => 'account/settings', method => 'POST', params => [ qw/trend_location_woeid sleep_time_enabled start_sleep_time end_sleep_time time_zone lang/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/sleep_time_enabled/ ], base_url_method => 'apiurl', } ], [ 'update_delivery_device', { aliases => [ qw// ], path => 'account/update_delivery_device', method => 'POST', params => [ qw/device include_entities/ ], required => [ qw/device/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'update_profile', { aliases => [ qw// ], path => 'account/update_profile', method => 'POST', params => [ qw/name url location description include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'update_profile_background_image', { aliases => [ qw// ], path => 'account/update_profile_background_image', method => 'POST', params => [ qw/image tile include_entities skip_status use/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'update_profile_colors', { aliases => [ qw// ], path => 'account/update_profile_colors', method => 'POST', params => [ qw/profile_background_color profile_link_color profile_sidebar_border_color profile_sidebar_fill_color profile_text_color include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'update_profile_image', { aliases => [ qw// ], path => 'account/update_profile_image', method => 'POST', params => [ qw/image include_entities skip_status/ ], required => [ qw/image/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'blocking', { aliases => [ qw// ], path => 'blocks/list', method => 'GET', params => [ qw/include_entities skip_status cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'blocking_ids', { aliases => [ qw// ], path => 'blocks/ids', method => 'GET', params => [ qw/stringify_ids cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/stringify_ids/ ], base_url_method => 'apiurl', } ], [ 'create_block', { aliases => [ qw// ], path => 'blocks/create', method => 'POST', params => [ qw/screen_name user_id include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_block', { aliases => [ qw// ], path => 'blocks/destroy', method => 'POST', params => [ qw/screen_name user_id include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'lookup_users', { aliases => [ qw// ], path => 'users/lookup', method => 'GET', params => [ qw/screen_name user_id include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'show_user', { aliases => [ qw// ], path => 'users/show', method => 'GET', params => [ qw/user_id screen_name include_entities/ ], required => [ qw/user_id screen_name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'users_search', { aliases => [ qw/find_people search_users/ ], path => 'users/search', method => 'GET', params => [ qw/q page count include_entities/ ], required => [ qw/q/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'contributees', { aliases => [ qw// ], path => 'users/contributees', method => 'GET', params => [ qw/user_id screen_name include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'contributors', { aliases => [ qw// ], path => 'users/contributors', method => 'GET', params => [ qw/user_id screen_name include_entities skip_status/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'remove_profile_banner', { aliases => [ qw// ], path => 'account/remove_profile_banner', method => 'POST', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_profile_banner', { aliases => [ qw// ], path => 'account/update_profile_banner', method => 'POST', params => [ qw/banner width height offset_left offset_top/ ], required => [ qw/banner/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'users_profile_banner', { aliases => [ qw// ], path => 'users/profile_banner', method => 'GET', params => [ qw/user_id screen_name/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Suggested Users [ 'user_suggestions', { aliases => [ qw/follow_suggestions/ ], path => 'users/suggestions/:slug', method => 'GET', params => [ qw/slug lang/ ], required => [ qw/slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'suggestion_categories', { aliases => [ qw// ], path => 'users/suggestions', method => 'GET', params => [ qw/lang/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'user_suggestions_statuses', { aliases => [ qw// ], path => 'users/suggestions/:slug/members', method => 'GET', params => [ qw/slug/ ], required => [ qw/slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Favorites [ 'favorites', { aliases => [ qw// ], path => 'favorites/list', method => 'GET', params => [ qw/user_id screen_name count since_id max_id include_entities/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'destroy_favorite', { aliases => [ qw// ], path => 'favorites/destroy', method => 'POST', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'create_favorite', { aliases => [ qw// ], path => 'favorites/create', method => 'POST', params => [ qw/id include_entities/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], # Lists [ 'get_lists', { aliases => [ qw/list_lists all_subscriptions/ ], path => 'lists/list', method => 'GET', params => [ qw/user_id screen_name reverse/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'list_statuses', { aliases => [ qw// ], path => 'lists/statuses', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id since_id max_id count include_entities include_rts/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'delete_list_member', { aliases => [ qw/remove_list_member/ ], path => 'lists/members/destroy', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'list_memberships', { aliases => [ qw/listed_ids/ ], path => 'lists/memberships', method => 'GET', params => [ qw/user_id screen_name cursor filter_to_owned_lists/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'list_subscribers', { aliases => [ qw// ], path => 'lists/subscribers', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id cursor include_entities skip_status/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'subscribe_list', { aliases => [ qw// ], path => 'lists/subscribers/create', method => 'POST', params => [ qw/owner_screen_name owner_id list_id slug/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'is_list_subscriber', { aliases => [ qw/is_subscribed_list/ ], path => 'lists/subscribers/show', method => 'GET', params => [ qw/owner_screen_name owner_id list_id slug user_id screen_name include_entities skip_status/ ], required => [ qw/list_id slug user_id screen_name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'unsubscribe_list', { aliases => [ qw// ], path => 'lists/subscribers/destroy', method => 'POST', params => [ qw/list_id slug owner_screen_name owner_id/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'members_create_all', { aliases => [ qw/add_list_members/ ], path => 'lists/members/create_all', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'is_list_member', { aliases => [ qw// ], path => 'lists/members/show', method => 'GET', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id include_entities skip_status/ ], required => [ qw/list_id slug user_id screen_name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'list_members', { aliases => [ qw// ], path => 'lists/members', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id cursor include_entities skip_status/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw/include_entities/ ], base_url_method => 'apiurl', } ], [ 'add_list_member', { aliases => [ qw// ], path => 'lists/members/create', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw/list_id slug user_id screen_name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'delete_list', { aliases => [ qw// ], path => 'lists/destroy', method => 'POST', params => [ qw/owner_screen_name owner_id list_id slug/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'update_list', { aliases => [ qw// ], path => 'lists/update', method => 'POST', params => [ qw/list_id slug name mode description owner_screen_name owner_id/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'create_list', { aliases => [ qw// ], path => 'lists/create', method => 'POST', params => [ qw/name mode description/ ], required => [ qw/name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_list', { aliases => [ qw// ], path => 'lists/show', method => 'GET', params => [ qw/list_id slug owner_screen_name owner_id/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'list_subscriptions', { aliases => [ qw/subscriptions/ ], path => 'lists/subscriptions', method => 'GET', params => [ qw/user_id screen_name count cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'members_destroy_all', { aliases => [ qw/remove_list_members/ ], path => 'lists/members/destroy_all', method => 'POST', params => [ qw/list_id slug user_id screen_name owner_screen_name owner_id/ ], required => [ qw/list_id slug/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'list_ownerships', { aliases => [], path => 'lists/ownerships', method => 'GET', params => [ qw/user_id screen_name count cursor/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Saved Searches [ 'saved_searches', { aliases => [ qw// ], path => 'saved_searches/list', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'show_saved_search', { aliases => [ qw// ], path => 'saved_searches/show/:id', method => 'GET', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'create_saved_search', { aliases => [ qw// ], path => 'saved_searches/create', method => 'POST', params => [ qw/query/ ], required => [ qw/query/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'destroy_saved_search', { aliases => [ qw// ], path => 'saved_searches/destroy/:id', method => 'POST', params => [ qw/id/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Places & Geo [ 'geo_id', { aliases => [ qw// ], path => 'geo/id/:place_id', method => 'GET', params => [ qw/place_id/ ], required => [ qw/place_id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'reverse_geocode', { aliases => [ qw// ], path => 'geo/reverse_geocode', method => 'GET', params => [ qw/lat long accuracy granularity max_results callback/ ], required => [ qw/lat long/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'geo_search', { aliases => [ qw// ], path => 'geo/search', method => 'GET', params => [ qw/lat long query ip granularity accuracy max_results contained_within attribute:street_address callback/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'similar_places', { aliases => [ qw// ], path => 'geo/similar_places', method => 'GET', params => [ qw/lat long name contained_within attribute:street_address callback/ ], required => [ qw/lat long name/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'add_place', { aliases => [ qw// ], path => 'geo/place', method => 'POST', params => [ qw/name contained_within token lat long attribute:street_address callback/ ], required => [ qw/name contained_within token lat long/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Trends [ 'trends', { path => 'trends/place', method => 'GET', params => [ qw/id exclude/ ], required => [ qw/id/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_available', { aliases => [ qw// ], path => 'trends/available', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'trends_closest', { aliases => [ qw// ], path => 'trends/closest', method => 'GET', params => [ qw/lat long/ ], required => [ qw/lat long/ ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Spam Reporting [ 'report_spam', { aliases => [ qw// ], path => 'users/report_spam', method => 'POST', params => [ qw/screen_name user_id/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], # Help [ 'get_configuration', { aliases => [ qw// ], path => 'help/configuration', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_languages', { aliases => [ qw// ], path => 'help/languages', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_privacy', { aliases => [ qw// ], path => 'help/privacy', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'get_tos', { aliases => [ qw// ], path => 'help/tos', method => 'GET', params => [ qw// ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], [ 'rate_limit_status', { aliases => [ qw// ], path => 'application/rate_limit_status', method => 'GET', params => [ qw/resources/ ], required => [ qw// ], add_source => 0, deprecated => 0, authenticate => 1, booleans => [ qw// ], base_url_method => 'apiurl', } ], ] ], ]} 1; __END__ =for Pod::Coverage api_def =cut Net-Twitter-Lite-0.12008/examples/oauth_desktop.pl000644 000766 000024 00000002415 13021411233 022047 0ustar00marcstaff000000 000000 #!/usr/bin/perl # # Net::Twitter::Lite - OAuth desktop app example # use warnings; use strict; use Net::Twitter::Lite::WithAPIv1_1; use File::Spec; use Storable; use Data::Dumper; # You can replace the consumer tokens with your own; # these tokens are for the Net::Twitter example app. my %consumer_tokens = ( consumer_key => 'v8t3JILkStylbgnxGLOQ', consumer_secret => '5r31rSMc0NPtBpHcK8MvnCLg2oAyFLx5eGOMkXM', ); # $datafile = oauth_desktop.dat my (undef, undef, $datafile) = File::Spec->splitpath($0); $datafile =~ s/\..*/.dat/; my $nt = Net::Twitter::Lite::WithAPIv1_1->new(ssl => 1, %consumer_tokens); my $access_tokens = eval { retrieve($datafile) } || []; if ( @$access_tokens ) { $nt->access_token($access_tokens->[0]); $nt->access_token_secret($access_tokens->[1]); } else { my $auth_url = $nt->get_authorization_url; print " Authorize this application at: $auth_url\nThen, enter the PIN# provided to contunie: "; my $pin = ; # wait for input chomp $pin; # request_access_token stores the tokens in $nt AND returns them my @access_tokens = $nt->request_access_token(verifier => $pin); # save the access tokens store \@access_tokens, $datafile; } my $status = $nt->user_timeline({ count => 1 }); print Dumper $status; Net-Twitter-Lite-0.12008/examples/oauth_webapp.pl000644 000766 000024 00000014022 13021411233 021651 0ustar00marcstaff000000 000000 #!/usr/bin/perl # # Net::Twitter::Lite - OAuth webapp example # package MyWebApp; use warnings; use strict; use base qw/HTTP::Server::Simple::CGI/; use Data::Dumper; use Net::Twitter::Lite::WithAPIv1_1; # You can replace the consumer tokens with your own; # these tokens are for the Net::Twitter example app. my %consumer_tokens = ( consumer_key => 'v8t3JILkStylbgnxGLOQ', consumer_secret => '5r31rSMc0NPtBpHcK8MvnCLg2oAyFLx5eGOMkXM', ); my $server_port = 8080; # The server needs to store request tokens/secrets. When a user is returned # from Twitter's authentication flow to our callback URL, the request token # will be included in the callback parameters. We'll look up the secret that # matches the token. It will be used to obtain an access token/secret. Request # tokens are only good for about 15 minutes. # # In a production app, you'll want to use something like Redis to automatically # expire secrets after 20 minutes or so. (Keep them a bit longer than Twitter # so Twitter drops them first. You don't want to surprise users who authorize # on Twitter and then you faile to find the secret you need to obtain access # tokens. # # For our simple demo, we'll just store them in memory with expiration. my $request_token_cache = {}; # We only need it once! sub get_secret { delete $request_token_cache->{shift()} } sub set_secret { $request_token_cache->{$_[0]} = $_[1] } sub twitter_client { Net::Twitter::Lite::WithAPIv1_1->new(%consumer_tokens); } my %dispatch = ( '/oauth_callback' => \&oauth_callback, '/' => \&my_last_tweet, ); # all request start here sub handle_request { my ($self, $q) = @_; my $request = $q->path_info; warn "Handling request for ${ \$q->url(-full => 1) }\n"; my $handler = $dispatch{$request} || \¬_found; $self->$handler($q); } # Display the authenicated user's last tweet sub my_last_tweet { my ($self, $q) = @_; # if the user is authorized, we'll get access tokens from a cookie my %tokens = $q->cookie('dont-do-this'); unless ( %tokens ) { warn "User has no access_tokens\n"; return $self->authorize($q); } warn <<""; Using access tokens: access_token => $tokens{access_token} access_token_secret => $tokens{access_token_secret} my $nt = $self->twitter_client; # pass the access tokens to Net::Twitter::Lite $nt->access_token($tokens{access_token}); $nt->access_token_secret($tokens{access_token_secret}); # attempt to get the user's last tweet my $status = eval { $nt->user_timeline({ count => 1 }) }; if ( $@ ) { warn "$@\n"; # if we got a 401 response, our access tokens were invalid; get new ones return $self->authorize($q, $nt) if $@ =~ /\b401\b/; # something bad happened; show the user the error $status = $@; } print $q->header(-nph => 1), $q->start_html, $q->pre(Dumper $status), $q->end_html; } # send the user to Twitter to authorize us sub authorize { my ($self, $q, $nt) = @_; $nt ||= $self->twitter_client; my $callback = join '', $ENV{SERVER_URL}, 'oauth_callback'; my $auth_url = $nt->get_authorization_url( callback => $callback, ); set_secret( $nt->request_token, $nt->request_token_secret ); warn "Sending user to: $auth_url\n"; print $q->redirect(-nph => 1, -uri => $auth_url); } # Twitter returns the user here sub oauth_callback { my ($self, $q) = @_; # If the user authorized the app, we'll get oauth_token and oauth_verifier # parameters. If they hit "cancel" to deny the request, then the "return to # ..." button, we'll ge the request_token back in the "denied" parameter. if ( my $token = $q->param('denied') ) { warn "Sadly, we were denied for request_token $token.\n"; get_secret($token); # discard it, it's of no value, now print $q->redirect(-nph => 1, -uri => "$ENV{SERVER_URL}"); return; } my $request_token = $q->param('oauth_token'); my $verifier = $q->param('oauth_verifier'); my $request_secret = get_secret($request_token); unless ( $request_secret ) { # Something is wrong: # - the request_token has expired # - our callback was hit with invalid parameters # - this is a replay (we've already exchanged the request token # for an access token/secret # Your app will need to deal with it. We'll punt the user to # the home page. print $q->redirect(-nph => 1, -uri => "$ENV{SERVER_URL}"); return; } warn <<""; User returned from Twitter with: oauth_token => $request_token oauth_verifier => $verifier # We'll need the request token/secret for authorization my $nt = $self->twitter_client; $nt->request_token($request_token); $nt->request_token_secret($request_secret); # exchange the request token for access tokens my ( $access_token, $access_token_secret ) = $nt->request_access_token(verifier => $verifier); warn <<""; Exchanged request tokens for access tokens: access_token => $access_token access_token_secret => $access_token_secret # *** Don't do this at home! *** # For our simple example, we'll store the access token/secret in a cookie. # In a production app, you don't want to do this. Store the token/secret # in a database, encrypted! my $cookie = $q->cookie(-name => 'dont-do-this', -value => { access_token => $access_token, access_token_secret => $access_token_secret, }); warn "redirecting newly authorized user to $ENV{SERVER_URL}\n"; print $q->redirect(-cookie => $cookie, -nph => 1, -uri => "$ENV{SERVER_URL}"); } # display a 404 Not found for any request we don't expect sub not_found { my ($self, $q) = @_; print $q->header(-nph => 1, -type => 'text/html', -status => '404 Not found'), $q->start_html, $q->h1('Not Found'), $q->p('You appear to be lost. Try going home.'); } my $app = MyWebApp->new($server_port); $app->run;