The Developer's Guide To Social Programming M. Hawker (Addison Wesley, 2011) WW

The%20Developer's%20Guide%20to%20Social%20Programming%2C%202011

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 335

DownloadThe Developer's Guide To Social Programming - M. Hawker (Addison-Wesley, 2011) WW
Open PDF In BrowserView PDF
The Developer’s
Guide to Social
Programming

Developer’s Library Series

Visit developers-library.com for a complete list of available products

T

he Developer’s Library Series from Addison-Wesley provides
practicing programmers with unique, high-quality references and

tutorials on the latest programming languages and technologies they
use in their daily work. All books in the Developer’s Library are written by
expert technology practitioners who are exceptionally skilled at organizing
and presenting information in a way that’s useful for other programmers.
Developer’s Library books cover a wide range of topics, from opensource programming languages and databases, Linux programming,
Microsoft, and Java, to Web development, social networking platforms,
Mac/iPhone programming, and Android programming.

The Developer’s
Guide to Social
Programming
Building Social Context Using
Facebook, Google Friend
Connect, and the Twitter API
Mark D. Hawker

Upper Saddle River, NJ • Boston • Indianapolis • San Francisco
New York • Toronto • Montreal • London • Munich • Paris • Madrid
Cape Town • Sydney • Tokyo • Singapore • Mexico City

Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in this book, and the publisher was aware
of a trademark claim, the designations have been printed with initial capital letters or in all capitals.
The author and publisher have taken care in the preparation of this book, but make no expressed or
implied warranty of any kind and assume no responsibility for errors or omissions. No liability is
assumed for incidental or consequential damages in connection with or arising out of the use of the
information or programs contained herein.
The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or
special sales, which may include electronic versions and/or custom covers and content particular to
your business, training goals, marketing focus, and branding interests. For more information, please
contact:
U.S. Corporate and Government Sales
(800) 382-3419
corpsales@pearsontechgroup.com
For sales outside the United States please contact:
International Sales
international@pearson.com
Visit us on the Web: informit.com/aw
Library of Congress Cataloging-in-Publication Data:
Hawker, Mark D.
The developer’s guide to social programming : building social context using Facebook,
Google friend connect, and the Twitter API / Mark D. Hawker.
p. cm.
ISBN 978-0-321-68077-8 (pbk. : alk. paper) 1. Online social networks. 2. Entertainment
computing. 3. Internet programming. 4. Google. 5. Facebook (Electronic resource) 6.
Twitter. I. Title.
HM742.H39 2010
006.7’54—dc22
2010020866
Copyright © 2011 Pearson Education, Inc.
All rights reserved. Printed in the United States of America. This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical,
photocopying, recording, or likewise. For information regarding permissions, write to:
Pearson Education, Inc
Rights and Contracts Department
501 Boylston Street, Suite 900
Boston, MA 02116
Fax (617) 671 3447
ISBN-13: 978-0-321-68077-8
ISBN-10: 0-321-68077-4
Text printed in the United States on recycled paper at RR Donnelley Crawfordsville in Crawfordsville,
Indiana.
First printing, August 2010

❖
To Mam and Dad, I am forever grateful for your
patience, understanding, love, and support.
More than you will ever know. And to my
brother, Dale, who continues to pleasantly
surprise us all. I will love you always.
“Some dreams are dressed in gossamer and
gumboots; ethereal hope undergirded by
practical endeavour.”
SarahJayne Vivian

❖

Contents at a Glance
I: Twitter
1 Working with the Twitter API

1

2 Diving Into the Twitter API Methods
3 Authentication with Twitter OAuth

21
45

4 Extending the Twitter API: Retweets, Lists,
and Location 61

II: Facebook Platform
5 An Overview of Facebook Platform Website
Integration 77
6 Registration, Authentication, and Translations
with Facebook 99
7 Using Facebook for Sharing, Commenting, and
Stream Publishing 115
8 Application Discovery, Tabbed Navigation, and the
Facebook JavaScript Library 137

III: Google Friend Connect
9 An Overview of Google Friend Connect

165

10 Server-Side Authentication and OpenSocial
Integration 193
11 Developing OpenSocial Gadgets with Google
Friend Connect 209

IV: Putting It All Together
12 Building a Microblog Tool Using CodeIgniter
13 Integrating Twitter, Facebook, and Google
Friend Connect 267

235

Table of Contents
I: Twitter
1 Working with the Twitter API
Twitter API Essentials
Twitter API Methods

3

Twitter API Parameters

6

Twitter API Return Formats
Accessing the Twitter API
cURL

10

11

12

Twitter-async

14

Twitter API Rate Limiting

17

Twitter API Error Handling
Summary

1

1

18

19

2 Diving Into the Twitter API Methods
Twitter API Methods
User Objects

23

Status Objects

26

Direct Message Objects
Saved Search Objects
ID Objects

21

21

28
29

30

Relationship Objects
Response Objects
Hash Objects

31
32

33

Twitter Search API

34

Introducing the Atom Syndication Format
Twitter Search API Methods
Summary

38

43

3 Authentication with Twitter OAuth
Introducing Twitter OAuth
OAuth Benefits
OAuth Definitions

46
46

45

45

34

viii

Contents

Implementing Twitter OAuth
Twitter OAuth Workflow

48
48

Test Tube: A Sample Twitter Application
Summary

50

59

4 Extending the Twitter API: Retweets, Lists,
and Location 61
Extending Twitter’s Core Functionality
Retweet API
Lists API

64

Geolocation API

68

Twitter Community Evolution
Platform Translations
Spam Reporting
Future Directions
Summary

61

62

71

71

72
74

76

II: Facebook Platform
5 An Overview of Facebook Platform Website
Integration 77
Facebook Platform for Developers
Facebook Platform

77

78

Registering a Facebook Application

79

Referencing a Facebook Platform Application
Facebook API, FQL, and XFBML
Facebook API and FQL
XFBML

97

Summary

98

81

84

84

6 Registration, Authentication, and Translations
with Facebook 99
User Authorization and Authentication

99

Logging In and Detecting Facebook Status
Logging Out, Disconnecting, and Reclaiming
Accounts 107

101

Contents

Connecting and Inviting Friends
Translations for Facebook

109

111

Preparing Your Application and Registering Text
Administering and Accessing Translations
Summary

111

113

114

7 Using Facebook for Sharing, Commenting,
and Stream Publishing 115
Content-Sharing and Live Conversation
Facebook Share

115

116

Facebook Widgets

118

Social Commenting and Stream Publishing
Comments Box
Open Stream API
Summary

120

120
123

135

8 Application Discovery, Tabbed Navigation,
and the Facebook JavaScript Library 137
Application Dashboards and Counters
News and Activity Streams

138

139

Games and Applications Counters

143

Navigating and Showcasing Your Application
Using Tabs 145
Configuring and Installing an Application Tab
Extending an Application Tab

149

Dynamic Content and the Facebook
JavaScript (FBJS) Library 157
Facebook Animation Library
Facebook Dialogs

157

160

Handling Events with an Event Listener
Summary

162

164

III: Google Friend Connect
9 An Overview of Google Friend Connect
Components of Google Friend Connect
Google Friend Connect Gadgets

165

165

166

146

ix

x

Contents

Google Friend Connect JavaScript API
Server-Side Integration

167

167

Google Friend Connect Plug-ins

168

Using the Google Friend Connect JavaScript API

169

Installing and Configuring the JavaScript Library
Working with Google Friend Connect Data
An Overview of the OpenSocial API
OpenSocial API Methods

169

171

173

173

The DataRequest Object

174

Fetching People and Profiles

176

Fetching and Updating Activities

177

Fetching and Updating Persistence

178

Color Picker: A Google Friend Connect
Application 181
Summary

191

10 Server-Side Authentication and OpenSocial
Integration 193
Server-Side OpenSocial Protocols and Authentication
Methods 193
Google Friend Connect Authentication Methods
OpenSocial Client Libraries

194

196

Using the PHP OpenSocial Client Library
with Google Friend Connect 197
Google Friend Connect Authentication Workflow
Setting Up a Server-Side Application
OpenSocial Data Extraction Principles
Summary

197

198
201

207

11 Developing OpenSocial Gadgets with Google
Friend Connect 209
An Overview of Google Gadgets

209

Anatomy of an OpenSocial Google Gadget
OpenSocial v0.9 Specification

Advanced OpenSocial Gadget Development
Creating a Google Gadget

222

Color Picker, Revisited

222

Testing, Tracking, and Directory Submission
Summary

233

210

214
217

230

Contents

IV: Putting It All Together
12 Building a Microblog Tool Using CodeIgniter
An Overview of CodeIgniter

235

235

The Model-View-Controller Architectural Design

236

Installing, Configuring, and Exploring CodeIgniter
CodeIgniter Libraries
CodeIgniter Helpers

237

240
245

Building the Basic Sprog Application

246

Stage 1: Creating the Registration, Login, and Home
Pages 247
Stage 2: Extending the Sprog Application with Updates,
Comments, and Likes 257
Summary

266

13 Integrating Twitter, Facebook, and Google Friend
Connect 267
Implementing Twitter Functionality

267

Setting Up Twitter and Twitter-async Support

268

Stage 3: Extending the Sprog Application
with Twitter Functionality 270
Updating a User’s Twitter Account

276

Implementing Facebook Functionality

279

Registering a Facebook Application and Adding
Facebook Support 279
Stage 4: Extending the Sprog Application with
Facebook Functionality 281
Implementing Google Friend Connect Functionality
Registering and Adding Google Friend
Connect Support 292
Stage 5: Extending the Sprog Application
with Google Friend Connect Functionality 294
Summary

Index

301

303

292

xi

Preface
The World Wide Web is in constant flux and, since the introduction of utilities such as
Facebook and Twitter, has only recently had social interaction at its core. Currently,
Facebook and Twitter have more than 400 million active users, and the Facebook
Platform alone is integrated with more than 250,000 websites and applications, engaging
over 100 million Facebook users each month.These numbers continue to increase each
day. Another dominant force is Google, who introduced their Friend Connect, which
enables users to add social functionality to any of their websites. All three companies
continue to roll out massive changes to their development platform, rendering previous
best practices obsolete.
However, just knowing the technical aspects of each platform is not a guarantee that
it will succeed. It is important to also see how each is distinct and to prepare you for
changes through examples and sample code.The purpose of these examples is to provide
a springboard to build applications on, so there is plenty of room for extending and
adapting to suit your own needs.This book is one of the first of its kind to bring
together three of the most popular social programming platforms under one hood.
Welcome to social programming.

Who This Book Is For
This book is written for beginner or intermediate developers who are comfortable with
PHP and the major technologies of the Web: (X)HTML, JavaScript, and Cascading Style
Sheets (CSS), as well as Atom, JavaScript Object Notation (JSON), Really Simple
Syndication (RSS), and Extensible Markup Language (XML).The reader should also
have access to a web server, such as Apache or Internet Information Services (IIS), to test
code examples.
No prior experience of social programming is required, although some familiarity
and active user accounts with Facebook, Google, and Twitter is assumed.To be a good
developer for a platform, it helps to understand it from a user’s perspective.
This book will help the reader understand what makes a good Facebook, Google
Friend Connect, and Twitter application; explain and show how to use the core technologies of each platform; and build your confidence to develop engaging social
applications.

How This Book Is Structured
This book is divided into four main parts:
Part I,“Twitter,” provides an overview of the methods, authentication workflows, and
components of the Twitter API. It explains what is contained within the Twitter API,
including search, retweets, lists, and geolocation using code examples supported by a PHP
client library, twitter-async.
Part II, “Facebook Platform,” provides an overview of the service, including authentication, sharing, commenting, and publishing. A sample application is created,Test Tube,

highlighting key features of the platform through both client- and server-side scripting
using the Facebook Platform.
Part III, “Google Friend Connect,” showcases the service and its integration with
OpenSocial through client- and server-side scripting and the creation of a Google
gadget. A sample application, Color Picker, is created to demonstrate Google Friend
Connect in action.
Part IV, “Putting It All Together,” pulls each of the three social platforms together into
a coherent whole and demonstrates how to create your very own microblog from
scratch. A sample application, Sprog, is created using a popular web application framework, CodeIgniter, which is extended using select functionalities from Twitter, Facebook,
and Google Friend Connect.

Contacting the Author
If you have any questions or comments about this book, please send an e-mail to
socialprogramming@gmail.com.You can also visit the book’s website, http://www.
socialprogramming.info, for updates, downloadable code examples, and platform news.
An active code repository will be maintained, http://github.com/markhawker/SocialProgramming, which you can use to post issues you have with the code and to download future updates.

Acknowledgments
Writing this book has been one of, if not the, greatest and most thrilling experiences of
my life.This adventure has been supported by a great number of people. First, I want to
thank my acquisitions editor,Trina MacDonald, who was always there to listen and support me when I had queries and really helped shape the book. I appreciate the encouragement given through some tough and challenging times. Second, I’d like to thank my
development editor, Songlin Qiu, for her advice and insight; my technical editors, Joshua
Gross, Ben Schupak, and Joseph Annuzzi, who did an excellent job testing and correcting my source code; and Olivia Basegio for keeping us all in check. Others who offered
excellent advice and direction include Doug Williams at Twitter, Patrick Chanezon, Arne
Roomann-Kurrik, Bob Aman and Chris Schalk at Google, and Jaisen Mathai.Thanks
also to my connections on Twitter and Facebook for being with me from the beginning,
including Kevin Makice and Dusty Reagan, and to Raj Anand and Dr. Lydia Lau for
their input on my original proposal.
A final, special mention goes to SarahJayne Vivian for keeping me inspired and motivated, and for showing me the true meaning of friendship.Thank you. It truly has been
an amazing journey and one that I will never forget.

About the Author
Mark Hawker is a social applications developer and consultant focused on developing
for social platforms such as Facebook and Twitter. He is a graduate from the University
of Leeds, United Kingdom, with a First-class Honors degree in Informatics. A researcher
in the field of health informatics, Mark focuses his time on how to innovatively apply
social networking technologies in a wide variety of consumer health scenarios.

1
Working with the Twitter API
Talsohewithin
beauty and success of Twitter lies in its simplicity. It’s simple not just for its users but
its rich application programming interface (API), which provides you the
tools required to interact with Twitter’s internal services.The Twitter API is responsible
for more than 90% of Twitter server traffic and provides the gateway to much of Twitter’s
core functionality, such as status updates, direct messaging, and searches.As the Twitter
platform evolves, more features will be added to the Twitter API, so this book will serve as
a complement to the expanding online Twitter documentation. Recent enhancements
include the Geolocation API, Lists API, and the Retweet API (each of which is covered in
Chapter 4,“Extending the Twitter API: Retweets, Lists, and Location”).
This chapter explains a number of building blocks, such as methods, authentication,
return formats, and status codes that will enable you to start interacting with the service.
Interaction with the Twitter API is described using a command-line interface (cURL),
and in this chapter, you are introduced to a PHP client library developed by Jaisen Mathai
called twitter-async, which supports basic authentication as well as Twitter OAuth, which
is covered in Chapter 3,“Authentication with Twitter OAuth.”At the end of this chapter,
you will have gained an understanding of the Twitter API and developed the necessary
skills to start interacting with the service. From here, Chapter 2,“Exploring the Twitter
API and Search API,” will guide you through Twitter API return objects to give you an
in-depth understanding of how to interpret responses to suit all of your applications.

Twitter API Essentials
The Twitter API enables desktop and Internet-enabled third-party applications to interact
with Twitter services in a standard and easy-to-use way.An API is a conduit that enables
data from one application or service, in this case Twitter, to be shared with the outside
world. By making requests to the Twitter API, data is returned in a structured format that
makes it easy to parse and extract information from that data.The Twitter API separates
the functionality of the site into small, manageable functions, such as “get a list of followers” or “change a profile background” via a number of methods.

2

Chapter 1 Working with the Twitter API

Counting to 140
Twitter imposes a limit of 140 characters, or more technically 140 bytes, to updates (primarily because of the size restrictions of cell text messages). Although the Twitter API accepts
longer strings of text, those messages are truncated. Because Twitter uses the UTF-8 character set, it is possible to represent each of the 128 ASCII characters, which consume 1
byte, plus special Unicode and international characters, which can consume up to 4 bytes.
This is why tweets with special characters are truncated even though they are technically
140 characters in length. Twitter uses the Normalization Form C (NFC) convention for counting update length, which can be evaluated using the Normalizer class in PHP.

The Twitter API is a Representational State Transfer (REST)-based resource exposed
over HTTP(S), which means that “accessor” methods (those that retrieve data) require a
GET operation and “mutator” methods (those that create, update, or destroy data) require a
POST operation.
However, the Lists API methods require that you use a PUT operation for updating data
and also a DELETE operation for destroying data.This is discussed in Chapter 4 because it is
slightly removed from the conventional structures of the other Twitter API methods.The
DELETE operation instructs the Twitter servers to remove the requested resource and does
not return a response value to guarantee that this has been performed successfully. It is
recommended that applications use the POST operation wherever possible because both
successful and unsuccessful attempts will be reported to the requestor.
REST-based web services such as the Twitter API consist of three elements:
n

HTTP operation
How the request is being transferred to the Twitter API.The transfer operations are
GET, POST, PUT, and DELETE, as described earlier, and which operation is appropriate
depends on the method being executed. Supplying an incorrect operation will result
in an error.

n

Method
A URL that points to the location of a resource on Twitter’s servers.A list of methods appears in the next section, and Chapter 2 further describes these methods.
Methods can also include a number of parameters for customizing requests (for
example, returning only a certain number of values) or for supplying update text.

n

Return format
The format in which to return data back, which must be supported by that method.
Twitter accommodates Extensible Markup Language (XML), JavaScript Object
Notation (JSON), Really Simple Syndication (RSS), and Atom return formats
depending on the method that has been executed. For example, changing the URL
extension of a request from .xml to .json will adjust the return format.

The Twitter API has many different components. For example, the REST API and
Search API include methods for accessing Twitter services (for instance, updating timelines, status data, and user data), for searching timelines and trend data, and for user
authentication (see Chapter 3).Three other components of the Twitter API are the

Twitter API Essentials

Retweet API (for accessing and creating retweets), the Lists API (for accessing and creating
lists), and the Geolocation API (for geotagging tweets).These components are discussed
more fully in Chapter 4. Each Twitter API component functions in a similar way, sharing
parameter conventions and returning data in standard file formats, which makes each
component an intuitive service.

Twitter API Methods
Twitter API Versioning
The Twitter API supports versioning, which means that Twitter will be able to provide beta
functionality without compromising stable code. There are currently two method address
conventions: one for search methods, http://search.twitter.com/; and one for other
methods, https://api.twitter.com/<>/. In the second case, you can replace
<> with the version number that you intend to use, which should be set to 2 (the
latest release version as of this writing). Twitter expects that deprecation between old and
new versions will take approximately six months, and so you have plenty of time to update
code before changes become permanent.

The official Twitter API documentation groups methods into “categories” which can be
identified by the method stub. For example, the users/show method is part of the User
method category.The method stub will help you translate methods back into the language
used by Twitter to describe the methods in their official documentation. Most categories
are organized logically and include methods to perform each of the standard CRUD
(Create, Read, Update, and Delete) operations.The Search API methods that have the
stubs search and trends use the https://search.twitter.com/ prefix, and all other methods
use the https://api.twitter.com/2/ prefix.The Lists API methods have been deliberately
excluded here because they use a slightly different structure and are detailed in Chapter 4.
Where methods show an <> parameter, this must be replaced with a valid Twitter
user identifier, such as a screen name, as explained in the next section.All methods should
be appended with a .<> to denote which format the method should return.
Accessor Methods
These methods require a GET operation for extracting data from Twitter and are split into
the following categories:
n

Account methods
The account/rate_limit_status method returns the number of requests that a
user has remaining before his limit is refreshed.At the time of this writing, users
had approximately 150 requests available to them per hour.The account/verify_
credentials method checks whether a user’s credentials, in the form of a username
and password or OAuth tokens, are valid and returns an error or User object (see
Chapter 2) if successful.

3

4

Chapter 1 Working with the Twitter API

n

Block methods
The blocks/blocking method returns a collection of users that a user has blocked
on Twitter.The blocks/blocking/ids method returns the same collection of users
as the blocks/blocking method, although you are given only their user identifiers.
The blocks/exists/<> method checks whether a specified user has been
blocked by the authenticated user.

n

Direct messages methods
The direct_messages method retrieves a number of messages that a user has
received and works alongside the direct_messages/sent method, which refers to
the messages that the authenticated user has sent.

n

Favorites methods
The favorites method returns a number of updates that a user has marked as a
favorite. Favorites in Twitter are similar to bookmarks in a web browser.

n

Friendships methods
The friendships/exists method returns a simple true or false if two users are
following each other. In addition, the friendships/show method can be used to
extract more detailed information, such as whether the follow is reciprocated.

n

Help methods
The help/test method can be used to check whether the Twitter API is up and
running and does not count toward a user’s rate limit.

n

Saved searches methods
The saved_searches method returns a list of search terms that the authenticated
user has saved.A particular search can be retrieved via the saved_searches/show/
<> method.

n

Search methods
The search method is used to perform powerful searches and is covered in detail in
Chapter 2.

n

Social graph methods
The followers/ids and friends/ids methods return the identifiers of all the followers and friends a user has. For users with large numbers of connections, this can
be iterated over to retrieve them all.

n

Status methods
The statuses/retweets/<> method retrieves a number of statuses that have
“retweeted” the original <> update.The statuses/show/<> method
simply returns the Status object (see Chapter 2) for a given <>.

n

Timeline methods
The statuses/friends_timeline, statuses/home_timeline, statuses/public_
timeline and statuses/user_timeline methods return a collection of Status

Twitter API Essentials

objects (see Chapter 2) for a user’s friends, everyone on Twitter, or a specific user. In
addition, mentions (updates that reference a particular user) of the authenticated
user can be retrieved through the statuses/mentions method.Three retweet
methods exist and are covered in Chapter 4: statuses/retweeted_by_me,
statuses/retweets_of_me, and statuses/retweeted_to_me.
n

Trends methods
The trends method can be used to return the topics that are currently “trending”
on Twitter.To refine this search, you can also use the trends/current, trends/
daily, and trends/weekly methods. In addition to these three methods,Twitter has
two “local trends” methods—trends/available and trends/location—which
return trends for a given area (for example, the buzz in London or San Francisco).

n

User methods
The final set of methods is for returning details about users such as extracting the
details of followers (statuses/followers) and friends (statuses/friends), but
also for specific users via the users/show and users/lookup methods.Twitter
enables you to search for users via the users/search method, and to access suggested users through the users/suggestions and users/suggestions/
<> methods.

The next group of methods is contained within the same categories but is now for creating, updating, and deleting Twitter data.
Mutator Methods
In addition to the accessor methods described in the preceding section, you might also
want to manipulate Twitter data.These methods require a POST operation for mutating
Twitter data and are split into the following categories of methods:
n

Account
Twitter maintains a concise profile for every user that can be updated via the
account/update_profile method.This can be used to update their name, description, and location.You can also update colors and images via the account/update_
profile_background, account/update_profile_colors, and account/update_
profile_image methods. For users who want updates to be sent to their cell
phone, you can set the account/update_delivery_device method. Finally, for
ending a Twitter session, you should use the account/end_session method, which
logs your user out of your application and Twitter.

n

Block
One method exists for blocking nuisance users (blocks/create/<>), and
another exists for unblocking should a user change his mind (blocks/destroy/
<>).

5

6

Chapter 1 Working with the Twitter API

n

Direct messages
Some applications may want to send or delete messages on behalf of their users.The
direct_messages/destroy/<> and direct_messages/new methods exist for
such a use case.

n

Favorites
If you want to manage a user’s favorite tweets in your application, both the
favorites/create/<> and favorites/destroy/<> methods should
come in handy. Simply supplying an <> will add or remove a favorite from a
user’s profile.

n

Friendships
For managing a user’s friends list, the friendships/create/<> and
friendships/destroy/<> methods are particularly useful for creating and
destroying connections. Like the methods for manipulating favorites, all you need to
provide is an <> of the user to follow or un-follow.

n

Notifications
If users request to receive updates to their cell phone, you can use the
notifications/follow/<> and notifications/leave/<> methods to
set which friends they receive updates from.

n

Saved searches
Users sometimes may want to store frequently requested searches into their profile
so that they are easy to access at later dates.The saved_searches/create and
saved_searches/destroy/<> methods make this action seamless.

n

Statuses
You can use status methods to create statuses (statuses/update) and to delete
them (statuses/destroy/<>).You can also use a status method to retweet a
status (statuses/retweet/<>).

Instead of describing each method (and its parameters) in any more detail in this chapter, this discussion will follow an object-oriented approach, describing each return value as
an “object” (see Chapter 2). From just the methods listed here, you can perhaps start to
understand the size of the Twitter API and get an idea about which methods can be
accessed when connecting to the Twitter API later in this chapter.The remainder of this
section defines the many parameters available to tailor Twitter API method requests. Some
methods require parameters to be set, such as user identifiers or update text, but most do
not (and function just fine).

Twitter API Parameters
Parameters are particularly important because they can be used to customize the outputs
of requests and they affect data sent to the Twitter API in update, create, or delete operations.Twitter promotes the use of parameters such as since_id, max_id, and cursor in

Twitter API Essentials

timeline requests to reduce the burden of requests on its servers (not that a full result set
does not have to be returned each time the method is executed).You can set parameters
by either appending them to the method request if using GET operations such as
https://api.twitter.com/1/users/show.xml?id=markhawker and by adding additional
parameters separated by an ampersand (&) or by including them within POST, PUT, or
DELETE operations.The following section explores both approaches.
Coverage and Deprecation
Not all parameters are available for each of the Twitter API methods and may change over
time. Chapter 2 covers each parameter in detail. Parameters for the Lists API are defined in
Chapter 4 because this is a newer component that uses different naming conventions.

The Twitter API uses UTF-8 character encoding for all parameters, which means that
special characters such as the ampersand (&) and equals (=) characters must be encoded
before being sent to Twitter. Most programming languages contain functions for performing this conversion for you; for example, htmlentities(). Encoding special characters
will take up more storage than a single-byte character, which means that some requests
may be rejected if they are over Twitter’s 140-character limit.A list of the most popular
parameters that you can use when interacting with the Twitter API have been gathered
and categorized into parameters that affect input and parameters that affect output.
Parameters that can be used in both Search API methods and in other Twitter API
methods are denoted by an asterisk (*) character, whereas parameters exclusive to the
Search API are denoted by a caret (^) character.
Parameters Affecting Input
These parameters affect data that is sent to the Twitter API:
n

description, email, location, name, url

These parameters can be any set of alphanumeric characters and should be limited
to a maximum length of 20, 40, 100, 30, and 160 characters, respectively.The email
parameter must be a valid e-mail address.
n

follow

Boolean true or false parameter used when you want to enable notifications for a
target user and to follow that user.
n

image

Used for setting a user’s profile image or background and requires multipart form
data rather than a URL or raw image bytes.The content-type must be a valid GIF,
JPEG, or PNG image. In addition size restrictions apply: < 2,048 pixels and 800KB
for backgrounds and < 500 pixels and 700KB for profile images.
n

in_reply_to_status_id

Used for associating a mention with an original status. If the identifier is not valid,
or not the username mentioned within the update, the parameter is just ignored.

7

8

Chapter 1 Working with the Twitter API

n

lat, long

The latitude and longitude of the update, which must be a number set within the
range -90.0 to +90.0, and where north and east are positive.These parameters are
ignored if outside that range, if not a number, if geo_enabled is disabled, or if they
are not sent in pairs.
n

profile_background_color, profile_link_color, profile_
sidebar_border_color, profile_sidebar_fill_color, profile_text_color

Used for setting a user’s profile colors and must be set to a valid hexadecimal value.
Values may be either three or six characters in length; for example, fff and ffffff
are equivalents for the color white.You do not need to include the hash (#) character when using this parameter.
n

query

The saved search query that the user would like to save.
n

source

To help users identify which tool has published a tweet,Twitter has provided this
parameter, which can contain a short string for identifying your application.The
parameter will be returned as a URL-encoded string containing a hyperlink to your
application.Applications that use OAuth have this parameter set by default.
n

status, text

Used for setting a user’s status or within a direct message.To avoid truncation, the
string of text should be within 140 characters when encoded.
n

tile

Boolean parameter used to set whether a profile background image should be
“tiled” onscreen. Otherwise, it will remain in a fixed position in the top-left corner
of a profile page.
Parameters That Affect Output
These parameters affect data requested from the Twitter API:
n

callback*

For client-side JSON requests, the callback parameter can be set to a JavaScript
function name, which will automatically be sent the return data to parse.
n

count, page*, rpp^

Twitter imposes pagination limits, but you can combine count and page parameters
to retrieve the maximum number of results. For example, by setting count to 100,
you can iterate through pages 1–32 to extract all available status updates. Note that
the page parameter begins with 1, not 0.These parameters are scheduled to be deprecated in favor of cursor-based pagination.The rpp parameter is specific to the
Search API and is akin to the count parameter.The default is 15, but this can be
increased to 100 entries.

Twitter API Essentials

You can use the page parameter in conjunction with rpp to extract the maximum
number of results, which is currently 1,500. If you exceed Twitter’s pagination limits, an empty result set will be returned. Currently, the Search API will return results
up to 1.5 weeks in the past, but this might increase or decrease in the future as the
number of updates per day continues to increase.These parameters are set to be
replaced by the cursor parameter.
n

cursor

Setting a cursor breaks requests into “pages,” each with 100 results. Providing a
value of -1 begins paging, and the Twitter API will then return next_cursor and
previous_cursor parameters within responses so that you can “scroll” through
requests.Twitter also returns next_cursor_str and previous_cursor_str, which
are the string-based equivalents of the next and previous integers.
n

geocode^

For returning updates within a given radius (mi or km) of a latitude/longitude in the
format latitude,longitude,radius. Remember to URL-encode commas (,) to
code %2C.
n

id, user, user_a, user_b

When referencing a user, the id parameter can be set to either the integer user_id
or alphanumeric screen_name of a user or an integer identifier of a valid status,
direct message, or saved search.
n

lang^, locale^

To search for updates in languages other than English, use this parameter along with
the country’s two-letter ISO 639-1 code.
n

lat, long

The latitude and longitude of the location to return trending topics for which must
be a number set within the range -90.0 to +90.0, where north and east are positive.
n

max_id*, since_id*

An integer used to return status updates or direct messages that have identifiers
greater or less than that integer. For example, to show all statuses published more
recently than a particular status, say 12345, you set the since_id to 12345.
However, if you want to show all of the statuses that were posted before that particular status, you set the max_id to 12345 instead.
n

per_page

An integer used to control the number of results returned when searching for users.
This must be less than 20.
n

q*

The search query or username to be requested, which must be URL-encoded and
no larger than 140 characters.

9

10

Chapter 1 Working with the Twitter API

n

screen_name, source_screen_name, target_screen_name

The “friendly” alphanumeric name or username of a Twitter user, which is not the
same as a user_id, but it is possible that a screen_name may contain just numeric
characters. In this case, the screen_name parameter would be set to distinguish it
from a user_id. For example, a valid screen_name may be 1234567890, which
could also be interpreted by Twitter as a valid user_id value.
n

show_user^

When set to true, this parameter is used to prefix updates with : for
readers that do not display Atom’s author element.The default value for this
parameter is false.
n

source_id, target_id, user_id

The numeric identifier for a user, which remains fixed, unlike the screen_name
parameter, which can be changed by the user. It is recommended that you work
with and store this parameter rather than screen_name for your applications.
n

woeid

For retrieving location-specific trending topics, a Where on Earth IDentifier
(WOEID) is required.
The final part of this section looks at the return formats accepted by the Twitter API.
With this final piece of knowledge, you can start accessing and interacting with the
Twitter API to retrieve data.

Twitter API Return Formats
For successful requests, you should expect the Twitter API to return data back in the format that you requested.The Twitter API supports four MIME types for formatting
returned data:
n

JSON
JavaScript Object Notation is a lightweight data-interchange format favored in
AJAX applications and is considered a simpler and faster alternative to XML.
Defined in a structured format, JSON is object based, and simple text can be used
to represent many different data types and relationships. It is the favored MIME type
of the twitter-async client library, which is used throughout Chapters 2, 3, and 4.
JSON is the only data format supported by all the Twitter API methods, and so it’s
particularly important for you to understand it.

n

RSS and Atom
Really Simple Syndication is a standard form of XML commonly used on blogs and
news sites.Atom was created as an alternative to RSS to accommodate some of the
flaws in the RSS protocol and to improve international support. Both RSS and
Atom are used to accommodate people who want to “subscribe” to Twitter information streams, such as the public timeline or a particular user’s timeline.

Accessing the Twitter API

n

XML
Extensible Markup Language is a general-purpose language for specifying custom
markup languages.The language is extensible in that users can define their own tags
and structure. XML is used to structure data in a way that separates content from
presentation: a guiding principle of Web 2.0.

Not all methods support all of these data formats. Support for each of the methods will
be clearly identified as you explore the Twitter API in more detail in Chapter 2.As a comparison to XML, JSON returns a set of “key/value” pairs nested within curly braces. For
example, using the users/show method with the screen_name parameter set to
“markhawker” with JSON output would produce the following, which has been snipped
for brevity because we’re just comparing the two formats:
{
"screen_name":"markhawker", ..., "status":{
"text":"Testing JSON and XML output formats.", ... }
}

Whereas the same users/show request in XML would produce the following:

markhawker
...

Testing JSON and XML output formats.
...



As you can see, the two formats are comparable and return exactly the same data. It is
easy to “translate” JSON into a PHP object by using the json_decode() function, which
can then be manipulated in your applications.This complexity is handled for you if you
choose to use the twitter-async client library, which handles JSON responses by default.
The basics of the Atom file format are described in Chapter 2 when interacting with the
Search API, although it is not a requirement to use the format at all (because JSON is supported by all Twitter API methods).

Accessing the Twitter API
Most Twitter API requests require user authentication to access data that is not otherwise
open to the public, such as direct messages or favorites, and to control Twitter rate limiting. Historically,Twitter has implemented Basic Authentication, whereby user credentials
in the form of a username and password combination are sent in the header of a request.
Although this method is easy to use, it is prone to security risks, even if sent over a secure
connection, due to usernames and passwords being transferred across the Internet.A better, and safer, method that which implements open authentication (OAuth) has been
developed (see Chapter 3).

11

12

Chapter 1 Working with the Twitter API

Authorized Connections
The “Connections” tab inside a Twitter profile lists OAuth applications that users have
authorized on their Twitter account. From there, users can choose the “Revoke Access”
option to de-authorize unwanted applications.

Twitter has not set a deadline for deprecating Basic Authentication, but it is only a matter of time. For this reason, it is important that you get to grips with OAuth as soon as
possible.You can enable Basic Authentication by either typing the methods into your
browser’s address bar or by using a command-line application known as cURL. For production applications, you will require something more sophisticated, and so this section
also details how to make Twitter API requests using a client library called twitter-async. If
you intend to use another client library or programming language, the platform-independence of cURL should help guide you more than being taught how to interact with the
Twitter API using a specific programming language.The elegance and simplicity of twitter-async makes it a great choice for developing Twitter applications from the ground up.

cURL
The cURL application provides a way of accessing URL resources from the command
line and functions much like a text-based web browser. If cURL is not already installed on
your computer, you can download it for free from http://curl.haxx.se/download.html for
almost any operating system. If you download the version with Secure Sockets Layer
(SSL), you need to ensure that all the necessary files are included in the package.You can
find whether you have all the necessary files by navigating to the directory where you
have saved the cURL files and trying to run the command curl. If you get the following
response, you’ve succeeded:
curl: try "curl --help" or "curl --manual" for more information

If you get an error response saying that your operating system was unable to find a
specified component, it is recommend that you try another download source (of which
there are usually multiple sources for each version of cURL).Alternatively, search for the
component online or check the cURL FAQ (http://curl.haxx.se/docs/faq.html).You can
also run any of the method URLs directly from your web browser, although it is recommended that you change the file format from JSON to XML because browsers display
XML more elegantly inline.The web method works only for accessor methods, those that
pull data from Twitter, and cannot be used for actions such as creating tweets or sending
direct messages, which is why cURL is recommended.
If you are happy to try out cURL, here are some useful commands to help you interact
with the Twitter REST API from the command line:
n

curl

After you have navigated to the directory where you installed cURL, you can use
this command in the command line to initiate a cURL request.

Accessing the Twitter API

n

-A "Name Of Your User Agent"

This is used to set the user agent of the request.Twitter requires that you set this
parameter so requests can be attributed to particular applications and debugged by
the applications’ respective programmers.
n

-d

The –d switch is used to send unencoded data via POST. If you want to send a POST
request without parameters, just use –d "".
n

--data-urlencode "status=Hello, world."

The --data-urlencode switch is used to send URL-encoded messages—ones
including special characters and spaces—via a POST request.
n

-G

The –G switch is used to send –d data as a GET request so that parameters can be set
in the same way as in the switches described earlier (instead of appending them to
method URLs).
n

-H "Expect:"

The Twitter API may reject some cURL requests because it sometimes sets the
header parameter to Expect: 100-continue.This needs to be set to an empty field
to be valid.
n

-k

You might receive an error message when using the https:// prefix with requests
stating that the “certificate verify failed.”This verification process can be disabled by
supplying the –k switch.
n

-u <>:<>

Used for authentication where <> can be a Twitter screen_name, id or
email, and <>.Although cURL provides some security when sending
these details across the network, they might not be 100% secure. Using cURL with
SSL will help reduce the risk of a third-party phishing your Twitter credentials.
n

-v

Standing for verbose, this command-line switch will return the full HTTP headers
and additional server debugging information (for example, port names, user agent,
and cookie details).
As an example, you can run the following via cURL to display the public timeline
(which does not require authentication):
curl –k https://api.twitter.com/2/statuses/public_timeline.xml

13

14

Chapter 1 Working with the Twitter API

Returning the timeline of your followers requires user authentication. Remembering
to replace <>:<> with your actual username and password, try the
following:
curl –k –u <>:<>
https://api.twitter.com/2/statuses/home_timeline.xml

Getting more complex, to post an update which requires user authentication and a
parameter using a POST request, try this:

status

curl –k –u <>:<> --data-urlencode "status=Testing updating my
status with cURL."
https://api.twitter.com/2/statuses/update.xml

In addition to using the cURL command-line function, code examples using the twitter-async client library are provided in the next section to hint at how the Twitter API
functions inside a programming language such as PHP.

Twitter-async
You can download the twitter-async client library, which requires PHP 5.2+, from
http://github.com/jmathai/twitter-async. It contains just three files, enabling you to execute (a)synchronous calls to the Twitter API using Basic Authentication or OAuth.The
asynchronous element of twitter-async means that multiple requests can be executed in
parallel, instead of waiting idly for them to be executed serially (for example, sending multiple direct messages to a number of followers and then returning the results of each back
to the client application).The simplest twitter-async application you can make is one that
makes an unauthenticated call to the Twitter API, such as retrieving search trends:
$twitter = new EpiTwitter();
$trends = $twitter->get_trends();
echo $trends->responseText;

The preceding code shows the creation of the $twitter object, which is one of three
methods of initiating a request.The second is Basic Authentication, which is achieved by
supplying username and password parameters within the request. For example:
$user = $twitter->get_basic("/account/verify_credentials.json", null, "username",
"password");

The third method is using OAuth, discussed in detail in Chapter 3, which is the use of
a consumer key and consumer secret.The EpiTwitter object that was just created has
only two methods, one of which is constructing it! The second is executing the Twitter
API methods, which use the following naming convention:
n

The operation in lowercase, such as get, post, or delete, plus an underscore (_).
Operations that end in _basic are specifically for Basic Authentication or no authentication and must not be used for OAuth.

Accessing the Twitter API

n

n

The path to the Twitter API method that is in lowercase except for when there
needs to be a forward slash (/), which is denoted by a capital letter (for example,
usersShow). Underscores must be retained where appropriate, such as in the
account/verify_credentials method.
Parameters can be added by including an array inside the request, as follows:
usersShow(array("screen_name" => "markhawker")).

For example, the account/verify_credentials method can be called by using the
following:
$response = $twitter->get_basic("account/verify_credentials.json",
null, <>, <>);

Or, if you are using OAuth, you could use this:
$response = $twitter->get_accountVerify_credentials();

The client library also supports image uploading and exposing response headers, and it
provides additional functionality for exception handling.The following code can be used
to initiate the twitter-async library, assuming that it is stored within a directory called
twitter-async, which should be above your test page, which can be saved as index.php:
get_basic("/account/verify_credentials.json",
null, $username, $password);
if($response->code == 200) {
echo "

Username: ".$response->screen_name."

"; echo "

Description: ".$response->description."

"; } } catch(EpiTwitterException $e){ echo $e->getMessage(); exit; } catch(Exception $e) { echo $e->getMessage(); exit; } ?> The preceding code uses Basic Authentication, which you can replace with OAuth code after reading through Chapter 3.You should replace the $username and $password parameters with your own Twitter credentials.The example shows how a GET request can be initiated using your Twitter credentials and how exceptions can be handled. If the request for verifying a user’s credentials is successful, a status code 200 will be returned along with a User object (see Chapter 2), which is why you can extract their 15 16 Chapter 1 Working with the Twitter API screen_name and description.With a verified account, you can then extend the ple index.php file to also retrieve a user’s latest friends by using the following: 1 2 3 4 5 6 7 exam- echo "

Latest Friends

"; echo "
    "; $friends = $twitter->get_basic("/statuses/friends.json", null, $username, $password); foreach($friends as $friend) { echo "
  • ".$friend->screen_name.": ".$friend->status->text."
  • "; } echo "
"; Another way to access the $friends details is to use a for() loop and access each friend using $friends[$i]["screen_name"], ensuring that your counter is set to $i. Notice that you can also extract a user’s status via the embedded Status object accessible via $friend->status->text.The second parameter for this example was set to null, but you could also insert an array containing the parameters that you want to set. If you want to extract all the user’s friends, you must set “cursoring” by adding array("cursor" => -1) and then extracting the value of the next cursor and rerunning the request: 1 2 3 4 5 echo "

All Friends

"; echo "
    "; $cursor = -1; do { $friends = $twitter->get_basic("/statuses/friends.json", array("cursor" => $cursor), $username, $password); 6 foreach($friends->users as $friend) { 7 echo "
  • ".$friend->screen_name.": ".$friend->status->text."
  • "; 8 } 9 $cursor = $friends->next_cursor_str; 10 } while ($cursor > 0); 11 echo "
"; This do-while() loop initiates cursoring on Line 3 and then proceeds to return friends’ details until the cursor returns 0, which means that all the user’s friends have been returned.The foreach() loop should also be updated to replace $friends with $friends->users because cursoring places subsequent results within an array called users.A final example uses the asynchronous capabilities of twitter-async, which delays accessing results from requests for as long as possible.This might prove useful if you want to update a number of user accounts simultaneously or send multiple direct messages: $twitter->useAsynchronous(true); $users = array("user1", "user2", "user3", "user4"); // Edit Me $responses = array(); foreach($users as $user) { $responses[] = $twitter->post_basic("/direct_messages/new.json", Accessing the Twitter API array("user" => $user, "text" => "Hey, {$user}. What’s up?"), $username, $password); } echo "

Direct Messages

"; echo "
    "; foreach($responses as $response) { echo "
  • Direct Message: {$response->id}
  • "; } echo "
"; This code, alongside the other elements of index.php, should be uploaded to your web server.You’ll need all this in Chapter 2 when you experiment with more of the Twitter API methods. Twitter API Rate Limiting Rate limiting is Twitter’s way of controlling and regulating access to their servers, to provide equitable performance to all application developers and users.You may have seen the Fail Whale when you tried to access Twitter on the Web, and perhaps you’ve also seen “Rate Limit Exceeded” errors appearing on third-party applications that you may be using to access Twitter.This was their server’s way of saying they were overcapacity and needed a brief pause for breath. Two different limits apply to the number of requests per hour made to the Twitter API. For the Twitter API, the default rate is 150 requests per hour, through a mixture of account- and IP-based rate limiting.Therefore, if you reach the Twitter API limit on one third-party application, other applications will also be subject to that limit. In which case, you should access your account through the Twitter web client until your limits have been reset.The Search API is limited by IP address, but the rate limits are considered sufficient to not warrant a number being released on the number of requests per hour. POST and GET Rate Limiting Rate limiting affects only methods that request information via a GET request. This means that methods that use the POST, PUT, or DELETE requests to submit, update, or delete data (such as tweets) are not affected. Requests to the account/rate_limit_status method to check limit status are not charged, to provide developers access to how many free requests a user has. If you think your application might exceed those rate limits—for instance, if you intend to send out multiple messages or tweets—you can request to be “whitelisted” by filling out a request form (http://twitter.com/help/request_whitelisting) to increase your limits to 20,000 requests per hour.This process may take up to a week, but you will receive confirmation from the Twitter team if you have been whitelisted.Applications that repeatedly abuse their rate limits can also be “blacklisted” and are required to e-mail Twitter Support with further details as to why they keep reaching the limits.You can avoid the rate limiter in several ways, including caching results, prioritizing active users, and reducing the number of times a particular search is requested. 17 18 Chapter 1 Working with the Twitter API Twitter API Error Handling For error handling, methods that require a particular request will return a meaningful status code indicating whether the request was successful or not. If you’ve ever encountered a “404 – Page Not Found” or a “501 – Internal Server Error,” you’ve experienced status codes.These are just fancy “user-friendly” ways to present a status code error back to the browser in a meaningful way.The Twitter API uses a similar method of returning response codes and friendly error messages should a problem arise with a request. Twitter uses the following three-digit codes to report whether a request was successful and provides a description of the error encountered within a construct known as a Hash object (see Chapter 2), which is a simple structure containing the error code and a description from the Twitter API: n 200 – OK Your request was successful, and so you should receive back exactly what you requested from the Twitter API in the data format that you specified. n 304 – Not Modified There was no new data to return, and so you already have the most up-to-date data.This will occur if you make a request to a timeline in a period sooner than once per minute. n 400 – Bad Request The request was invalid.This could be because a method that required parameters may have been missed, formatted incorrectly, or a rate limit has been exceeded. n 401 – Not Authorized Authentication failed for the user details you provided.This means that a password has been supplied incorrectly. Check that it is correct and try again. n 403 – Forbidden The request was understood, but it was refused. Check the returned error text for an explanation.This may be due to rate limits being reached. n 404 – Not Found The method URL requested is invalid or does not exist. n 406 – Not Acceptable The method was formatted incorrectly when being requested from the Search API. Check that you have properly encoded the URL. n 500 – Internal Server Error, 502 – Bad Gateway, 503 – Service Unavailable Something is broken with Twitter; try again later. It may be that it is down or being upgraded, or perhaps its servers are overloaded with requests. Summary As an example,Twitter API error messages are returned in the requested format with an error message. For example, an XML error may look like this: /direct_messages/destroy/456.xml No direct message with that ID found. When you are using twitter-async, you can retrieve an error message from a response by using the $response->code and $response->error variables to return both the status code and error message, respectively. It is assumed that any request that does not return a status code 200 will need to be reformatted and requested again.This model makes it simple to enclose a request within a conditional statement to test for this occurrence.You can then choose whether to return this error message directly back to users or return a meaningful response indicating that they must resubmit their request.The most common error message will be that a rate limit will have been exceeded, and so sending a request for this data before submitting the response may be preferable, storing a cached value for the number of remaining requests for the duration of the session so that it is not being requested each time. Summary This chapter provided an overview of the Twitter API and its many methods, parameters, and return formats.Two tools that you can use to access the Twitter API were described: a command-line tool, cURL; and a PHP client library called twitter-async, which is used throughout Chapters 2, 3, and 4.This chapter also briefly explained how Twitter handles errors by returning meaningful status codes with requests, which you can use to either manipulate the data or manage a failed request.The next chapter identifies the types of data you can expect to retrieve from the Twitter API, including user data and status updates. 19 This page intentionally left blank 2 Diving Into the Twitter API Methods C hapter 1,“Working with the Twitter API,” explored the Twitter application programming interface and provided essential information you need when interacting with the Twitter API, such as return formats and response codes.The Twitter API is split into several method categories, but these are grouped together in this chapter, except for the Retweet API, Lists API, and Geolocation API (which are explored in Chapter 4, “Extending the Twitter API: Retweets, Lists, and Location”).The Twitter API contains a number of methods, including ones for sending updates, direct messages, following and unfollowing users, and account management.The Search API contains methods for extracting search and trend information from Twitter as a means of filtering, finding, and sorting the huge volumes of data. This chapter explores the numerous Twitter API methods in detail, illustrating them using an object-oriented approach focusing on their return values, and giving examples of each alongside sample output and source code.You can test the examples using the command-line cURL interface or via twitter-async, as described in Chapter 1. If you do not want to use cURL, you can access many of the Twitter API methods directly via the Twitter web interface by typing the commands into your web browser’s address bar and providing your Twitter username and password when prompted. Twitter API Methods Beware, Deprecation! As the Twitter API evolves, you may find that some attributes become deprecated. Instead of removing the attributes from their outputs, Twitter will set them to null where applicable. There is also the possibility that methods will become deprecated, which will result in an error being returned for method calls. 22 Chapter 2 Diving Into the Twitter API Methods To understand the methods that the Twitter API provides in conjunction with the parameters described in Chapter 1, it is important to explore the various outputs that you can expect when interacting with the service.These return “objects” include several useful pieces of data about a status or direct message, a user, or even an error or simple Twitter response.There are eight main objects in the Twitter API: n User objects n Status objects n Direct Message objects n Saved Search objects n ID objects n Relationship objects n Response objects Hash objects n Alongside sample XML responses for each of these methods to illustrate these return objects, a form of UML (Universal Modeling Language, a universal language and diagramming technique) is used to illustrate these return objects and the methods that can be used to expose them. Figure 2.1 provides an example of an object and the conventions that have been adopted in this chapter. Object Name +Attribute 1: Type +Attribute 2: Type #Attribute 3: Type +<> Method 1(Parameter 1:Type, Parameter 2:Type=20): Return File Format -<> Method 2(): Return File Format Figure 2.1 Skeleton that will be used to describe Twitter API objects. Several conventions have been adopted to fit in with the nature of the Twitter API, as follows: n Objects are divided into three “compartments”: a class name; attributes, which include types such as integer, string, or true/false Boolean values (and attributes can also be other objects; for example, in some instances, a User object also includes a Status object); and operations or methods, which will return back that object. Twitter API Methods n #element defines a protected element that requires user authentication for it to be returned (for example, when users have protected their status). Methods denoted with a hash (#) character mean that they can be executed without authentication but may not return all values. n -method n +method n <> denotes what operation be one of GET, POST, PUT, or DELETE. n Parameters are enclosed in brackets, and default values are identified with an equals (=) character. For example, count=20 means that the default value for the count parameter is 20. So, if the parameter is omitted, 20 values will be returned. Return formats appear after the method name and colon (:) and must be set to one of json, xml, atom, or rss. n defines a private method that must be executed with user authentication or will fail and return an error Hash object. defines a public method that does not require any user authentication to return all data. is required by the method, which can For each of the Twitter API objects, you’ll see an illustration of the object, a description, and example of what values to expect back from the service. In Chapter 1, a sample file was created, index.php, which is extended in this chapter with more calls to the Twitter API. User Objects User objects (see Figure 2.2) are full of interesting data about an individual or a set of individuals when wrapped inside a users array, such as when using statuses/friends or blocks/blocking methods.With any of the methods that use cursors for pagination, you should expect the return format to look like the following skeleton code block, which includes a collection of User objects plus indicators of the values of the next and previous cursors, which can be used to retrieve subsequent results: ... ... ... User objects are also embedded within Status objects to help reduce the number of calls made to the Twitter API. In this instance, they do not contain the embedded Status object as shown above. In Direct Message objects, there are also sender and recipient objects that are exactly the same as User objects but without the embedded Status object, which is why it defaults to a null value. 23 24 Chapter 2 Diving Into the Twitter API Methods User +created_at: Date +description: String +favourites_count: Integer +followers_count: Integer +following: Boolean = null +friends_count: Integer +geo_enabled: Boolean = false +id: Integer +location: String +name: String +notifications: Boolean = null +profile_background_color: String +profile_background_image_url: String +profile_background_title: Boolean +profile_image_url: String +profile_link_color: String +profile_sidebar_border_color: String +profile_sidebar_fill_color: String +profile_text_color: String +protected: Boolean +screen_name: String #status: Status = null +statuses_count: Integer +time_zone: String +url: String +utc_offset: String +verfified: Boolean = false -<> -<> -<> -<> account/verify_credentials(): json/xml blocks/blocking(page:Integer): json/xml blocks/exists/<>(): json/xml statuses/followers(cursor:Integer, id:String,screen_name:String, user_id:Integer): json/xml -<> statuses/friends(cursor:Integer, id:String,screen_name:String, user_id:Integer): json/xml #<> users/lookup(screen_name:String, user_id:Integer): json/xml #<> users/search(page:Integer,per_page:Integer=20, q:String): json/xml #<> users/show(id:String,screen_name:String, user_id:Integer): json/xml -<> account/update_delivery_device(device:String): json/xml -<> account/update_profile(description:String, email:String, location:String, name:String, url:String): json/xml -<> account/update_profile_background_image(image:Image, tile:Boolean=false): json/xml -<> account/update_profile_colors(profile_background_color:String, profile_link_color:String, profile_sidebar_border_color:String, profile_sidebar_fill_color:String, profile_text_color:String): json/xml -<> account/update_profile_image(image:Image): json/xml -<> blocks/create/<>(): json/xml -<> friendships/create/<>(follow:Boolean): json/xml -<> notifications/follow/<>(): json/xml -<> notifications/leave/<>(): json/xml -<> report_spam(id:String,screen_name:String, user_id:Integer): json/xml -<> blocks/destroy/<>(): json/xml -<> friendships/destroy/<>(): json/xml Figure 2.2 Twitter API User object including Status object. An example of a User object returned by requesting the https://api.twitter.com/1/users/show.xml?id=markhawker method currently contains the following keys and values in XML: 15397909 Mark Hawker markhawker West Yorkshire, United Kingdom Health informatics researcher and social application developer. Creator of @omnee. http://a3.twimg.com/profile_images/ 234974305/me_normal.jpg http://markhawker.tumblr.com/ false 1139 001313 Twitter API Methods 00131e 1d8395 e3f0f2 1d8395 185 Fri Jul 11 23:02:14 +0000 2008 131 0 London http://a3.twimg.com/profile_background_ images/35364101/collage.gif true 13859 false false ... Notice the Status object that is returned inside the status element for all nonprotected accounts, and keys, such as , which contain no data and use a shorthand opening and closing tag.The created_at key is used to show when an individual first started using Twitter. In this case, it was on July 11, 2008. By default, the majority of methods will return 100 users per page, so the cursor parameter is required to return details of all followers. Here are two examples using the twitter-async library and the sample code created in Chapter 1: $user = $twitter->get_basic("/users/show.json", array("screen_name" => "markhawker"), $username, $password); // $user = $twitter->get_usersShow(array("screen_name" => "markhawker"), $username, $password); $followers = $twitter->get_basic("/statuses/followers.json", array("cursor" => -1, "screen_name" => "markhawker"), $username, $password); // $followers = $twitter->get_statusesFollowers( array("cursor" => -1, "screen_name" => "markhawker"), $username, $password); If successful, each request should return a User object or an array of User objects, which can be accessed using a foreach($followers->users as $follower) or for() loop. Note that there are two distinct ways of forming the queries using either get_basic() or by using the Twitter API method name in the name itself, which will return equivalent results. In some instances, you might want to use the longhand version to extract data other than in JSON format. From the $followers data, the relevant next_cursor_str and previous_cursor_str parameters can be retrieved by using $followers->next_cursor_str or $followers->previous_cursor_str, respectively, 25 26 Chapter 2 Diving Into the Twitter API Methods which was demonstrated in Chapter 1. Each element of the $user can be accessed by using $user-> followed by the name of the element; for example, $user->id or $user>friends_count. If you want to access the Status object, you just use $user->status>id, where the id field can be replaced by any of the elements contained within the Status object (as described in the following section). The two variants to these methods are the users/suggestions and users/ suggestions/<> methods, which were not included in Figure 2.2.They can be used to access Twitter’s suggested user lists—such as users who are recommended from Business, Health, or Technology categories—and can be accessed as follows: $users = get_basic("/users/suggestions/health.json", null, $username, $password); echo "
    "; foreach($users->users as $user) { echo "
  • ".$user->screen_name."
  • "; } echo "
"; If you are unsure of category names, you can use the users/suggestions method to extract a list of categories and their associated “slugs,” which you can then use in the users/suggestions/<> method. Status Objects Status objects (see Figure 2.3) contain data about the user’s latest status update as well as geolocation data, which is explored in Chapter 4.The truncated key denotes that a status update was larger than the 140-character limit imposed by Twitter and has been truncated. The favorited key denotes whether the authenticated user has bookmarked that update, which can be accessed using any of the favorites methods. Other information contained within Status objects is the source of the update and information as to whether it was also a mention. Each Status object contains a User object minus its nested Status object. Multiple Status objects are enclosed inside a statuses array and can be accessed in the same way as the collection of User objects.An example of a Status object returned by requesting the https://api.twitter.com/2/statuses/show.xml?id=5327214528 method currently contains the following keys and values in XML: Sun Nov 01 01:08:45 +0000 2009 5327214528 Now, I really must sleep. Good night. Gravity false Twitter API Methods false ... Status +created_at: Date +favorited: Boolean +geo: String +id: Integer +in_reply_to_screen_name: String +in_reply_to status_id:Integer +in_reply_to_user_id: String +source: String +text: String +truncated: Boolean +user: User = null #<> favorites(id:String,page:Integer): atom/json/rss/xml -<> statuses/friends_timeline(count: Integer=20, max_id:Integer, page:Integer, since_id:Integer): atom/json/rss/xml -<> statuses/home_timeline(count:Integer=20, max_id:Integer, page:Integer, since_id:Integer): atom/json/rss/xml -<> statuses/mentions(count:Integer=20, max_id:Integer, page:Integer,since_id:Integer): atom/json/rss/xml +<> statuses/public_timeline(): atom/json/rss/xml -<> statuses/retweeted_by_me(count:Integer=20, max_id:Integer, page:Integer since_id:Integer): atom/json/rss/xml -<> statuses/retweets_of_me(count:Integer=20, max_id:Integer, page:Integer since_id:Integer): atom/json/rss/xml -<> statuses/retweeted_to_me(count:Integer=20, max_id:Integer, page:Integer since_id:Integer): atom/json/rss/xml -<> statuses/retweets(count:Integer, id:Integer): json/xml #<> statuses/show/<>(): json/xml -<> statuses/user_timeline(id:String, screen_name:String, user_id,count:Integer=20, max_id:Integer, page:Integer, since_id:Integer): atom/json/rss/xml -<> favorites/create/<>(): json/xml -<> statuses/update(in_reply_to_status_id:Integer, lat:String,long:String, status:String): json/xml -<> favorites/destroy/<>(): json/xml -<> statuses/destroy/<>(): json/xml -<> statuses/retweet/<>(): json/xml Figure 2.3 Twitter API Status object including User and Retweet objects. You will notice that within some Status objects (such as the statuses/home_ method, which replaces the deprecated statuses/friends_timeline) there are Retweet objects denoting that a particular status was retweeted.These are explained in more detail in Chapter 4. Like User objects, these may not be included in all situations, and so they may be null or unavailable. Here is an example using the twitter-async library to update a status: timeline $status = $twitter->post_basic("/statuses/update.json", array("status" => "This is a test status."), $username, $password); Again, this could also be achieved by using the $twitter->post_statusesUpdate() convention with equivalent outcomes.The results of this request can be extracted by 27 28 Chapter 2 Diving Into the Twitter API Methods either using $status->responseText or by accessing fields directly such as $status->id, which returns the identifier for the new status update. Direct Message Objects Direct Message objects (see Figure 2.4) contain all you need to know about the message, the sender, and the recipient.The sender and recipient elements are User objects without embedded Status objects, which were discussed earlier in this chapter.This is one of the advantages of adopting an object-oriented approach: Structures can be reused multiple times. Direct Message +created_at: Date +id: Integer +recipient: User +recipient_id: Integer +recipient_screen_name: String +sender: User +sender_id: Integer +sender_screen_name: String +text: String -<> direct_messages(count:Integer=20, max_id:Integer,page:Integer, since_id:Integer): atom/json/rss/xml -<> direct_messages/sent(count:Integer=20, max_id:Integer, page:Integer, since_id:Integer): atom/json/rss/xml -<> direct_messages/new(user:String, screen_name:String, user_id:Integer, text:String): json/xml -<> direct_messages/destroy/<>(): json/xml Figure 2.4 Twitter API Direct Message object. A sample Direct Message object that can be obtained from any of the methods from Figure 2.4 looks like this: 154217109 15397909 Testing out the @twitterapi and Direct Message Objects. XXXXXXXX Wed Jun 03 19:49:27 +0000 2009 markhawker XXXXXXXX ... ... Twitter API Methods Multiple Direct Message objects are enclosed within a direct-messages array, and individual message elements are listed as direct_message. Notice the subtle use of an underscore (_) for individual elements and a hyphen (-) for the array name if you are looking to parse results using regular expressions or other means.As an example, you should add the following code to your index.php file: echo "

Direct Message Objects

"; $direct_messages = $twitter->get_direct_messages(array("count" => 2), $username, $password); echo "
    "; foreach($direct_messages as $direct_message) { echo "
  • ".$direct_message->text."
  • "; } echo "
"; What this code will print out is the text from the authenticated user’s latest two direct messages.You can modify this by adjusting the count parameter and by adding a page parameter to view older direct messages. Saved Search Objects Four methods enable you to manipulate information about searches that users have saved to their profile. For example, a search could be saved for a specific keyword (for example, healthcare), which saves the user time inputting the keyword multiple times across different applications to perform the same search. Saved Search objects (see Figure 2.5) contain five keys for defining a search query that a user has saved: id, name, query, position, and created_at. Saved Search +created_at: Date +id: Integer +name: String +position: Integer +query: String -<> saved_searches(): json/xml -<> saved_searches/show/<>(): json/xml -<> saved_searches/create(query:String): json/xml -<> saved_searches/destroy/<>(): json/xml Figure 2.5 Twitter API Saved Search object. 29 30 Chapter 2 Diving Into the Twitter API Methods A sample Saved Search object in XML looks like this: 333753 healthcare healthcare Sun Jun 07 13:36:37 +0000 2009 The position key denotes the absolute position of a Saved Search object in the saved_searches array, which is returned from the saved_searches method.This value can be empty or an integer starting from 1. In the instance above, it is empty because it is the only saved search available.To retrieve a collection of saved searches, you should modify index.php to include the following: echo "

Saved Search Objects

"; $saved_search = $twitter->post_saved_searchesCreate(array("query" => "test"), $username, $password); echo "

Saved Search: ".$saved_search->id."

"; $saved_searches = $twitter->get_saved_searches(null, $username, $password); print_r($saved_searches->responseText); $delete_saved_search = $twitter->post_basic("/saved_searches/destroy/ {$saved_search->id}.json", null, $username, $password); echo "

Deleted Search: ".$delete_saved_search->id."

"; The preceding code will create a Saved Search object using the keyword test and then prints out all the authenticated user’s saved searches.The test search is then deleted, and its identifier is printed. ID Objects ID objects (see Figure 2.6) contain multiple id elements wrapped inside an ids array and a cursor-based id_list. ID +id: Integer -<> blocks/blocking/ids(cursor:Integer): json/xml #<> followers/ids(cursor:Integer,id:String, screen_name:String, user_id:Integer): json/xml #<> friends/ids(cursor:Integer,id:String, screen_name:String,user_id:Integer): json/xml Figure 2.6 Twitter API ID object. Twitter API Methods The two “social graph” methods friends/ids and followers/ids used for retrieving all followers and people who a user is following are more lightweight than the statuses/friends and statuses/followers methods, in that they return only a list of identifiers, not detailed information about the set of users: XXXXXXXX XXXXXXXX XXXXXXXX ... 0 0 Remember to enable “cursoring” by setting cursor=-1 in the friends/ids or followers/ids method calls; otherwise, no results will be returned. In the preceding example, the next_cursor and previous_cursor elements are set to 0 because all the data was successfully returned by the query.To extract all of a user’s friends, you use the following code: echo "

ID Objects

"; $cursor = -1; do { $ids = $twitter->get_basic("/friends/ids.json", array("cursor" => $cursor, "screen_name" => $username), $username, $password); foreach($ids->ids as $id) { echo "
  • ".$id."
  • "; } $cursor = $ids->next_cursor_str; } while ($cursor > 0); For this method to work, you must set the initial cursor parameter to -1; otherwise, Twitter will return an error.As with other methods that require cursors, the twitter-async library adds next_cursor_str and previous_cursor_str elements as the other cursor elements are converted to floating-point numbers by PHP. Relationship Objects Relationship objects are generated from the method friendships/show for detailing the relationship between two users known as the source and target.With authentication, the source parameter is attributed to the logged-in user unless either a source_screen_ name or source_id is provided.A target user must be supplied by setting the 31 32 Chapter 2 Diving Into the Twitter API Methods target_screen_name of target_id parameters.A friendships/show method is shown here: sample Relationship object using the https://api.twitter.com/2/friendships/show.xml?target_screen_name=socprog& source_screen_name=markhawker The XML response from this query looks like this: true true socprog 109892189 true true markhawker false 15397909 The notifications_enabled and blocking elements will be empty unless user authentication is provided because this is not publicly available data.This can be re-created using the sample file by adding the following: echo "

    Relationship Objects

    "; $relationship = $twitter->get_basic("/friendships/show.json", array("target_screen_name" => "socprog", "source_screen_name" => $username), $username, $password); print_r($relationship->responseText); In this example, the source_screen_name is set to your own username, but this can be the credentials of any Twitter user.The target_screen_name is set to this book’s account, but could be any valid user identifier. Response Objects Similar to ID objects in that they only return one element, Response objects return a Boolean value of true or false.Two methods return this response: friendships/exists and help/test, returning a true or true.The friendships/exists uses a GET operation and both user_a and user_b parameters to be set; these parameters are screen names or identifiers of users, which requires authentication for protected users.The help/test method does not require any parameters and uses a GET operation: echo "

    Response Objects

    "; Twitter API Methods $friendship = $twitter->get_basic("/friendships/exists.json", array("user_a" => $username, "user_b" => "socprog"), $username, $password); echo $friendship->responseText; The $friendship->responseText should return either true or false for this method depending on whether you follow this book’s Twitter account. Hash Objects The final sets of objects are Hash objects.Two methods will return a Hash object as a sign of success (blocks/exists/<> and account/end_session), whereas the other methods return a Hash object to notify you of an error.The blocks/exists/<> and account/verify_credentials methods both return a Hash object to signify that a block or user does not exist.Although you can check the status codes for successful and unsuccessful requests, it is possible to use the Hash object to get a description of the particular problem. Hash objects contain two elements error and request. For example, executing the account/end_session method will return the following: Logged out. /account/end_session.xml Other popular error messages include “Not found,”“Could not authenticate you,” and “This method requires authentication.” Even though other error messages may be added in the future, they will conform to the key/value pair given above.The account/rate_limit_status method is the only exception to this rule; it returns the following response: 86 100 2009-06-01T21:05:01+00:00 1243890301 The key remaining-hits indicates the number of requests left to the Twitter API until the counter is reset and should always be less than or equal to the hourly-limit. Both reset-time and reset-time-in-seconds are two ways of saying when the user’s rate limit will be reset. First, reset-time is a Greenwich mean time (GMT) datetime stamp in the format YYYY-MM-DDTHH:MM:SS+00:00, and reset-time-in-seconds is the equivalent UNIX timestamp measured in seconds since January 1, 1970. By subtracting the current UNIX timestamp from reset-time-in-seconds, you will see that it is equivalent to reset-time.To access these elements programmatically, you use the following: echo "

    Hash Objects

    "; $rate_limit_status = $twitter>get_basic("/account/rate_limit_status.json", 33 34 Chapter 2 Diving Into the Twitter API Methods null, $username, $password); echo "

    Remaining Hits: ".$rate_limit_status->remaining_hits."

    "; echo "

    Hourly Limit: ".$rate_limit_status->hourly_limit."

    "; echo "

    Reset Time: ".$rate_limit_status->reset_time."

    "; echo "

    Reset Time (Secs): ".$rate_limit_status->reset_time_in_seconds. "

    "; One thing to note is that twitter-async has converted the minus character (-) of each element to an underscore (_), which was discovered by printing out $rate_limit_status->responseText. Twitter Search API The Search API is used to perform Twitter searches and for extracting trend data. Unlike the methods discussed previously, which support multiple return formats, the Search API supports only two formats,Atom and JSON, which is why the JSON format is recommended.The Atom syndication format is described in the following section so that you can see how it compares to JSON before exploring the Search API methods and search operators.The Twitter API and Search API are separate entities, which means that date formats, User and Status objects, and screen_name capitalization are not standard across both, although this is one of the goals of the new version of the Twitter API. Introducing the Atom Syndication Format The Atom syndication format is an XML-based data standard considered to be an alternative to Really Simple Syndication (RSS), which you may have been exposed to through newsfeed subscriptions.The Atom format is the reason you can subscribe to Twitter searches in your browser via the web interface.To get you started, here is an example of a Search API Atom feed for the search term markbook, which is the hashtag used during the production of this book: tag:search.twitter.com,2005:search/markbook markbook - Twitter Search since_id removed for pagination. 2009-07-02T21:47:02Z 1 tag:search.twitter.com,2005:2443841666 2009-07-02T21:47:02Z Been working on #markbook tonight. Getting a skeleton chapter ready. Funny how Atom and JSON are *so* different in @twitterapi. Been working on <a href="http://search.twitter.com/ search?q=%23markbook">#<b>markbook</b></a> tonight. Getting a skeleton chapter ready. Funny how Atom and JSON are *so* different in <a href="http://twitter.com/ twitterapi">@twitterapi</a>. 2009-07-02T21:47:02Z <a href="http://www.tweetdeck.com/">TweetDeck </a> en markhawker (Mark Hawker) http://twitter.com/markhawker The first thing you will notice is that you are given a wealth of meta-data stored inside the feed element and related Twitter update information embedded within an entry element (or multiple entry elements). Note that in this example, one entry element has been included by setting the rpp parameter to 1; typically, however, multiple elements are returned, with the default being 15 entries. Feed Elements All feed elements contain meta-data associated with the search query to enable it to be repeated or traversed programmatically.This includes preformatted links to display the next results and refresh the page plus any Twitter warning information.They also contain 35 36 Chapter 2 Diving Into the Twitter API Methods information regarding the OpenSearch specifications used by Twitter (for example, in the link http://search.twitter.com/opensearch.xml).The attributes within a feed element are as follows: n entry Each result is contained within its own entry element, which is described in the next section. n id Unlike numeric identifiers in Twitter API objects, the id element of the Search object contains a text string describing the search query in general terms. n link Several link elements are contained within a feed element, each including three common attributes detailing their type, href and ref.The link element tagged with the self attribute details the query that was run along with XML pointers for OpenSearch, which facilitates the syndication of results. Both the next and refresh references enable results to be automatically refreshed if desired. n openSearch:itemsPerPage This element contains the number of search results returned and should be identical to the rpp parameter supplied in the query.The default is 15 but can be increased up to a maximum of 100 entries returned in an instance. n title Containing the query appended with the - Twitter Search label, this element may be useful in saving you time creating an appropriate page title yourself. n twitter:warning Any warning messages provided by Twitter will be contained within this element (in this instance warning that the since_id parameter was excluded).Although this element can be useful when debugging your applications, it is important to note that not all Search API responses will contain this element. n updated This element describes when the search results were last updated and is in the format YYYY-MM-DDTHH:MM:SSZ.This can be useful if caching results in a database, because you can test whether an update needs to be performed based on whether the data has been refreshed. Entry Elements Each update matching the query string is encapsulated within its own entry element. Although some basic information is returned referencing the update, it is nowhere near as complete as the data returned in Status or User objects from the Twitter API. In this case, Twitter Search API should additional information be required by your application, sufficient information is provided to enable you to make requests using the Twitter API to extract that information: n author This value contains a nested set of two elements, name and uri.The name element contains the name and screen_name of the user enclosed in parentheses and uri links to the author’s Twitter profile page. n content, title Both elements contain the body of the update but the content element also contains HTML that can be used to reconstruct the Status object. Depending on whether you want to re-present the update or analyze its text will help you decide which element to use. n id Similar to feed elements, the id is a text string used to identify the update in the search results.The trailing integers of this value are the Status object id of the update, which provides an opportunity to extract further details using the Twitter API.The Status object id and full URL is provided in one of the link elements. n link Containing the same attributes as in feed elements, the two link values give the URL to the Status object and a link to the author’s profile image stored by Twitter. n published, updated These two values give the creation date of the Status object in the same YYYY-MMformat as in feed elements. DDTHH:MM:SSZ n twitter:geo This element will be populated with status location data if explicitly enabled by the user. n twitter:lang, twitter:source The twitter:source value is the encoded link to the application used to publish the update and matches the source attribute of the Status object.The twitter:lang value is the language of the update stored in the two-letter ISO 6391 format. Contrasting Atom and JSON Outputs In contrast to the Atom syndication format the Search API, JSON output returns a set of “key/value” pairs enclosed within a parent results object. For the same query for markbook that was executed earlier, the following JSON data is returned: {"results":[ { "text":"Been working on #markbook tonight. Getting a skeleton 37 38 Chapter 2 Diving Into the Twitter API Methods chapter ready. Funny how Atom and JSON are *so* different in @twitterapi.", "to_user_id":null, "from_user":"markhawker", "id":2443841666, "from_user_id":924649, "iso_language_code":"en", "geo":null, "source":"<a href="http:\/\/www.tweetdeck.com \/">TweetDeck<\/a>", "profile_image_url":"http:\/\/s3.amazonaws.com \/twitter_production\/profile_images\/234974305\/me_normal.jpg", "created_at":"Thu, 02 Jul 2009 21:47:02 +0000" } ], "since_id":0, "max_id":2452360691, "refresh_url":"?since_id=2452360691&q=markbook", "results_per_page":1, "next_page":"?page=2&max_id=2452360691&rpp=1&q=markbook", "completed_in":0.027692, "page":1, "query":"markbook" } In this example, you can see a results key with entries placed within square brackets and each enclosed within a pair of curly braces and separated by a comma: "results":. You will also notice there is meta-data returned similar to feed elements: since_id, max_id, refresh_url, results_per_page, next_page, completed_in, page, and query. The attributes returned for each entry are similar to entry elements with a few aesthetic exceptions. Forward slashes (/) are “escaped” by a backslash (\), because in JavaScript a forward slash is used as an escape character. By escaping the character, it prevents the interpreter from performing the action typically associated after the forward slash.You are also explicitly given the Status object id attribute and a to_user attribute if a user is mentioned in the update. Finally, the date format between both outputs is inconsistent, but the JSON output is comparable to that of the JSON output of the Twitter API. Twitter Search API Methods There are two categories in the Search API: Search and Trends. Search allows you to supply a query and retrieve results based on search terms and a mix of operators and parameters.The Trends category shows you what’s hot or “trending” in the community currently or for any given date or week. Twitter Search API)] Search In its simplest form, a query in the Search API consists of the stem https://search.twitter.com/search.<>, where <> can be replaced with json or atom, a q parameter, and a keyword (for example, https://search.twitter.com/ search.json?q=twitter).This will return in JSON format the default number of updates, 15, that include the twitter keyword. Note that keywords must be URL encoded. So, for example, if you want to find updates mentioning a particular user, an @ symbol is encoded as %40; for a hashtag, the hash character (#) is encoded as %23; and for searching for an update containing a question, the question mark character (?) is encoded as %3F. Set a User Agent You must supply a user agent to prevent the Twitter API returning a status code 403 for requests. You can do so by setting the –A switch in cURL, or if you are using twitter-async this will be set automatically for you. To conduct a simple search within the index.php sample code, you just add the following: echo "

    Search Objects

    "; $query = "test"; $search = $twitter->get_search(array("q" => urlencode($query), "rpp" => 2), $username, $password); echo "

    Query: ".$search->query."

    "; echo "
      "; foreach($search->results as $result) { echo "
    • ".$result->from_user.": ".$result->text."
    • "; } echo "
    "; Twitter Search is about more than just simple keywords and parameters, which were discussed in Chapter 1.You can also use a wealth of operators to customize results or control how results are returned from the Search API. Operators are similar to the parameters that you were shown in Chapter 1 and the main operators are listed here.You can find a full list at http://search.twitter.com/operators, which mirrors some, but not all, of the functionality of an advanced Twitter search. There are numerous content-based operators, including those for phrase matching, hyperlink and source filtering, and word negation. Here is a description of some contentbased operators: n To search for multiple keywords, you can separate words with a plus (+) character. For example, twitter+api would find status updates containing both twitter and api. 39 40 Chapter 2 Diving Into the Twitter API Methods n Exact phrase matches can be found by enclosing the words within quotation marks (“”), which are URL encoded using %22. For example, %22twitter+api%22 would find status updates containing the phrase twitter api. n To search for one word or another word (or both), you use the logical OR operator (for example, twitter+OR+api). n If you want to exclude a word from a search you prefix the word with a minus (-) character. For example, twitter+-api searches for updates containing twitter but not api. n You can return status updates that must include a hyperlink. For this, you would use the filter:links operator. For example, twitter+filter:links returns status updates containing twitter and that include a hyperlink. If you want to find updates sent from a particular source, such as TweetDeck, you can use the source:application operator (for example, twitter+source:tweetdeck).This could prove useful if you have set your own source parameter and want to track how users are interacting with your application. n In addition to content-based operators, a number of meta-content operators exist for filtering updates to or from a particular user and updates sent from a geographic region or before or after specific dates.The operators are as follows: n To filter by updates sent to or from a user, you can use the from:username and to:username operators. For example, twitter+from:markhawker would search for updates containing twitter and sent by markhawker. For filtering updates sent to markhawker, you would use to:markhawker. n As devices begin to be supported by the Geolocation API, the location:place_name operator and geocode parameter will become increasingly useful for location-based searches (for example, party+location:London). Dates can be used to filter updates using since:YYYY-MM-DD or until:YYYY-MM-DD. For example, you may be running a competition that only accepts entries after a specified date, or even before a closing date (for example, vote+until:2009-0704). Note that Twitter Search currently only provides results up to a week and a half in the past. n You can experiment with any of these operators by modifying the $query parameter, which was used in the search example. By outputting the $search->responseText, you can also start to build up a picture of what elements are returned by the Search API and how you can use them in your own applications. Trends Although search is good for filtering and extracting information at an individual level, you need trends methods to provide aggregate-level data across the Twitter ecosystem. Twitter Search API Local Trends Methods Twitter has two trends methods for providing trends specific to a particular location. The trends/available and trends/location methods will return trending topics using the Yahoo! Where On Earth ID (WOEID) convention and will make trend results more relevant to a user’s specific location. There are four trends methods.They output in JSON format only and are summarized here: n To extract the ten topics currently trending on Twitter, use the trends method. This method will return a trends element containing a name and url for performing the related Twitter search.An as_of attribute is also included, which gives the date and time that the results were valid.An example date is Sat, 01 Aug 2009 18:00:00 +0000. n The trends/current method displays similar information to the ten topics but uses a non-URL-encoded query attribute in place of a url and provides the as_of element as the number of seconds since January 1, 1970.This method permits the use of an exclude parameter, which can be set to hashtags to remove all hashtags from the trends list.An example date is 2009-08-01 18:00:00. n The trends/daily method allows for a date parameter to be supplied in the format YYYY-MM-DD to extract top topics for a given date. If no date is provided, results are returned for today’s date.The exclude parameter can be supplied to exclude hashtags. The trends/weekly method returns the top 30 topics for each day in a given week by providing a date parameter and optionally setting the exclude parameter. If no date is provided, results are returned for the current week. n All methods apart from the trends method return results in a somewhat strange manner. Comparing the two, the trends method will return the following JSON results, which have been truncated to show only two trends: {"trends":[ { "name":"Roger Federer", "url":"http:\/\/search.twitter.com\/search? q=%22Roger+Federer%22+OR+%23Federer" }, { "name":"A-Rod", "url":"http:\/\/search.twitter.com\/search?q=A-Rod" } ], "as_of":"Sun, 05 Jul 2009 18:34:58 +0000" } 41 42 Chapter 2 Diving Into the Twitter API Methods In comparison, all three trends/current, trends/daily, and trends/weekly methods return results in the following format, which (again) has been truncated and generalized for the sake of brevity: {"trends":{ "2009-07-05 19:30:00":[ { "query":"Wimbledon OR #Wimbledon", "name":"Wimbledon" }, { "query":"\"Roger Federer\" OR Federer", "name":"Roger Federer" } ] }, "as_of":1246822183 } These short examples demonstrate the varied outputs of the trends methods in terms of both their structure and date formats.To access the same trends programmatically, you should add the following code: echo "

    Trends Objects

    "; echo "

    Current Trends

    "; $trends = $twitter->get_trends(null, $username, $password); print_r($trends->responseText); echo "

    Current Trends

    "; $trends_current = $twitter->get_trendsCurrent(array("exclude" => "hashtags"), $username, $password); print_r($trends_current->responseText); echo "

    Daily Trends

    "; $date = date("Y-m-d"); $trends_daily = $twitter->get_trendsDaily(array("date" => $date, "exclude" => "hashtags"), $username, $password); print_r($trends_daily->responseText); echo "

    Weekly Trends

    "; $trends_weekly = $twitter->get_trendsDaily(array("date" => $date, "exclude" => "hashtags"), $username, $password); print_r($trends_weekly->responseText); In addition to these examples, the two local trends methods can be accessed by supplying lat and long parameters or a woeid.The lat and long is used to sort results from the trends/available method by distance from that particular location.These methods are accessible via the following code: echo "

    Local Trends Objects

    "; Summary $trends_available = $twitter->get_basic("/trends/available.json", array("lat" => 37, "long" => -122), $username, $password); print_r($trends_available->responseText); This should return the closest matches to San Francisco (the town specified by the lat and long parameters), which is contained within this JSON response: "country":"United States", "url": "http://where.yahooapis.com/v1/place/2487956", "placeType": {"code": 7, "name": "Town"}, "woeid": 2487956, "countryCode": "US", "name": "San Francisco" }, ...] The response will return a number of potential matches, starting with the closest, which was an exact match to San Francisco.The next stage is to extract the WOEID by using $trends_available[0]["woeid"], which can then be entered into the trends/location method: $trends_location = $twitter->get_basic("/trends/". $trends_available[0]["woeid"].".json", null, $username, $password); print_r($trends_location->headers); The results from this query should return the following JSON data: "as_of": "2010-03-15T22:10:03Z", "locations": , "trends": This response will return a regular Trends object with an embedded locations element for extracting the initial woeid and name of the location. Summary This chapter illustrated a number of Twitter API methods that enable you to perform a multitude of actions to access and mutate data, such as sending updates and exploring a user’s social graph.You were also given an overview of the Search API, including the Atom syndication format, methods, and operators that you can use to extract both individual-level search data and also aggregate trends data.The next chapter explores how to use OAuth for user authentication so that you can begin to put your knowledge of Twitter methods to practical use. 43 This page intentionally left blank 3 Authentication with Twitter OAuth C hapter 2,“Exploring the Twitter API and Search API,” covered the various Twitter API and Search API methods using cURL and twitter-async using Basic Authentication. Basic Authentication is by no means unique to Twitter, and many sites and social services also use the same mechanism for user authentication. However, requiring a user’s password even over a secure connection such as HTTPS can present security concerns.Although the barrier to entry is higher for an OAuth implementation in comparison to Basic Authentication, it is an essential tool for accessing the Twitter API because Basic Authentication will be deprecated in the future. This chapter investigates Twitter’s implementation of OAuth as an alternative to Basic Authentication and describes the workflow of Twitter OAuth, with a focus on web applications. OAuth is a method for interacting with Twitter on behalf of users without requiring them to supply a password every time they want to use an application.Twitter OAuth takes the form of the “Sign in with Twitter” service, which enables users to sign in to your website or application using their Twitter credentials.The chapter then provides a walkthrough of how to implement Twitter OAuth using twitter-async to create a very simple application called Test Tube.You can then use the code in this example as a basic template for your own Twitter application ideas. Introducing Twitter OAuth OAuth is an open protocol to facilitate a standard, secure authorization method for desktop, mobile, and web applications.The idea behind OAuth is similar to that of valet keys provided in some of today’s luxury cars.The valet keys give parking attendants access to certain features of the car but may restrict them to driving only a limited number of miles or may prevent them from opening the trunk. In this instance, you are giving someone limited access to your car via a special key, while using another key to unlock everything else.This is in contrast to Basic Authentication, through which users are giving you their 46 Chapter 3 Authentication with Twitter OAuth keys, and thus not only exposing their passwords to prying eyes but also giving you unrestricted access to their accounts. In February 2009,Twitter released the first implementation of OAuth as a closed beta for developer experimentation.This has now been opened up to all developers through a new registration process for OAuth applications, available at http://twitter.com/oauth_ clients. (You must have a Twitter account to access this URL.) All the applications that you have previously registered with Twitter will appear here. Clicking an application name will give you further details about the application and will enable you to edit your application settings, reset your consumer key and consumer secret (described in the next section), or delete your application. During registration, you are prompted with a series of fields that you must fill out, including application name, description, and website.You are also asked whether you are creating a desktop or browser application (because the authentication steps are slightly different) and whether you require read/write or just read-only access to user data. Readonly access is just “pulling” data from Twitter, as you have seen with Twitter API accessor methods, and would include reading a user’s updates, direct messages, or favorites. Read/write access includes pulling data from Twitter but also “pushing” data back, as you have seen with mutator methods of the Twitter API.This includes updating a user’s status, sending a direct message, or marking a favorite.The callback URL is a location where users are redirected after successfully authenticating your application. For unsuccessful attempts, a user is returned to the Twitter home page. OAuth Benefits In addition to avoiding the impending deprecation of Basic Authentication, both users and developers can gain a number of benefits by adopting OAuth. For users, they no longer need to hand out their passwords to applications, and they can view authorized applications by visiting the Twitter “Connections” tab in their profile. From the Twitter “Connections” tab, users can de-authorize or “Revoke Access” to unwanted applications, which was previously subject to a user trusting an application to remove users’ profile details from their data store or required users to change their password to “break” the relationship. In the case of “Sign in with Twitter”, users can also use their Twitter credentials to authenticate themselves on third-party websites (using their Twitter details to post comments, for example). Permissions are also granular, allowing users to select whether they want to permit read-only or read/write access to an application. For developers, you will no longer need to worry about users changing their password or storing password details securely.Adopting OAuth will also show that you care about the progression and evolution of the Twitter API, which gives users greater confidence in your application. OAuth Definitions Before delving into the Twitter OAuth workflow, you need to understand a few terms so that you can start speaking the OAuth lingo: Introducing Twitter OAuth n Consumer A website or application that uses OAuth to access Twitter on behalf of the user: your application. Consumers are created and developed by individuals or organizations known as consumer developers (you).Access by the consumer to a user’s protected resources is controlled by a consumer key and consumer secret, which are used by Twitter to identify the consumer.The consumer key and consumer secret are given to a consumer developer when registering a consumer and can be reset at any time. For brevity, throughout this chapter, the word application is used rather than the word consumer. n OAuth protocol parameters Parameters with names beginning with oauth_ (for example, oauth_consumer_ key, oauth_token, oauth_nonce, oauth_timestamp, oauth_version, oauth_ signature_method, and oauth_signature).These parameters are handled internally via the twitter-async client library to ensure that OAuth exchanges are validated. n Protected resources Data stored by Twitter that an application can access through authentication (for example, account data, updates, direct messages, favorites). n Service provider A web application that allows access to protected resources via OAuth. In this chapter,Twitter is the service provider. n Tokens Used by the application rather than a user’s username and password to gain access to protected resources on Twitter.Tokens are random strings of letters and numbers paired with a token secret.There are two types of token: request and access.Twitter supports the HMAC-SHA1 signature base string.The Twitter OAuth workflow has two phases: authorization and access.The authorization phase is when the users give permission to Twitter that an application can “impersonate” them.The access phase is when the application actually does the impersonating. In terms of tokens, a request token is required only once during the authorization phase to generate an access token and token secret, which can then be stored and used multiple times during action phases.Twitter tokens currently do not expire, and so once users authorize an application, it will be granted infinite access to their information unless they choose to revoke access.Access can also be revoked if Twitter suspends an application. n User This is an individual or organization that has signed up for a Twitter account. Users create protected resources, which they can share with a consumer. For example, their direct messages or updates can be read (and written) by an application. 47 48 Chapter 3 Authentication with Twitter OAuth The next section explores the full Twitter OAuth workflow, using all these terms in context (so don’t worry if they don’t make much sense just yet). Implementing Twitter OAuth After you have registered your application, you are ready to begin implementing Twitter OAuth.The Twitter API includes four OAuth methods: oauth/request_token, oauth/authorize, oauth/authenticate, and oauth/access_token.The official Twitter documentation for these methods is complex and is best described using workflows and by giving an example. Twitter OAuth Workflow A simplified workflow for browser-based applications is as follows: 1. A user visits an application, and a request token is generated by Twitter by calling the oauth/request_token method and using the application’s consumer key and consumer secret. 2. A request can be made to oauth/authorize by following a URL appended with the request token to request user authorization.The oauth/authenticate method is reserved for applications using the “Sign in with Twitter” feature, which can be used to provide “one-click” user authentication. For desktop applications, you must set the parameter oauth_callback=oob in the oauth/authorize method to initiate PIN-based authorization.Where desktop authorization differs is that after obtaining approval from the user,Twitter displays a seven-digit PIN that must be recorded by the user and then entered into the application to be used as the oauth_verifier parameter. Steps 4 and 5 are the same as web-based authentication.The twitter-async library does not support this desktop application workflow. 3. Following the URL, the user is redirected to Twitter where the request token is verified. If not logged in to Twitter, the user is required to log in to grant access to the application.At this stage, the user is reminded of which application is requesting access by being shown its logo, description, and developer information, and is then prompted to allow or deny access to their protected resources. If access is denied, a prompt will be displayed by Twitter but the user will not be redirected back to the application. 4. If allowed,Twitter marks the request token as authorized and redirects the user back to the application using the callback URL together with the request token and other OAuth protocol parameters. 5. An access token is then generated by passing the request token and OAuth protocol parameters to the oauth/access_token method, which can then be stored alongside the token secret by the application. Implementing Twitter OAuth 6. Whenever applications want to access a user’s protected resources, they use the access token and token secret along with their consumer key and consumer secret for each request. Figure 3.1 shows this workflow, specifically the transition between your application and Twitter in terms of authentication and redirects. If a user is already signed in to Twitter and they have authorized your application, this will appear like a “one-click” process. If users close down their browser window before authenticating their details, the next time they visit the Twitter site they will be prompted with an error saying that their request token has expired. User Visits Application Your Application Domain Application Sends Request to oauth/authenticate or oauth/authorize using Request Token created by oauth/request_token User Clicks Button or Link to Sign In With Twitter Is User Logged in to Twitter? Twitter No Allow User to Enter Their Credentials Yes Has User Authorized Application Before? Yes No Prompt User to Authorize Application Authorized? Yes Your Application Domain Store Screen Name, Access Token and Token Secret Figure 3.1 Redirect to Callback URL Including Access Token and Token Secret Workflow of a “Sign in with Twitter” session. No Redirect to Home Page 49 50 Chapter 3 Authentication with Twitter OAuth A number of OAuth client libraries are available to help reduce the complexity of this workflow. Client libraries are generally supplied by third parties and are tested quite rigorously by hundreds, if not thousands, of developers. One such library is twitter-async, which is used in the sample application described in the next section,Test Tube, which you can use as a template for your own Twitter applications. Test Tube: A Sample Twitter Application Twitter-async is a PHP client library that enables you to integrate with the Twitter API and Search API using OAuth.Twitter-async was written to maximize the efficiency of making HTTP requests over cURL using a mixture of synchronous and asynchronous methods.The twitter-async client file (EpiTwitter.php) has two dependencies contained within EpiOAuth.php and EpiCurl.php that handle all the authentication and URL signing relevant to Twitter and for handling the cURL requests. If you like, take some time to familiarize yourself with them; you will be using them later in this section. Class Methods Twitter-async has two methods: __construct and __call.The constructor takes a minimum of two parameters and a maximum of four.The first two parameters are the consumer key and consumer secret that were generated by Twitter during application registration.The last two are the access token and token secret, which are generated during the authorization phase and should be stored to allow requests to be made on behalf of users.The __call method handles the majority of other requests and uses a simple naming convention to map onto Twitter API and Search API method names known as API endpoints.As an example, the account/verify_credentials method maps to get_accountVerify_credentials, which consists of a lowercase GET request, an underscore (_) and a lowercase URL which has the forward slash (/) omitted and the first letter of the preceding method name capitalized. Parameters can be added by adding an array inside the method call. For example, for statuses/update, you would use post_statusesUpdate(array("status" => "This is my new status.")). Uploading Images Using Twitter-async Twitter-async supports the uploading of images via the account/update_profile_image and account/update_profile_background_image methods. This is achieved by using the following: post_accountUpdate_profile_image( array("@image" => "@filename.png;type=image/png") ) Remember to prefix the key and value with an “at” (@) character and that the image must be an absolute path to a file on your server. Implementing Twitter OAuth When using OAuth, you should not use the get_basic(), post_basic(), and delete_basic() methods; these were reserved for Basic Authentication. Instead, twitterasync provides get(), post(), and delete() methods that require an application’s consumer key and secret to access Twitter resources. For these methods, you are not required to supply the user’s screen name and password; these are already catered for when using OAuth. Accessing Responses When you use twitter-async to make a call to the Twitter API, you will be returned an object with properties.The properties are named identical to what you have previously seen in both of the Twitter APIs, and dimensions of two or more are returned as arrays (for instance, when a collection of users or statuses is returned). For example, the following code snippet is a JSON response from the account/verify_credentials method that has been stored in the $user variable: { screen_name: "markhawker", name: "Mark Hawker", status: { text: "This is my last status.", created_at: "Sat Aug 01 12:00:00 +0000 2009" }, } In this example, you can access properties in two ways, either directly as member variables such as $user->screen_name or $user->status->text or through the response property by using $user->response["screen_name"] or $user->response ["status"]["text"]. For methods that return multiple responses, you can either access them through the $user[0]->screen_name syntax (remembering that PHP uses zerobased indexing, and so zero is actually the first response) or via using a looping function such as for(), foreach() or while(). If you are having trouble accessing data, you should return the response text via $user->responseText, which will give the full data set. In some instances,Twitter wraps data within arrays, so instead of using $response->element, you would use $response[0]->element instead. Creating a Twitter-async Application As a developer, it is generally easier to understand a new concept by experiencing it, so in this section you will develop a simple application to show your ten latest Twitter friends along with their profile image and a link back to their profile.You can demonstrate both the oauth/authorize and the oauth/authenticate or “Sign in with Twitter” workflows using similar codes, but the only difference between the oauth/authenticate and the oauth/authorize workflow is that in the former the user is only prompted to allow or deny access to the application once. In the latter, users are prompted to allow or deny access each time that they use the application. 51 52 Chapter 3 Authentication with Twitter OAuth “Sign in with Twitter” Buttons Twitter provides a number of ready-made buttons that you can use to standardize the sign-in experience of users. You can find these on the Twitter API wiki (http://apiwiki.twitter.com/ Sign-in-with-Twitter). Downloadable source code for this chapter is available via the book’s code repository (http://github.com/markhawker/Social-Programming/). If you want to start from scratch, however, it is assumed that you have downloaded the twitter-async client library and have uploaded the files EpiCurl.php, EpiOAuth.php, and EpiTwitter.php to your web server inside a twitter-async directory.There are four steps to getting your application up and running: registering your application with Twitter, creating a “landing page,” creating a “master page,” and then testing your application.Although only a simple application, you should be able to quickly make modifications to test what you have learned so far about the Twitter API methods. Registering Your Application At the start of every project, you must register your application with Twitter by going to http://twitter.com/apps/new. From there, the required fields should be self-explanatory up to callback URL field, which will point to a “master page,” which is the page that the user will be sent back to once a request token and token secret have been granted, master.php. For example, if your domain name is http://mytwitterapp.com/, you set your callback URL to http://mytwitterapp.com/master.php. Because you are just going to be accessing protected resources and not mutating them, you should select read-only access and also check the Use Twitter for Login option (because you will be using this feature). Click Save and create a new PHP file called functions.php, which will be a utility file for all your Twitter functions, and enter the lines shown in Listing 3.1 using the consumer key and consumer secret that Twitter has just generated for your application during the registration process. Listing 3.1 1 2 3 4 5 6 7 8 9 10 11 The functions.php File logout() {} verify() {} check() {} printFriends() {} The INDEX, MASTER, and TITLE variables can be modified should you want to use different filenames. Remember that if you change the value of MASTER you should also edit the callback URL from within Twitter. Be sure to add the consumer key and consumer secret that Twitter generated for your application on lines 5 and 6.The init() function on lines 10 to 12 is used to create the EpiTwitter object using the consumer key and consumer secret but also handles being passed an OAuth token and token secret upon a user successfully authorizing the application. Methods on lines 13 to 17 are intentionally left empty because they will be updated later in this section. Now that you have saved your configuration details within functions.php, you are ready to create the landing page. Creating the Landing Page The landing page will serve a single purpose: generating a valid request token, which can be then passed to the Twitter OAuth authorization and authentication URLs for a user to click to be taken to Twitter.Twitter-async handles all this complexity for you, so a simple landing page can be created using the code in Listing 3.2. Listing 3.2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 The index.php File getAuthorizeUrl(); $authenticate_url_forced = $twitter->getAuthenticateUrl(null, array("force_login" => true)); $authenticate_url_unforced = $twitter->getAuthenticateUrl(); } catch(EpiOAuthException $e) { echo "There was an error"; exit; } catch(EpiTwitterException $e) { echo "There was an unknown exception"; exit; } ?> <?php echo TITLE; ?> 53 54 Chapter 3 Authentication with Twitter OAuth 20 21
    22

    Test Tube

    23

    This application uses Twitter’s "Sign in with Twitter" feature to demonstrate what is possible in only a few lines of code.

    24

    Authorize with Twitter

    25

    Forced Login

    26

    Whether a user is logged into Twitter or not they will be prompted to login and then Allow/Deny the application.

    27

    Sign
in with Twitter

    28

    Unforced Login

    29

    The currently logged in user will be used and then prompted to then Allow/Deny the application.

    30

    Sign in with Twitter

    31
    32 33 34 ?> Line 2 is used to include the functions.php file containing the application logic for convenience.The Twitter object is initiated on line 3 and can be used for a number of things, but on the landing page you will use it to create an authorization (line 24) and two authenticate URLs (lines 27 and 30).These URLs map to the Twitter API oauth/authorize and oauth/authenticate methods.The authenticate URL on line 24 demonstrates how you can pass the force_login parameter to the method, thus prompting users to log in to Twitter regardless of whether they are already logged in (which proves useful if they have multiple accounts). Note that Twitter handles the force_login rather strangely, in that even if it is set to false, it will be accepted and the user will be forced to log in.The “Sign in with Twitter” button has also been used alongside a simple Cascading Style Sheet (CSS) containing the following styles: body { background: #3ea8bc; font-family: Tahoma, Verdana, Arial, sansserif; margin: 1em; padding: 1em; } img { border: 0; } #main { background: #fff; padding: 1em; border: 5px solid #ccc; textalign: center; } .following, .follower { margin: 1em; border: 0; } .tweet { font-size: 1.5em; color: #ccc; } Save the code in Listing 3.2 as index.php, and then upload the file to your web server alongside functions.php, the image, and the CSS. Implementing Twitter OAuth Creating the Master Page The next page is the master page, which is the page that was set as the callback URL, and will have the following functionality: n Handling of a “sign-in” process n Handling of a “sign-out” process n Handling of users who access the page and who have not signed in n Accessing a user’s protected resources in the form of a friends list Handling of simple exceptions to degrade gracefully n For simplicity, you can use cookie-based storage of user credentials, although in practice you might want to store them in a database or in PHP sessions.You can re-create the master page with the skeleton code used in Listing 3.3. Listing 3.3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 The master.php File <?php echo TITLE; ?>

    Hello, screen_name; ?>!

    <?php
echo $user->screen_name; ?>

    "status->text; ?>"

    Sign Out

    Twitter Error

    55 56 Chapter 3 Authentication with Twitter OAuth 28 29 30 31 32 33

    We were unable to verify your Twitter credentials.

    As with the landing page, you must include the functions.php dependency, which will be revisited to add the login(), logout(), verify(), check(), and printFriends() functions. Lines 3 to 8 contain the workflow that first evaluates whether the logout parameter has been set via the link on line 25. If it hasn’t, this workflow will attempt to create the Twitter object and verify whether a valid user has visited the page on line 7. If a valid $user is available, the application will show his or her Twitter username, profile picture, and latest friends. If not, an error message will display. Save the code in Listing 3.3 as master.php and reopen functions.php. Edit the logout() function so that it contains the following code: function logout() { $twitter = init($_COOKIE["oauth_token"], $_COOKIE["oauth_token_secret"]); $twitter->post_accountEnd_session(); setcookie("oauth_token", "", 1); setcookie("oauth_token_secret", "", 1); header("Location: ".INDEX."?loggedout"); } These lines are used to handle the sign-out process by calling the method, clearing the cookie that contained the user’s credentials, and then redirecting back to the landing page. Next, here’s the login() function: account/end_session function login() { // An OAuth Token has just been granted from Twitter if (!empty($_GET["oauth_token"])) { $twitter = init(); $oauth_token = $_GET["oauth_token"]; try { $twitter->setToken($oauth_token); $token = $twitter->getAccessToken(); $twitter->setToken($token->oauth_token, $token->oauth_token_secret); setcookie("oauth_token", $token->oauth_token); setcookie("oauth_token_secret", $token->oauth_token_secret); header("Location: ".MASTER."?loggedin"); } catch(EpiOauthException $e) { header("Location: ". INDEX."?oauthexception"); } catch(EpiTwitterException $e) { header("Location: ".INDEX."?exception"); } } else if ( Implementing Twitter OAuth empty($_COOKIE["oauth_token"]) && empty($_COOKIE["oauth_token_secret"]) ) { setcookie("oauth_token", "", 1); setcookie("oauth_token_secret", "", 1); header("Location: ".INDEX); } else { return init($_COOKIE["oauth_token"], $_COOKIE["oauth_token_secret"]); } } If an authorized request token has been returned from Twitter, you then need to convert it into an access token.This function checks for the token, attempts to create the access token, and then stores it alongside the token secret within a cookie.The user is then redirected or the page is “refreshed” so that the request token cannot be reused. If you do not do this, users might receive an error if they refresh the page manually with the request token still in the URL. If an access token and token secret cannot be found in the cookie, you should redirect the user back to the landing page. The only case this leaves is if you have a user who has had his credentials stored in the cookie and has just returned from the automatic refresh and is now logged in. In this case, the init() function is called using the access token and token secret. If you store the access token and token secret alongside the user’s screen name, you will be able to perform Twitter actions on behalf of the user. In Part IV of this book, you learn how to create your own microblog application from scratch. Just because you have received an access token and token secret does not mean that the user has been verified as legitimate.This is why you need to call the account/verify_credentials method, which will return a status code 401 if the user credentials are incorrect, which is encompassed within the verify() and check() functions, which will return false for all responses that do not have a status code of 200: function verify($twitter) { if(is_object($twitter)) { $response = $twitter->get_accountVerify_credentials(); return check($response); } else { return false; } } function check($payload) { return ($payload->code == 200) ? $payload : false; } You now have a test to ensure that you have a verified user and can now work with his protected resources. Remember that a call to the account/verify_credentials method returns a User object if valid, so that is why you can extract their profile_ image_url, screen_name, and status on lines 18 to 20 in Listing 3.3.The final function 57 58 Chapter 3 Authentication with Twitter OAuth is printFriends(), which calls the statuses/friends method, passing a count parameter to extract the user’s latest ten friends.The results from this method are ordered by the latest person added first: function printFriends($twitter, $count = 10) { try { $friends = $twitter->get_statusesFriends(array("cursor" => -1)); if (check($friends)) { $next_cursor = $friends->next_cursor; $previous_cursor = $friends->previous_cursor; echo "

    Latest ".$count." Twitter Friends

    "; for ($i = 0; $i < $count; $i++) { $friend = $friends->users[$i]; echo "name."\" href="http://twitter.com/\". $friend->screen_name."\"> profile_image_url."\" alt=\"".$friend->screen_name."\" height="48" width="48" />"; } } else { return false; } } catch(EpiTwitterException $e) { echo "

    You have no friends to list.

    "; } } Save functions.php after adding master.php to your web server. the new functions, and then upload it alongside Testing Your Application Before testing, you should ensure that you have all the files uploaded to your web server and have successfully registered your test application on Twitter. Navigate to your landing page in a browser and you should see your landing page with three hyperlinks:“Authorize with Twitter” and two “Sign in with Twitter” buttons, as shown in Figure 3.2. If you roll your mouse cursor over the links, you should see that you have an oauth_token parameter appended to the URL, which was automatically generated by twitter-async. Clicking the first link should redirect you to Twitter, where you can sign in (if required) and gain access to your application. If all was successful, you should then be redirected to your master page, which is shown in Figure 3.3. Feel free to now explore the other links and see where they take you. Consider denying access to your application or using the forced and unforced login options.You might also want to be more adventurous and test some other Twitter API methods using the same principles as used to create the printFriends() method. For example, you could update the code created in Chapter 2 to use OAuth rather than Basic Authentication. Summary Figure 3.2 Landing page for the Test Tube application. Figure 3.3 Master page for the Test Tube application. Summary This chapter provided an overview of OAuth as a more secure mechanism for obtaining user credentials for accessing their protected resources from Twitter.The example in this chapter used a PHP OAuth client library, twitter-async, to show how you can use OAuth to simplify the Twitter authorization process to create a simple Twitter application. Combining the skills you have learned in this chapter with those you learned in and Chapters 1 and 2, you should now feel confident to go on and develop your own applications. Chapter 4,“Extending the Twitter API: Retweets, Lists, and Location,” covers some of the newer Twitter API methods, such as the Retweet API and the Geolocation API. 59 This page intentionally left blank 4 Extending the Twitter API: Retweets, Lists, and Location C hapter 1,“Working with the Twitter API,” and Chapter 2,“Exploring the Twitter API and Search API,” gave an overview of the Twitter API and illustrated the essential Twitter API methods for account maintenance, updating status, searching, and accessing trends using Basic Authentication, cURL, and the twitter-async PHP client library. In Chapter 3,“Authentication with Twitter OAuth,” you used OAuth as a means of authenticating user accounts without handling usernames and passwords within your applications and created a simple application using this method.As Twitter evolves, new functionality will be added to the public website and also for developers within the Twitter API.As examples, new features that were implemented during the writing of this book include the Retweet API, Lists API, and geolocation functionality: n The Retweets API provides core functionality for handling retweets. n The Lists API enables users to curate lists of users that can be subscribed to and followed and can be either public or private. There are many location-based Twitter applications that handle geolocation internally.Twitter now allows developers to “tag” updates on an opt-in tweet-by-tweet basis based on a user’s privacy settings. n This chapter takes each of these new functionalities and describes how they work and, with the aid of simple code examples, shows you how you can implement them in your Twitter applications.These examples extend the Test Tube application created in Chapter 3. Extending Twitter’s Core Functionality As Twitter continues to gain momentum in the personal and business spheres, it is inevitable that they will look to increase their core service functionality to both generate revenue and increase user participation.As has been seen with the introduction of OAuth and the phased deprecation of Basic Authentication, sometimes these changes can affect 62 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location your applications in major ways, which is why OAuth was explained in detail.Twitter has introduced API versioning, which means that applications can be made to support specific API versions and Twitter will be able to provide beta functionality without compromising stable code.The convention that is being used is as follows: https://api.twitter.com/<>/<> Here, can be replaced with the version number that you intend to use, which can currently be set to a 1 or 2.Twitter intends to keep this version control method simple, and so will not be introducing complex branching and conventional version-control features. Introduced in version 2 of the Twitter API was support for retweets, lists, and geolocation. Retweet API The Retweet API enables developers to programmatically create a retweet (an act akin to forwarding an e-mail) and provides several ways to access retweets that users have created, that their followers have created, and tweets of their own that have been retweeted. Five new methods were added, and the statuses/friends_timeline method was superseded by the statuses/home_timeline method, which includes retweets.The new Retweet API methods are as follows: n statuses/retweet Retweets a tweet and requires an id parameter of the tweet you are retweeting submitted via POST or PUT.This method supports only JSON or XML output. n statuses/retweets Returns up to 100 retweets of a given tweet using GET.An example is https://api. twitter.com/2/statuses/retweets/1234.xml, where 1234 is the value of a valid status id.An optional count parameter can be supplied to restrict results.This method supports only JSON or XML output. n statuses/retweeted_by_me, statuses/retweeted_to_me Returns a default of the 20 most recent tweets made by or to the authenticated user and accepts the count and page parameters using GET.Along with JSON and XML, this method also supports Atom. Following its initial release to developers, the majority of feedback for the Retweet API addressed how to handle multiple retweets, which saw a change in the way retweet “collapsing” was processed by Twitter.To prevent clutter, a retweet appears only once in the user’s home timeline, and subsequent retweets of the same tweet have to be retrieved via the statuses/retweets method, which will return up to a maximum of 100 retweets. For example, if you want to return the five most recent retweets for the tweet with identifier 1234, you make the following call: https://api.twitter.com/2/statuses/retweets/1234.xml?count=5 Extending Twitter’s Core Functionality In the initial specification, it was possible that users would see updates from others whom they did not follow appearing in their timeline because of retweets being represented internally as “User B retweeted by User A” rather than “User A retweeted User B.” In the latest incarnation of the Retweet API, you will see retweets from users you are following returned as Status objects that have a retweeted_status element nested within them from the original tweeter.This way, users will see a familiar face in their timeline but the retweeted tweet will be accredited to the original user. If no retweeted_status element is returned within the Status object, the tweet has not yet been retweeted.To see an example using twitter-async, open the functions.php file that you created in Chapter 3 and add the printRetweets() function as shown in Listing 4.1. Listing 4.1 The printRetweets() Function function printRetweets($twitter, $type = "of", $count = 5, $page = 1) { try { $method = "get_statusesRetweets_".$type."_me"; $retweets = $twitter->$method(array("count" => $count, "page" => $page)); if (check($retweets)) { echo "

    Latest ".$count." Retweets ".$type." Me

    "; echo "
      "; foreach ($retweets as $retweet) { echo "
    • ".$retweet->id.": "".$retweet-> text."" last retweeted by: "; $method = "get_statusesRetweets{$retweet->id}"; $statuses = $twitter->$method(array("count" => 1)); if (check($statuses)) { $retweeters = ""; foreach ($statuses as $status) { $retweeters .= $status->user->screen_name.", "; } } echo substr($retweeters, 0, -2)."
    • "; } echo "
    "; } else { return false; } } catch(EpiTwitterException $e) { echo "

    You have no retweets to list.

    "; } } The function can be called within master.php underneath the printFriends() function as printRetweets($twitter, "of", 5, 1).The function makes use of the 63 64 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location statuses/retweets method to get details of the retweeter and prints a single user as the count parameter is set to 1.The format of the retweeted_status element is exactly the same as with a Status object.When multiple retweets are requested, they are contained within a statuses element as an array of status elements, which can be iterated over using a foreach() loop. In the code listing above, the original status text could be accessed using $status->retweeted_status->text using data from the statuses/ retweets method call. Unfortunately, the way in which retweets are handled by Twitter means that commenting on the original tweet is not permitted (which has caused some upset in the user base, and many clients support both the new method of retweeting plus allowing users to comment and submit as a regular mention).What the Retweet API adds is the ability to quickly retrieve retweets programmatically so that they can be tracked and managed gracefully within all third-party applications that choose to implement the new features. Lists API Lists are a feature for organizing and sharing “groups” of Twitter users publicly or privately.These lists are linked through a user’s profile and can be subscribed to (if permitted) by everyone, and therefore have the potential to be the new discovery mechanism for new and exciting accounts. For developers, the Lists API contains methods for creating, updating, retrieving, and deleting lists (and their members and subscribers).Another feature exists for retrieving a timeline of updates from a list that gives users greater control over their timelines and how information is filtered to prevent overload (for example, being able to see messages from close friends or work colleagues in a separate timeline from the home timeline). If group preferences are stored within Twitter, this means that other applications can share these preferences to provide a more streamlined user experience (because users will need to create lists only one time rather than multiple times per application).An example is when switching between desktop and mobile clients and synchronization of groups occurs between the two. List API Limits The current incarnation of the Lists API limits users to having a maximum of 20 lists, each of which can have up to 500 members. There are no known limits for list subscribers. These numbers may be increased, or decreased, in the future depending on Twitter’s resource management and capability. Unlike other Twitter API methods, the Lists API adheres more strictly to the definition of the Representational State Transfer (REST) design pattern, such as https://twitter. com/<>/lists/memberships.xml, which returns the public lists that a specified <> has been added to (see Table 4.1).This structure will decrease the need for excessive parameters in API method calls and should be a more friendly and understandable format for Twitter users.To demonstrate how the information is returned back to developers in XML the List object looks like this: Extending Twitter’s Core Functionality 1111 Example List @markhawker/example-list example-list An example list. 0 1 /markhawker/example public ... Table 4.1 Lists Methods, Parameters, and Return Types Method Description Method Parameters Return Type POST Creates a new list lists description, mode, name List object POST/ PUT Updates an existing list lists/ <> description, mode, name List object GET Gets the lists that the user has created lists cursor Lists collection GET Gets the lists that the user has been added to lists/ memberships cursor Lists collection GET Gets the lists that the user subscribes to lists/subsc riptions cursor Lists collection DELETE Deletes a specified list lists/ <> None List object GET Gets the timeline for list members lists/ <> /statuses max_id, page, per_page, since_id Statuses collection GET Gets the list details. lists/ <> None List object 65 66 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location The id element is unique to each list and does not change if elements such as the list changes.The slug element is an alphanumeric version of the name, which is in lowercase and uses the hyphen character (-) in place of spaces.The Lists API is split into three categories, each with similar methods: Lists, for creating, reading, updating, and deleting of lists (see Table 4.1); List Members, for adding and removing of users to the list and for checking member status for a user and returning all members (see Table 4.2); and List Subscribers, for subscribing and unsubscribing and for checking subscriber status for a user and returning all subscribers (see Table 4.3). name Table 4.2 List Member Methods, Parameters, and Return Types Method Description Method Parameters Return Type POST Adds a member to a list <>/ members id List object GET Gets the list members <>/ members cursor Users collection DELETE Removes a member from a list <>/ members id List object GET Checks whether a user is a memberf <>/ members/<> None User object Table 4.3 List Subscriber Methods, Parameters, and Return Types Method Description Method Parameters Return Type POST Subscribes the authenticated user to a list <>/ subscribers None List object GET Gets the list subscribers <>/ subscribers cursor Users collection DELETE Unsubscribes the authenticated user from a list <>/ subscribers None List object GET Checks whether a user is a subscriber of a list <>/ subscribers/ <> None User object Extending Twitter’s Core Functionality The https://api.twitter.com/2/<>/ prefix is used on each of the Lists API methods where <> must be replaced with the logged-in user’s screen_name in the methods in Table 4.1 and can be set to any valid screen_name in the methods in Tables 4.2 and 4.3. Instead of using <>, you should use the appropriate identifier of the list that you want to access. For the XML example shown earlier, for example, you would use 1111 as the <>. Each of these methods should be appended with a format set to either XML or JSON.The following few examples use twitter-async. In these examples, the <> parameter is set to the value of $list_user, which is equal to $user>screen_name, which can be accessed after calling the verify() function in master.php of the sample code: n $new_list = $twitter->post("/{$list_user}/lists.json", array("description" => "An example list.", "mode" => "private", "name" => "Example List")); n $updated_list = $twitter->post("/{$list_user}/lists/ {$new_list->id}.json", array("description" => "An updated example list.")); n $lists = $twitter->get("/{$list_user}/lists.json", array("cursor" => -1)); n $deleted_list = $twitter->delete("/$list_user/lists/ {$updated_list->id}.json"); For each of the examples, you can access the responseText, such as $new_list-> retrieve the data returned by the Twitter API. In the examples of updating and deleting the list, these also use the id value of the previous lists within their method names. Here is an example of extracting all the lists that the authenticated user has been added to: responseText, to echo "

    List Objects

    "; $cursor = -1; do { $lists = $twitter->get("/{$list_user}/lists/memberships.json", array("cursor" => $cursor)); foreach($lists->lists as $list) { echo "
  • ".$list->id.": ".$list->name." created by ".$list-> user->screen_name."
  • "; } $cursor = $lists->next_cursor_str; } while ($cursor > 0); 67 68 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location The next set of methods (see Table 4.2) is for updating the members of an existing list. With the exception of the final method, these methods function in the same way as Lists methods but require a numeric id parameter, which is of the logged-in user. In the last method, if the user is not a member of the specified list, an appropriate Hash object will be returned; otherwise, it will be a User object. Each of these methods should be appended with a format set to either XML or JSON. Here are two sample URLs that use the public @twitterapi team list: n n https://api.twitter.com/2/twitterapi/team/members.xml https://api.twitter.com/2/twitterapi/team/members/3191321.xml To test the final method using twitter-async, you would use the following: $id = $response->id; $membership = $twitter->get("/twitterapi/team/members/{id}.json"); if ($membership->code == 200) { echo "Yes, the user is a member of this list."; } else { echo "Sorry, the user is not a member of this list."; } The $id parameter will be that of the authenticated user. However, if you replace it with 3191321 (a current member of the Twitter API team), you should receive a successful response.The $membership element will also contain a User object if successful, so the message could use $membership->name to display the member’s name.The methods listed in Table 4.3 enable you to update subscribers to an existing list. Unlike the List Member methods that only allow the authenticated user who created the list to add and remove members, authenticated users can subscribe and unsubscribe themselves to and from any public list. Like the List Member methods, you can use the using the final check method shown in the table to determine whether a user subscribes to a list. These three categories cover all the current functionalities, but these may be extended in future implementations of the Lists API (perhaps to include bulk adding and removing features). Geolocation API Many third-party applications that support geolocation do so by using the user-defined location field within Twitter profiles.This field is not coded in any way and represents an account-level location for the user. Some applications provide functionality to update profile locations by using the Global Positioning System (GPS) within cell phones or location-aware laptops or other Internet-enabled devices.The Geolocation API is the natural extension to this third-party functionality, enabling applications to tag single updates with a user’s current latitude and longitude.The feature is an opt-in service, quite understandably, and supports multiple use cases such as providing context-aware advertising or for browsing updates from users around a neighborhood, arena event, or music concert. Extending Twitter’s Core Functionality Mozilla Geode and Yahoo! Fire Eagle Several options are available for supporting geolocation within web browsers and mobile devices. Two popular choices are Mozilla’s Geode and Yahoo!’s Fire Eagle. In the future, many more will become available as geolocation becomes a mainstream feature. A browserbased extension for Mozilla Firefox named Geode can be used to add geolocation features to the popular web browser through a W3C standards-compliant API. A broker-based solution is Fire Eagle, a service that allows users to update their location and control its privacy and access by other applications. It provides an API to access locations, but requires users to have access to an account. In terms of the Geolocation API for developers, two new fields were created: one within the User object, which is a read-only field named geo_enabled, indicating whether the user has opted-in to the feature; and the geolocation itself, which can be added as lat and long parameters to a status update request. GeoRSS-Simple is used to specify the return data format of locations in XML and uses GeoJSON for JSON requests. For example, specifying a lat of 37.78445 and long of -122.39671 (the approximate location of the Twitter headquarters in San Francisco) will return the following in XML using GeoRSS-Simple: 37.78445 -122.39671 And the same request will return the following using GeoJSON: "geo": { "type": "Point", "coordinates": [37.78445, -122.39671] } If no geolocation data is available, an empty result set will be returned as in XML or "geo": {} in JSON. If geolocation data is available, coordinates and place elements will also be included, with further details about the current location of the user. The place elements will contain all the data described in the Twitter geo methods described here. Currently, all geolocation data will be removed from an update after seven days of being posted.Twitter also provides three Geolocation API methods that support adding a location to updates: geo/reverse_geocode and geo/nearby_places, for returning a set of locations that are closest to a latitude and longitude or IP address; and geo/id/<>, which returns detailed information about one specific location. It is recommended that you use the geo/nearby_places method for returning location data specific to the authenticated user and geo/reverse_geocode for general geographic data. Both methods will return the same data elements, but the former will return results in an order specific to the user. If you use the latitude and longitude of the Twitter headquarters, a call to the geo/reverse_geocode method will return the following JSON: 69 70 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location { "result": { "places": }. "query":{ "type": "reverse_geocode", "url": "http://api.twitter.com/1/geo/reverse_geocode.json? lat=37.78445&long=-122.39671&accuracy=0&granularity=neighborhood", "params": { "granularity": "neighborhood", "coordinates": { "type": "Point", "coordinates": [-122.39671,37.78445] }, "accuracy": 0 } } } Additional parameters that you can send to this method include max_results (to control how many results are returned), granularity (which defaults to neighborhood but could also be set to city), and accuracy (which you can set to a numeric value to denote a radius in meters or a string for feet which must be suffixed by ft). For example, to search for results within an 800-foot radius, you set the accuracy parameter to 800ft. For the geo/nearby_places method, you can also supply an ip parameter rather than a lat and long.Twitter will convert the ip parameter using Geo-IP. Currently, results are limited to the United States, but the Twitter people are working on including other locations eventually.This method returns the coordinates of both the place itself and the neighborhood or city in which it is situated.This could be used if you wanted to plot the location in a Geographical Information System (GIS). If this same query were executed via twitter-async, you would access variables using the following code: echo "

    Geolocation Objects

    "; $response = $twitter->get("/geo/reverse_geocode.json", array("lat" => 37.78445, "long" => -122.39671, "max_results" => 3)); echo "
      "; foreach($response->result->places as $geo) { echo "
    • ".$geo->id.": ".$geo->full_name." (".$geo->contained_within[0] ->full_name.")
    • "; } echo "
    "; The results are accessed from within the $response->result->places object, and data from the contained_within element must be extracted by using $geo->contained_within[0].As for accessing the initial query, you would use $response->query to extract the parameters executed alongside the method.To demonstrate the geo/id/<> method, you can use one of the id elements returned by the query Extending Twitter’s Core Functionality above.The closest to the Twitter headquarters is 5c92ab5379de3839, which is South Beach, San Francisco. If you pass this into the geo/id/<> method, you’ll output the following JSON: { "url": "http://api.twitter.com/1/geo/id/5c92ab5379de3839.json", "country": "", "bounding_box": { "type": "Polygon", "coordinates": [[...]] }, "place_type": "neighborhood", "contained_within": , "polylines": ["ioseFd`_jVhKjKxKkHbFdHhD{DjIhEhLiSnDbUo}@bmAoj@su "full_name": "South Beach", "geometry": { "type": "Polygon", "coordinates": [[...]] }, "name": "South Beach", "id": "5c92ab5379de3839", "country_code": "US" } The additional information contained within this method gives access to polygon coordinates as well as data for drawing a polyline. Unfortunately, the id returned by both of these methods does not relate to a Yahoo! Where On Earth ID (WOEID), which could be used by the Local Trends methods. If you are using your own GIS, you could use these coordinates to plot your own maps or use the Google Maps API to show the locations of tweets in near real time. Twitter Community Evolution Alongside major feature extensions, which offer new opportunities for application developers in their own applications,Twitter has also started supporting community-driven tools that promote the growth of its own platform. Currently, these include translations and spam reporting, but could extend to other features in the future.The translate feature has huge potential to be extended to third-party developers for providing internationalized applications based on community submissions of translations, which is something Facebook and Google Friend Connect already support. Platform Translations Translations is a new feature to support Twitter in French, Italian, German, and Spanish (FIGS) in addition to English and Japanese, which are currently available on the Twitter 71 72 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location website. In the future, this will be extended to other languages, too. For now, however, Twitter hopes to test the platform using these four new languages first.Twitter is recruiting volunteers to provide these translations. If you’re interested in contributing, you can visit their official Translate (@translate) page to register to become a translator. Spam Reporting The original solution for spam reporting involved following the Twitter spam account (@spam) and sending it a direct message with the screen name of the suspected spammer. However, this was found to be too complicated for most users, who often just retweeted spam messages and therefore were suspected of spamming themselves.As a replacement, a Report for Spam feature has been added to the Twitter actions context menu. So, you can now report a particular user without having to follow the spam account and send it a message. Twitter also released a new API method for performing this functionality named report_spam. It enables developers to incorporate spam control directly within their applications. Spam can be reported by supplying an id, user_id, or screen_name parameter via a POST request to the report_spam method, which will return a User object if successful or a Hash object if unsuccessful. For example, if you suspect iamaspammer13 is a spam account, you can use the following cURL command: curl –k -u username:password -d "screen_name=iamaspammer13" https://api.twitter.com/2/report_spam.json Calls to this method are limited per user per hour and so should be used sparingly when in batches.As usual, relevant error responses will be returned once this rate has been reached. No automated response will be taken by Twitter as a result of a spam request for reasons such as abuse and mistaken identity, so users should not expect accounts to be suspended immediately upon submitting a request.To test this feature out in code, you can use the Test Tube application from Chapter 3, adding the following line of code to the master.php: printFollowers($twitter, 10); The line above will execute the printFollowers() function, which will be detailed next, should be placed inside the functions.php file.The function will return a list of the last ten (or however many are provided in the second parameter) followers of the authenticated user along with a radio button next to each so that a user can select a potential spammer and click Report Spam to send the request to Twitter.The printFollowers() function is shown in Listing 4.2. Listing 4.2 The printFollowers() Function function printFollowers($twitter, $count = 10) { try { $followers = $twitter->get_statusesFollowers(array("cursor" => -1)); if (check($followers)) { Twitter Community Evolution $next_cursor = $followers->next_cursor; $previous_cursor = $followers->previous_cursor; echo "

    Latest ".$count." Twitter Followers

    "; echo "
    "; for ($i = 0; $i < $count; $i++) { $follower = $followers->users[$i]; echo "name."\" href=\" http://twitter.com/".$follower->screen_name."\">profile_image_url."\" alt=\"".$follower-> screen_name."\" height=\"48\" width=\"48\" />"; echo " screen_name."\" />"; } echo ""; echo "

    "; echo "
    "; } else { return false; } } catch(EpiTwitterException $e) { echo "

    You have no followers to list.

    "; } } In this function, the statuses/followers method is called along with a cursor parameter that returns the latest 100 followers.These are then iterated over using the $count parameter that was supplied to the function as a limiter. Each follower has a radio button next to his or her profile picture that will be submitted via the form as a spammer value alongside a hidden method value, which will be parsed by the master.php file.An extension to this could be to use a check box to report multiple spammers.You now need to add the report_spam functionality within the master.php file: if (isset($_POST["method"])) { switch($_POST["method"]) { case "spam": $response = $twitter->post_report_spam(array("screen_name" => $_POST["spammer"])); echo check($response) ? "

    Spam user {$_POST[‘spammer’]} reported successfully.

    " : "

    Spam user {$_POST[‘spammer’]} reported unsuccessfully.

    "; break; } } else { printFollowers($twitter, 10); } 73 74 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location The name of the case parameter is the same as the hidden method value of the form, and the screen_name parameter is set to the value of spammer.The check() function will validate the method call and return the corresponding User object if successful or false if unsuccessful. For this example, no further processing was completed on the response, but the simple text line denoting either a successful or unsuccessful report attempt indicates where you could add extra functionality.The extensibility of the functions.php library and the power of twitter-async make adding these features relatively easy after you have suitable architectures in place. Future Directions As a platform,Twitter is still in its infancy.The introduction of OAuth and Sign In With Twitter is their first real step toward being a worthy “connect” provider.Twitter has already confirmed three features during the writing of this book: the Streaming API, contributions functionality, and Twitter @anywhere. Streaming API Twitter has released new Streaming API methods, such as firehose, filter, and retweet, that enable developers to provide almost real time access to large amounts of Twitter data.This is also the service that is used to index public statuses by Google and Microsoft Bing.These methods use streaming HTTP, whereby clients are connected to continuous data streams and will have to explicitly disconnect themselves to stop receiving data.The current Streaming API methods are as follows: n The statuses/filter method returns all public statuses that match one or more filter parameters.These include follow for mentions, locations for geotagged updates, and track for specific keywords.The default access to this method allows you to track up to 200 keywords, 200 users, and 10 “bounding boxes” for locations. These boxes are a combination of longitude/latitude pairs, such that the first pair is the southwest corner of the box and the second pair is the northeast corner. n The statuses/firehose method returns all public statuses without any kind of filtering.This is one of the least-used Streaming API methods because of its size and the fact that other methods that return less data can often be used in combination to return a more comprehensive set of data. n The statuses/links method returns all statuses that contain either an http: or https: link. Like the statuses/firehose method, because of the number of data items retrieved by this method, it is less widely used. n The statuses/retweet method returns all retweets made by users. It is generally not used, in favor of the statuses/filter method, whereby you can set the follow parameter to track a set of users. Twitter Community Evolution n The statuses/sample method returns a random sample of all public statuses, which is a small proportion of the Firehose. For research or data mining,Twitter also allows you to request access to the Gardenhose, which gives access to a larger number of samples. Only public accounts are made available, and so you will not be able to extract information from protected Twitter accounts.The Streaming API uses Basic Authentication, and access to methods other than statuses/filter and statuses/sample must be explicitly requested from Twitter to prevent abuse and to track usage. Because of the large amounts of data that will be flowing to your applications, it is recommended that you decouple stream processing and persistence.This just means that as soon as you receive data from Twitter it should be stored and then processed using methods other than attempting to render inline. An example PHP client for use with the Streaming API is Phirehose (http://code. google.com/p/phirehose/), which is moderately maintained.The library uses a fairly simple structure that conforms to the official Streaming API documentation: require_once("Phirehose.php"); class MyStream extends Phirehose { public function enqueueStatus($status) { print $status; } } $stream = new MyStream("<>", "<>"); $stream->consume(); In this example, the Phirehose class is extended, and the enqueueStatus() function is overridden, and called once for each status successfully retrieved. If you are interested in using the Streaming API, you should read the documentation provided by Twitter (http:/ /dev.twitter.com/pages/streaming_api) and within Phirehose to ensure that your applications run smoothly. Because extracting large amounts of data was not the focus of this book, this section provides just a snapshot of what is possible via the Streaming API. Contributions For groups or organizations that have multiple users who post on their behalf from a shared account,Twitter is implementing a “contributors” feature.An account will have to explicitly enable the feature, which will set the contributors_enabled parameter within a User object to true, and thus enable specified user accounts to update its status.Within a Status object will be a new parameter called contributors containing a set of user identifiers who will have “signed” the update.A sample can be accessed at https://api. twitter.com/2/statuses/show/7680619122.xml.The update outputs a regular Status object plus the following: 8285392 75 76 Chapter 4 Extending the Twitter API: Retweets, Lists, and Location The feature enables you to append the contributor’s username to a tweet (for example, the @twitterapi account invited @raffi to tweet on its behalf) so that users can direct responses back to the person who was referred to in the tweet.At the time of this writing, this feature is not yet available within the Twitter API. Twitter @anywhere At the time of this writing, the details about Twitter @anywhere are scarce.As a concept, @anywhere is an attempt to enable Twitter functionality, such as following people, to be embedded within any web page using just a few lines of JavaScript. Like website integration with the Facebook Platform (see Part II) and Google Friend Connect (Part III), this client-side functionality could see new incarnations of Sign In With Twitter and other related Twitter API methods when used in combination with a server-side library such as twitter-async. Summary Twitter is a continually moving target.As a developer, not only will you have to contend with existing features being changed, you will also have to react to new features being added or old features being deprecated and removed. During the course of writing this book,Twitter introduced the Lists API, Retweet API, and Geolocation API, and was already underway in the development of the Streaming API.This goes to show the pace of change of the platform in even a short space of time. In this chapter, you were given examples of these new methods and other community features such as translations and spam reporting, which are likely to be included as features in the future. Keeping up-todate with the Twitter API announcements and blog will ensure you are the first to know of new Twitter enhancements. 5 An Overview of Facebook Platform Website Integration Iprofiles n today’s networked world, Facebook is a household name enabling users to create rich and interact with others across the world through wall posts, status updates, messages, and pokes. For developers, the Facebook Platform has opened up almost infinite possibilities to create engaging applications that have before been mostly restricted to the internal Facebook environment.This is where Facebook Platform integration for websites (previously known as Facebook Connect) is different. It allows developers to hook into the Facebook ecosystem through external applications on the Web, cell phones, and even game consoles. This chapter explores the fundamentals of Facebook for developers, including the Facebook Platform and website integration.You will learn about core components, including the Facebook API for manipulating Facebook data, the Facebook Query Language (FQL) for accessing data, and the Facebook Markup Language (XFBML) for displaying Facebook components such as profile pictures in your web applications. You will also learn how to create a sample application that you’ll use in Chapter 6, “Registration,Authentication, and Translations with Facebook,” for registration, authentication, and internationalization and in Chapter 7,“Using Facebook for Sharing, Commenting, and Stream Publishing,” for sharing, commenting, and publishing. Facebook Platform for Developers On August 15, 2006, Facebook introduced the first version of its Facebook Platform and API enabling users to share their information with third-party websites and applications of their choosing.At the official 2007 f8 press conference, Mark Zuckerberg gave a keynote presentation to 800 developers introducing the next evolution of the Facebook Platform:“Imagine all the things we’re going to be able to build together”. 78 Chapter 5 An Overview of Facebook Platform Website Integration This movement was led by the opening of Facebook registration to users outside of the United States and the exploitation of network connections through the social graph. He highlighted three components to the platform: n Deep integration Integration points enable applications to create synergies with the Facebook environment.These integration points include boxes, tabs, application info sections, inboxes, bookmarks, the Publisher, activity streams, feed forms, and canvas pages. Not all integration points suit all applications, and so which features you choose to exploit depends on what type of application you are developing.Also, Facebook has deprecated many of these integration points (such as boxes and application info sections), and Facebook is likely to add more in the future. n Mass distribution The integration points provide unique ways to distribute your application through the social graph.These include notifications and requests that can push messages to friends, but also serendipitous means (such as via activity streams or via browsing a user’s profile page). New features also include application and game dashboards, and counters, which were not available for testing during the production of this book, but are available on the Facebook Developer Roadmap. n New opportunity Applications can create new business opportunities, as within canvas pages you can display advertisements or use applications to transact through Facebook. By attracting more users to your application, both your business and Facebook benefit through increased site traffic and creating a richer social graph. While the Facebook Platform continues to evolve, enabling developers to build within the Facebook ecosystem, a new movement to integrate Facebook data with external applications has already started to mature.This is where Facebook Platform website integration comes into its own. Facebook Platform Facebook Platform for websites is the next evolution of the Facebook Platform, enabling you to integrate Facebook functionality into your own site, desktop application, cell phone applications, and beyond.This is not just about users collaborating and sharing within the internal Facebook environment as was the intention of the original Facebook Platform, this is about bringing Facebook to your own product or service. Plug-ins and social widgets, as well as custom programming, can get you up and running with the Facebook Platform in minutes in some cases. Facebook Platform website integration offers three benefits: 1. Increasing registrations because users can register on your application in just two clicks using their Facebook user credentials (see Chapter 6). No longer do they Facebook Platform need to remember yet another password. In addition, through authorized accounts, you get access to their Facebook data such as name, photo, location, and more.This allows you to create a richer personalized experience, such as serving them targeted information based on their location, age, gender, or interests. 2. Driving traffic to your product or service by giving users the opportunity to comment on, share, and stream content through their Facebook social graph and activity streams so that their friends click back to your site and engage with your content, completing the viral loop (see Chapter 7). 3. Increasing activity on your site by adding social context to increase user engagement, not just showing users what’s most popular on your site, but what’s most popular with their friends on your site.This is known as social filtering and adds to the personalized experience. Facebook provides a sample application called The Run Around (http://www. somethingtoputhere.com/therunaround/) that demonstrates the service in action.To integrate the Facebook Platform into your site, you need to first set up a Facebook application, get an API key, and add some snippets of JavaScript code to your existing site.The next section focuses on concretizing these steps and requires an active Facebook user account. Registering a Facebook Application The process for creating a Facebook application is much the same as for regular Facebook Platform applications.You’ll need to ensure that you have the Facebook Developer application enabled on your account by visiting http://www.facebook.com/developers and then clicking “Set Up New Application”.You will be presented with a space to enter your application name and agree to the Facebook terms and conditions.The application name entered here will be the one that is used within the Facebook Application Directory and viewable on all correspondence with users. Use a suitable name such as “Test Tube” and click “Create Application”. Facebook Principles and Policies As a developer, you are obliged to adhere to the Facebook Developer Principles and Policies (http://developers.facebook.com/policy/) to help protect your users, yourself, and Facebook. The Application Edit page contains seven tabs, containing every setting available to Facebook Platform developers: n Basic n Authentication n Profiles n Canvas n Connect 79 80 Chapter 5 An Overview of Facebook Platform Website Integration n Widgets n Advanced Migrations n Most of these tabs are applicable to Facebook Platform for website applications with the exception of Canvas, which is used only if you have an internal Facebook application, and Advanced, which is for server whitelisting and mobile integration.The “Sandbox Mode” setting in the “Advanced” tab may prove useful should you only want developers to view the application (for instance, before being made live). Basic Tab The “Basic” tab contains options for controlling how your application appears within the Facebook Application Directory, such as name, description, logo, icon and language. From this tab, you can also add other developers to your application (who must be a friend on Facebook), which will give them full access to the application via their own profile. Facebook also strongly supports adding user-facing links to help, privacy, and terms of service URLs, which can contain information such as contact addresses or frequently asked questions.The bookmark URL must be set if you want to allow users to bookmark your application via the XFBML element. The three most important fields on this tab are your application ID,API key, and secret. These parameters are used to authenticate your application with Facebook. (Only you and Facebook should know the secret!) These parameters should be added to a configuration file, which you can create and save as config.php and which will be included on each page on which you want to use Facebook Platform for websites functionality: Should your secret ever be compromised, you can reset it by going to the Facebook Developer application, selecting your application, and clicking the “Reset Secret Key” option. Because the secret is used to “sign” all Facebook requests, resetting it renders the old code useless. Authentication Tab The “Authentication” tab contains two important authentication callback URLs, which are “pinged” when a user first authorizes or removes your application.These will be created in Chapter 6, where the authentication process is explained, but should be set to http://myfacebookapp.com/authorize.php and http://myfacebookapp.com/remove.php (where myfacebookapp.com should be replaced by your own web server details). Facebook Platform Profiles Tab The “Profiles” tab is usually reserved for Facebook Platform applications, but it also contains options for the Publisher interface (see Chapter 7). Set the “Publish Text” option to Check Mood and the Publish Callback URL to http://myfacebookapp.com/publish.php and “Self-Publish Text” to “Update Mood” and the “Self-Publish Callback URL” to http://myfacebookapp.com/self_publish.php. Connect Tab The “Connect” tab contains settings that are available only to Facebook Platform for websites applications, such as the “Connect URL”, which you should set to http://myfacebookapp.com/, and a setting that enables you to add a logo, which will appear when a user first registers for your application or when requesting permissions such as reading or writing to their stream. If you want your implementation to span multiple domains, you can set the base domain to myfacebookapp.com, which will enable foo.myfacebookapp. com and bar.myfacebookapp.com.The account reclamation URL, as explained in Chapter 6, is requested should a user remove his or her account from Facebook and wants to create an independent account on your site without Facebook integration.Access to friend linking is being revamped by Facebook and will be available in mid to late 2010. Further details are available on the Facebook Developer Roadmap and will also be posted on this book’s website at http://www.socialprogramming.info. Widgets Tab The “Widgets” tab is useful if you intend to use the comment boxes or live stream boxes on your website or application (see Chapter 7). From here, you can control who can administrate and moderate comments and also control who is able to comment.When you are happy with all the settings, just click “Save Changes” to be returned back to the Facebook Developer application.You can make other user-facing changes from here, such as editing your application’s profile, which is where users can become fans, viewing application usage statistics, and handling translations (see Chapter 6).The next section explains how to reference your application using both the server-side PHP and client-side JavaScript client libraries. Migrations Tab The “Migrations” tab was created to provide backward functionality to help developers transition their applications to use Facebook’s new features (for example, the handling of empty arrays in JSON and other potentially application-breaking platform adjustments). From this tab, developers can disable new features until they are happy that their application can support them. Referencing a Facebook Platform Application To reference Facebook Platform on your site, you need to upload a small file called a cross-domain communication channel file onto your web server to enable authenticated 81 82 Chapter 5 An Overview of Facebook Platform Website Integration communication between your site and Facebook.The file can be created by creating a new file called xd_receiver.htm and adding the following HTML: Only one of these channel files is required per domain, and so you can specify its location as a relative path using a forward slash (/) to denote relativity to your root directory. For instance, /example/xd_receiver.htm would look at the location http://www. example.com/example/xd_receiver.htm, whereas if your root directory were set to http://www.example.com/example already then you could just use xd_receiver.htm without the forward slash.After uploading the file and setting its permissions to 644 using chmod, you then need to add some JavaScript code to each of your pages that use Facebook. Listing 5.1 shows a simple implementation of this that you can save as index.php and store in the same directory as config.php and xd_receiver.htm. Listing 5.1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 A Simple Facebook Platform Page Test Tube

    Test Facebook Platform Page

    19 20 The code in Listing 5.1 is the simplest implementation of Facebook Platform website integration utilizing the JavaScript client library to log a user in and out. In Chapter 6, you will learn how to extend this basic authentication to use the post-authorize and postremove callback URLs so that you can start tracking which users are interacting with your application.This client-side code can be extended to use a server-side library such as the official Facebook PHP Client Library to access the Facebook API. Using the official client libraries means that a user’s session can be shared between client-side and server-side code, but if you want to use a third-party client, you will have to verify the signature of requests yourself by adding the following function to a functions.php file and uploading that to your web server: function valid_facebook_session($expires, $session_key, $ss, $user, $valid_signature, $secret) { $signature = md5("expires=".$expires."session_key=".$session_key."ss=". $ss."user=".$user.$secret); return ($signature == $valid_signature ? true : false); } The function ensures that parameters sent from Facebook are authentic and have not been tampered with. If you send a request to Facebook and receive a true response, then you know that it is genuine.Adding to the index.php file that you created in Listing 5.1, add the following code below line 2: include "functions.php"; include "facebook-platform/php/facebook.php"; $facebook = new Facebook(API_KEY, SECRET); $official_user = $facebook->get_loggedin_user(); $valid_facebook_session = valid_facebook_session( $_COOKIE[API_KEY."_expires"], $_COOKIE[API_KEY."_session_key"], $_COOKIE[API_KEY."_ss"], $_COOKIE[API_KEY."_user"], $_COOKIE[API_KEY], SECRET); $unofficial_user = ($valid_facebook_session ? $_COOKIE[API_KEY."_user"] : false); After adding the code into index.php, you can reference the $official_user and by adding the following code within the tags: $unofficial_user

    Official Client User:

    Unofficial Client User:

    83 84 Chapter 5 An Overview of Facebook Platform Website Integration Notice that both parameters will output the same identifier, but if the Facebook cookie (which is used in the unofficial clients) is tampered with, the signature will not match and will return false.With the client-side and server-side libraries now referenced successfully, you can now begin to use the Facebook API to access and manipulate user details and use the Facebook Markup Language (FBML) to display the results. Facebook API, FQL, and XFBML The Facebook Platform is split into four core components that comprise its REST-based API and give developers the tools to perform Facebook actions such as creating events, getting a list of friends, or updating a status through accessor (retrieval) and mutator (creating, updating, or deleting) methods and accessing Facebook data through the Facebook Query Language (FQL). For consistent formatting and user experience, you can use FBML for canvas applications and XFBML for